aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>2012-10-10 01:40:27 +0159
committerBernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>2012-10-10 01:40:27 +0159
commitee2ec6d2e2197bcd87b135f48ae82c209a83da9a (patch)
treef5386154f2fa284cbcff35e5857049ffc458f952
parent0b642ae1fa9a3e65eb826c1964482f975b33f5cd (diff)
downloadgcc-aarch64-ee2ec6d2e2197bcd87b135f48ae82c209a83da9a.tar.gz
Sync with svn rev. 192243
Signed-off-by: Bernhard Rosenkraenzer <Bernhard.Rosenkranzer@linaro.org>
-rw-r--r--ChangeLog8
-rw-r--r--MAINTAINERS2
-rw-r--r--contrib/ChangeLog8
-rwxr-xr-xcontrib/check_GNU_style.sh4
-rw-r--r--contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail36
-rw-r--r--gcc/ChangeLog753
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in25
-rw-r--r--gcc/ada/ChangeLog1289
-rw-r--r--gcc/ada/Make-generated.in61
-rw-r--r--gcc/ada/Makefile.rtl1
-rw-r--r--gcc/ada/a-calcon.adb4
-rw-r--r--gcc/ada/a-caldel-vms.adb4
-rw-r--r--gcc/ada/a-calend-vms.adb6
-rw-r--r--gcc/ada/a-calend.adb22
-rw-r--r--gcc/ada/a-calfor.adb2
-rw-r--r--gcc/ada/a-catizo.adb2
-rw-r--r--gcc/ada/a-cbdlli.adb14
-rw-r--r--gcc/ada/a-cbhama.adb4
-rw-r--r--gcc/ada/a-cbhase.adb13
-rw-r--r--gcc/ada/a-cbmutr.adb14
-rw-r--r--gcc/ada/a-cborma.adb16
-rw-r--r--gcc/ada/a-cborse.adb24
-rw-r--r--gcc/ada/a-cdlili.adb23
-rw-r--r--gcc/ada/a-cfdlli.adb14
-rw-r--r--gcc/ada/a-cfhama.adb11
-rw-r--r--gcc/ada/a-cfhase.adb10
-rw-r--r--gcc/ada/a-cforma.adb4
-rw-r--r--gcc/ada/a-cforse.adb4
-rw-r--r--gcc/ada/a-cidlli.adb26
-rw-r--r--gcc/ada/a-cihama.adb22
-rw-r--r--gcc/ada/a-cihase.adb30
-rw-r--r--gcc/ada/a-cimutr.adb31
-rw-r--r--gcc/ada/a-ciorma.adb38
-rw-r--r--gcc/ada/a-ciormu.adb19
-rw-r--r--gcc/ada/a-ciorse.adb71
-rw-r--r--gcc/ada/a-clrefi.adb15
-rw-r--r--gcc/ada/a-cobove.adb14
-rw-r--r--gcc/ada/a-cofove.adb14
-rw-r--r--gcc/ada/a-cohama.adb27
-rw-r--r--gcc/ada/a-cohase.adb42
-rw-r--r--gcc/ada/a-coinve.adb51
-rw-r--r--gcc/ada/a-comutr.adb31
-rw-r--r--gcc/ada/a-convec.adb73
-rw-r--r--gcc/ada/a-coorma.adb47
-rw-r--r--gcc/ada/a-coormu.adb65
-rw-r--r--gcc/ada/a-coorse.adb67
-rw-r--r--gcc/ada/a-crdlli.adb4
-rw-r--r--gcc/ada/a-direct.adb14
-rw-r--r--gcc/ada/a-direio.adb4
-rw-r--r--gcc/ada/a-dirval-mingw.adb12
-rw-r--r--gcc/ada/a-dirval-vms.adb12
-rw-r--r--gcc/ada/a-dynpri.adb4
-rw-r--r--gcc/ada/a-except-2005.adb24
-rw-r--r--gcc/ada/a-except.adb5
-rw-r--r--gcc/ada/a-exetim-mingw.adb4
-rw-r--r--gcc/ada/a-exetim-posix.adb5
-rw-r--r--gcc/ada/a-exexda.adb6
-rw-r--r--gcc/ada/a-exexpr-gcc.adb2
-rw-r--r--gcc/ada/a-ngcoar.adb6
-rw-r--r--gcc/ada/a-ngelfu.adb2
-rw-r--r--gcc/ada/a-sequio.adb4
-rw-r--r--gcc/ada/a-strfix.adb14
-rw-r--r--gcc/ada/a-strunb-shared.adb2
-rw-r--r--gcc/ada/a-strunb.adb9
-rw-r--r--gcc/ada/a-stwifi.adb17
-rw-r--r--gcc/ada/a-stwiun-shared.adb4
-rw-r--r--gcc/ada/a-stwiun.adb9
-rw-r--r--gcc/ada/a-stzfix.adb22
-rw-r--r--gcc/ada/a-stzsea.adb11
-rw-r--r--gcc/ada/a-stzsup.adb9
-rw-r--r--gcc/ada/a-stzunb-shared.adb14
-rw-r--r--gcc/ada/a-stzunb.adb18
-rw-r--r--gcc/ada/a-tags.adb58
-rw-r--r--gcc/ada/a-teioed.adb4
-rw-r--r--gcc/ada/a-textio.adb3
-rw-r--r--gcc/ada/a-tifiio.adb19
-rw-r--r--gcc/ada/a-wtedit.adb4
-rw-r--r--gcc/ada/a-wtenau.adb4
-rw-r--r--gcc/ada/a-ztedit.adb4
-rw-r--r--gcc/ada/a-ztenau.adb4
-rw-r--r--gcc/ada/aspects.ads13
-rw-r--r--gcc/ada/back_end.adb10
-rw-r--r--gcc/ada/bcheck.adb18
-rw-r--r--gcc/ada/binde.adb26
-rw-r--r--gcc/ada/bindgen.adb27
-rw-r--r--gcc/ada/butil.adb4
-rw-r--r--gcc/ada/ceinfo.adb8
-rw-r--r--gcc/ada/checks.adb2002
-rw-r--r--gcc/ada/checks.ads199
-rw-r--r--gcc/ada/clean.adb51
-rw-r--r--gcc/ada/cstand.adb15
-rw-r--r--gcc/ada/debug.adb2
-rw-r--r--gcc/ada/einfo.adb44
-rw-r--r--gcc/ada/einfo.ads2
-rw-r--r--gcc/ada/errout.adb19
-rw-r--r--gcc/ada/errout.ads9
-rw-r--r--gcc/ada/eval_fat.adb6
-rw-r--r--gcc/ada/exp_aggr.adb111
-rw-r--r--gcc/ada/exp_attr.adb14
-rw-r--r--gcc/ada/exp_ch2.adb2
-rw-r--r--gcc/ada/exp_ch3.adb330
-rw-r--r--gcc/ada/exp_ch3.ads6
-rw-r--r--gcc/ada/exp_ch4.adb1515
-rw-r--r--gcc/ada/exp_ch4.ads4
-rw-r--r--gcc/ada/exp_ch5.adb12
-rw-r--r--gcc/ada/exp_ch6.adb149
-rw-r--r--gcc/ada/exp_ch6.ads10
-rw-r--r--gcc/ada/exp_ch7.adb15
-rw-r--r--gcc/ada/exp_ch9.adb6
-rw-r--r--gcc/ada/exp_disp.adb483
-rw-r--r--gcc/ada/exp_imgv.adb18
-rw-r--r--gcc/ada/exp_intr.adb6
-rw-r--r--gcc/ada/exp_util.adb52
-rw-r--r--gcc/ada/exp_util.ads4
-rw-r--r--gcc/ada/expander.adb8
-rw-r--r--gcc/ada/freeze.adb86
-rw-r--r--gcc/ada/g-comlin.adb127
-rw-r--r--gcc/ada/g-socket.adb31
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in477
-rw-r--r--gcc/ada/gcc-interface/decl.c1
-rw-r--r--gcc/ada/gcc-interface/gigi.h3
-rw-r--r--gcc/ada/gcc-interface/trans.c13
-rw-r--r--gcc/ada/get_scos.adb77
-rw-r--r--gcc/ada/gnat1drv.adb66
-rw-r--r--gcc/ada/gnat_rm.texi76
-rw-r--r--gcc/ada/gnat_ugn.texi651
-rw-r--r--gcc/ada/gnatcmd.adb103
-rw-r--r--gcc/ada/gprep.adb8
-rw-r--r--gcc/ada/impunit.adb1
-rw-r--r--gcc/ada/init.c4
-rw-r--r--gcc/ada/layout.adb13
-rw-r--r--gcc/ada/lib-xref.adb7
-rw-r--r--gcc/ada/make.adb51
-rw-r--r--gcc/ada/makeutl.adb31
-rw-r--r--gcc/ada/makeutl.ads5
-rw-r--r--gcc/ada/namet.ads12
-rw-r--r--gcc/ada/namet.h8
-rw-r--r--gcc/ada/opt.adb4
-rw-r--r--gcc/ada/opt.ads55
-rw-r--r--gcc/ada/osint.adb9
-rw-r--r--gcc/ada/par-ch4.adb79
-rw-r--r--gcc/ada/par-prag.adb1
-rw-r--r--gcc/ada/par.adb18
-rw-r--r--gcc/ada/par_sco.adb75
-rw-r--r--gcc/ada/par_sco.ads6
-rw-r--r--gcc/ada/prep.adb8
-rw-r--r--gcc/ada/prepcomp.adb18
-rw-r--r--gcc/ada/prj-env.adb3
-rw-r--r--gcc/ada/prj-part.adb20
-rw-r--r--gcc/ada/prj-proc.adb4
-rw-r--r--gcc/ada/prj-util.adb8
-rw-r--r--gcc/ada/projects.texi74
-rw-r--r--gcc/ada/put_scos.adb35
-rw-r--r--gcc/ada/rtsfind.ads49
-rw-r--r--gcc/ada/s-bignum.adb1067
-rw-r--r--gcc/ada/s-bignum.ads116
-rw-r--r--gcc/ada/s-dimmks.ads184
-rw-r--r--gcc/ada/s-dmotpr.ads4
-rw-r--r--gcc/ada/s-exnllf.adb5
-rw-r--r--gcc/ada/s-exnllf.ads5
-rw-r--r--gcc/ada/s-gearop.adb4
-rw-r--r--gcc/ada/s-oscons-tmplt.c8
-rw-r--r--gcc/ada/s-spsufi.adb24
-rw-r--r--gcc/ada/s-spsufi.ads10
-rw-r--r--gcc/ada/s-stposu.adb41
-rw-r--r--gcc/ada/s-stposu.ads8
-rw-r--r--gcc/ada/s-tassta.adb15
-rw-r--r--gcc/ada/scans.ads6
-rw-r--r--gcc/ada/scng.adb4
-rw-r--r--gcc/ada/scos.adb3
-rw-r--r--gcc/ada/scos.ads73
-rw-r--r--gcc/ada/sem.adb105
-rw-r--r--gcc/ada/sem.ads41
-rw-r--r--gcc/ada/sem_aggr.adb131
-rw-r--r--gcc/ada/sem_attr.adb17
-rw-r--r--gcc/ada/sem_ch10.adb55
-rw-r--r--gcc/ada/sem_ch13.adb218
-rw-r--r--gcc/ada/sem_ch13.ads8
-rw-r--r--gcc/ada/sem_ch3.adb130
-rw-r--r--gcc/ada/sem_ch3.ads6
-rw-r--r--gcc/ada/sem_ch4.adb246
-rw-r--r--gcc/ada/sem_ch4.ads2
-rw-r--r--gcc/ada/sem_ch5.adb7
-rw-r--r--gcc/ada/sem_ch6.adb220
-rw-r--r--gcc/ada/sem_ch7.adb27
-rw-r--r--gcc/ada/sem_ch8.adb41
-rw-r--r--gcc/ada/sem_ch9.adb20
-rw-r--r--gcc/ada/sem_dim.adb932
-rw-r--r--gcc/ada/sem_dim.ads43
-rw-r--r--gcc/ada/sem_elab.adb26
-rw-r--r--gcc/ada/sem_eval.adb324
-rw-r--r--gcc/ada/sem_eval.ads9
-rw-r--r--gcc/ada/sem_prag.adb176
-rw-r--r--gcc/ada/sem_res.adb310
-rw-r--r--gcc/ada/sem_type.adb1
-rw-r--r--gcc/ada/sem_util.adb170
-rw-r--r--gcc/ada/sem_util.ads35
-rw-r--r--gcc/ada/sem_warn.adb59
-rw-r--r--gcc/ada/sinfo.adb66
-rw-r--r--gcc/ada/sinfo.ads266
-rw-r--r--gcc/ada/sinput-c.adb5
-rw-r--r--gcc/ada/sinput-l.adb245
-rw-r--r--gcc/ada/sinput.adb50
-rw-r--r--gcc/ada/sinput.ads109
-rw-r--r--gcc/ada/snames.ads-tmpl10
-rw-r--r--gcc/ada/sprint.adb42
-rw-r--r--gcc/ada/sprint.ads1
-rw-r--r--gcc/ada/style.ads11
-rw-r--r--gcc/ada/styleg.adb20
-rw-r--r--gcc/ada/styleg.ads10
-rw-r--r--gcc/ada/stylesw.ads8
-rw-r--r--gcc/ada/switch-c.adb122
-rw-r--r--gcc/ada/switch-m.adb32
-rw-r--r--gcc/ada/switch.ads1
-rw-r--r--gcc/ada/system-mingw.ads1
-rw-r--r--gcc/ada/system-solaris-sparcv9.ads1
-rw-r--r--gcc/ada/system-vms_64.ads1
-rw-r--r--gcc/ada/tbuild.adb11
-rw-r--r--gcc/ada/tbuild.ads8
-rw-r--r--gcc/ada/types.ads66
-rw-r--r--gcc/ada/types.h5
-rw-r--r--gcc/ada/ug_words1
-rw-r--r--gcc/ada/uintp.ads63
-rw-r--r--gcc/ada/usage.adb20
-rw-r--r--gcc/ada/validsw.adb8
-rw-r--r--gcc/ada/validsw.ads2
-rw-r--r--gcc/ada/vms_data.ads32
-rw-r--r--gcc/ada/xoscons.adb2
-rw-r--r--gcc/ada/xsnamest.adb11
-rw-r--r--gcc/builtin-attrs.def4
-rw-r--r--gcc/builtins.def2
-rw-r--r--gcc/c-family/ChangeLog8
-rw-r--r--gcc/c-family/c-ada-spec.c7
-rw-r--r--gcc/c-family/c-common.h1
-rw-r--r--gcc/c-family/c.opt8
-rw-r--r--gcc/c/ChangeLog10
-rw-r--r--gcc/c/c-decl.c4
-rw-r--r--gcc/cgraph.c2
-rw-r--r--gcc/common.opt23
-rw-r--r--gcc/config.gcc5
-rw-r--r--gcc/config/avr/avr.md74
-rw-r--r--gcc/config/avr/predicates.md7
-rw-r--r--gcc/config/darwin-c.c4
-rw-r--r--gcc/config/darwin.c4
-rw-r--r--gcc/config/h8300/h8300.c4
-rw-r--r--gcc/config/i386/driver-i386.c23
-rw-r--r--gcc/config/i386/i386.c265
-rw-r--r--gcc/config/m68k/m68k.md226
-rw-r--r--gcc/config/mips/mips-protos.h25
-rw-r--r--gcc/config/mips/mips.c276
-rw-r--r--gcc/config/mips/mips.md60
-rw-r--r--gcc/config/mmix/mmix.c19
-rw-r--r--gcc/config/pa/pa.md76
-rw-r--r--gcc/config/rs6000/rs6000.c60
-rw-r--r--gcc/config/rs6000/t-rs60002
-rw-r--r--gcc/config/rx/rx.c53
-rw-r--r--gcc/config/rx/rx.opt6
-rw-r--r--gcc/config/s390/s390.c1
-rw-r--r--gcc/config/sh/linux.h19
-rw-r--r--gcc/config/sh/predicates.md16
-rw-r--r--gcc/config/sh/sh-c.c79
-rw-r--r--gcc/config/sh/sh-protos.h55
-rw-r--r--gcc/config/sh/sh.c474
-rw-r--r--gcc/config/sh/sh.h81
-rw-r--r--gcc/config/sh/sh.md83
-rw-r--r--gcc/config/sh/sh.opt10
-rw-r--r--gcc/config/sh/sync.md632
-rwxr-xr-xgcc/configure2
-rw-r--r--gcc/configure.ac3
-rw-r--r--gcc/cp/ChangeLog98
-rw-r--r--gcc/cp/call.c12
-rw-r--r--gcc/cp/cp-gimplify.c19
-rw-r--r--gcc/cp/cp-tree.h34
-rw-r--r--gcc/cp/cvt.c8
-rw-r--r--gcc/cp/cxx-pretty-print.c10
-rw-r--r--gcc/cp/decl.c113
-rw-r--r--gcc/cp/decl2.c4
-rw-r--r--gcc/cp/error.c4
-rw-r--r--gcc/cp/mangle.c8
-rw-r--r--gcc/cp/name-lookup.c1
-rw-r--r--gcc/cp/parser.c29
-rw-r--r--gcc/cp/pt.c103
-rw-r--r--gcc/cp/semantics.c56
-rw-r--r--gcc/cp/tree.c6
-rw-r--r--gcc/cp/typeck.c9
-rw-r--r--gcc/dce.c35
-rw-r--r--gcc/df-problems.c15
-rw-r--r--gcc/doc/cpp.texi9
-rw-r--r--gcc/doc/invoke.texi271
-rw-r--r--gcc/dumpfile.c868
-rw-r--r--gcc/dumpfile.h68
-rw-r--r--gcc/dwarf2out.c14
-rw-r--r--gcc/expr.c2
-rw-r--r--gcc/flag-types.h16
-rw-r--r--gcc/fortran/ChangeLog38
-rw-r--r--gcc/fortran/expr.c2
-rw-r--r--gcc/fortran/frontend-passes.c2
-rw-r--r--gcc/fortran/interface.c64
-rw-r--r--gcc/fortran/io.c3
-rw-r--r--gcc/fortran/match.c5
-rw-r--r--gcc/fortran/matchexp.c8
-rw-r--r--gcc/fortran/primary.c6
-rw-r--r--gcc/fortran/resolve.c24
-rw-r--r--gcc/fortran/trans-types.c2
-rw-r--r--gcc/gcc.c38
-rw-r--r--gcc/gengtype.c8
-rw-r--r--gcc/gimple-low.c8
-rw-r--r--gcc/gimple-pretty-print.c50
-rw-r--r--gcc/gimple-pretty-print.h2
-rw-r--r--gcc/ginclude/stddef.h7
-rw-r--r--gcc/ginclude/stdint-gcc.h14
-rw-r--r--gcc/ginclude/stdint-wrap.h6
-rw-r--r--gcc/go/gofrontend/parse.cc160
-rw-r--r--gcc/go/gofrontend/parse.h7
-rw-r--r--gcc/go/gofrontend/types.cc12
-rw-r--r--gcc/ipa-inline-analysis.c17
-rw-r--r--gcc/ipa-inline.h19
-rw-r--r--gcc/ipa-split.c78
-rw-r--r--gcc/ira-build.c7
-rw-r--r--gcc/ira-color.c5
-rw-r--r--gcc/ira-int.h16
-rw-r--r--gcc/ira-lives.c32
-rw-r--r--gcc/ira.c61
-rw-r--r--gcc/ira.h6
-rw-r--r--gcc/lto-cgraph.c26
-rw-r--r--gcc/lto-streamer-out.c82
-rw-r--r--gcc/lto-streamer.h10
-rw-r--r--gcc/lto-symtab.c34
-rw-r--r--gcc/lto/ChangeLog14
-rw-r--r--gcc/lto/lto-partition.c2
-rw-r--r--gcc/lto/lto.c65
-rw-r--r--gcc/machmode.h5
-rw-r--r--gcc/optabs.c66
-rw-r--r--gcc/opts-global.c47
-rw-r--r--gcc/opts.c24
-rw-r--r--gcc/passes.c253
-rw-r--r--gcc/reginfo.c44
-rw-r--r--gcc/sched-deps.c4
-rw-r--r--gcc/simplify-rtx.c445
-rw-r--r--gcc/statistics.c2
-rw-r--r--gcc/testsuite/ChangeLog203
-rw-r--r--gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c11
-rw-r--r--gcc/testsuite/c-c++-common/pr33763.c60
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-23.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ref4.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted38.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice8.C10
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr54323.C37
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/stddef.C6
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/stdint.C135
-rw-r--r--gcc/testsuite/g++.dg/ext/builtin30.C27
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/vla12.C28
-rw-r--r--gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C54
-rw-r--r--gcc/testsuite/g++.dg/other/dump-ada-spec-1.C10
-rw-r--r--gcc/testsuite/g++.dg/template/friend53.C23
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C702
-rw-r--r--gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C716
-rw-r--r--gcc/testsuite/g++.dg/torture/pr54735.C179
-rw-r--r--gcc/testsuite/g++.dg/warn/Wnull-conversion-1.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/Wsign-compare-5.C20
-rw-r--r--gcc/testsuite/g++.dg/warn/Wsizeof-pointer-memaccess-1.C13
-rw-r--r--gcc/testsuite/gcc.dg/attr-alias-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/attr-alias-5.c1
-rw-r--r--gcc/testsuite/gcc.dg/builtins-85.c25
-rw-r--r--gcc/testsuite/gcc.dg/dump-ada-spec-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54519-1.c48
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54519-2.c45
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54519-3.c42
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54519-4.c39
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54519-5.c45
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54519-6.c27
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr54551.c28
-rw-r--r--gcc/testsuite/gcc.dg/lower-subreg-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/lto/20120723_0.c6
-rw-r--r--gcc/testsuite/gcc.dg/lto/resolutions_0.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr54087.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr54782.c18
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr51106-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp85.c40
-rw-r--r--gcc/testsuite/gcc.dg/ucnid-10.c2
-rw-r--r--gcc/testsuite/gcc.dg/ucnid-13.c2
-rw-r--r--gcc/testsuite/gcc.dg/ucnid-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/ucnid-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/vmx/3b-13.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr54457.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/vect-double-1.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/vect-rebuild.c33
-rw-r--r--gcc/testsuite/gcc.target/mips/madd-9.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-1.c22
-rw-r--r--gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c22
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr46728-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr46728-2.c2
-rw-r--r--gcc/testsuite/gcc.target/sh/pr51244-12.c68
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54760-1.c20
-rw-r--r--gcc/testsuite/gfortran.dg/class_53.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/generic_25.f9030
-rw-r--r--gcc/testsuite/gfortran.dg/generic_26.f9029
-rw-r--r--gcc/testsuite/gfortran.dg/generic_27.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_operator_17.f9043
-rw-r--r--gcc/testsuite/gfortran.dg/vect/vect.exp2
-rw-r--r--gcc/testsuite/lib/gcc-dg.exp13
-rw-r--r--gcc/testsuite/lib/scanasm.exp32
-rw-r--r--gcc/toplev.c3
-rw-r--r--gcc/toplev.h1
-rw-r--r--gcc/tree-cfg.c92
-rw-r--r--gcc/tree-dump.c382
-rw-r--r--gcc/tree-dump.h7
-rw-r--r--gcc/tree-inline.c55
-rw-r--r--gcc/tree-nested.c1
-rw-r--r--gcc/tree-parloops.c1
-rw-r--r--gcc/tree-ssa-address.c21
-rw-r--r--gcc/tree-ssa-forwprop.c2
-rw-r--r--gcc/tree-ssa-live.c5
-rw-r--r--gcc/tree-ssa-loop-im.c23
-rw-r--r--gcc/tree-ssa-pre.c10
-rw-r--r--gcc/tree-ssa-sccvn.c10
-rw-r--r--gcc/tree-streamer-in.c25
-rw-r--r--gcc/tree-streamer-out.c34
-rw-r--r--gcc/tree-vect-data-refs.c727
-rw-r--r--gcc/tree-vect-loop-manip.c135
-rw-r--r--gcc/tree-vect-loop.c1078
-rw-r--r--gcc/tree-vect-patterns.c110
-rw-r--r--gcc/tree-vect-slp.c512
-rw-r--r--gcc/tree-vect-stmts.c693
-rw-r--r--gcc/tree-vectorizer.c133
-rw-r--r--gcc/tree-vectorizer.h8
-rw-r--r--gcc/tree-vrp.c83
-rw-r--r--gcc/tree.h9
-rw-r--r--gcc/valtrack.c220
-rw-r--r--gcc/valtrack.h84
-rw-r--r--gcc/var-tracking.c7
-rw-r--r--libbacktrace/ChangeLog22
-rw-r--r--libbacktrace/Makefile.am4
-rw-r--r--libbacktrace/Makefile.in3
-rw-r--r--libbacktrace/btest.c2
-rwxr-xr-xlibbacktrace/configure11
-rw-r--r--libbacktrace/configure.ac6
-rw-r--r--libbacktrace/dwarf.c47
-rw-r--r--libcpp/ChangeLog7
-rw-r--r--libcpp/directives.c45
-rw-r--r--libgcc/ChangeLog60
-rw-r--r--libgcc/config.host2
-rw-r--r--libgcc/config/arm/unwind-arm.h7
-rw-r--r--libgcc/config/gthr-rtems.h11
-rw-r--r--libgcc/config/gthr-vxworks.h9
-rw-r--r--libgcc/config/i386/gthr-win32.c10
-rw-r--r--libgcc/config/i386/gthr-win32.h18
-rw-r--r--libgcc/config/mips/gthr-mipssde.h9
-rw-r--r--libgcc/config/pa/gthr-dce.h9
-rw-r--r--libgcc/config/s390/gthr-tpf.h7
-rw-r--r--libgcc/config/sh/linux-atomic.S223
-rw-r--r--libgcc/config/sh/linux-atomic.c81
-rw-r--r--libgcc/config/sh/t-linux8
-rw-r--r--libgcc/config/sh/t-netbsd1
-rw-r--r--libgcc/config/sh/t-sh2
-rw-r--r--libgcc/gthr-posix.h6
-rw-r--r--libgcc/gthr-single.h9
-rw-r--r--libgcc/gthr.h4
-rw-r--r--libgcc/unwind-dw2-fde-dip.c8
-rw-r--r--libgfortran/ChangeLog16
-rw-r--r--libgfortran/Makefile.in43
-rw-r--r--libgfortran/aclocal.m474
-rw-r--r--libgfortran/config.h.in3
-rwxr-xr-xlibgfortran/configure23
-rw-r--r--libgfortran/configure.ac3
-rw-r--r--libgfortran/libgfortran.h2
-rw-r--r--libgfortran/runtime/environ.c42
-rw-r--r--libgo/MERGE2
-rw-r--r--libgo/Makefile.am1
-rw-r--r--libgo/Makefile.in1
-rw-r--r--libgo/go/bufio/bufio.go3
-rw-r--r--libgo/go/builtin/builtin.go3
-rw-r--r--libgo/go/bytes/bytes.go2
-rw-r--r--libgo/go/compress/flate/inflate.go12
-rw-r--r--libgo/go/compress/flate/reader_test.go95
-rw-r--r--libgo/go/crypto/elliptic/elliptic.go2
-rw-r--r--libgo/go/crypto/rand/rand_test.go11
-rw-r--r--libgo/go/crypto/rand/rand_windows.go4
-rw-r--r--libgo/go/crypto/rsa/pkcs1v15.go29
-rw-r--r--libgo/go/crypto/tls/conn.go10
-rw-r--r--libgo/go/crypto/x509/verify.go2
-rw-r--r--libgo/go/crypto/x509/x509.go55
-rw-r--r--libgo/go/database/sql/fakedb_test.go6
-rw-r--r--libgo/go/database/sql/sql.go9
-rw-r--r--libgo/go/encoding/binary/varint.go2
-rw-r--r--libgo/go/encoding/gob/decode.go6
-rw-r--r--libgo/go/encoding/gob/doc.go2
-rw-r--r--libgo/go/encoding/gob/encoder_test.go29
-rw-r--r--libgo/go/encoding/gob/type.go18
-rw-r--r--libgo/go/encoding/json/encode.go2
-rw-r--r--libgo/go/flag/flag.go4
-rw-r--r--libgo/go/fmt/fmt_test.go12
-rw-r--r--libgo/go/fmt/print.go5
-rw-r--r--libgo/go/go/ast/print.go73
-rw-r--r--libgo/go/go/ast/print_test.go21
-rw-r--r--libgo/go/go/ast/resolve.go2
-rw-r--r--libgo/go/go/ast/walk.go3
-rw-r--r--libgo/go/go/build/build.go6
-rw-r--r--libgo/go/go/build/build_test.go29
-rw-r--r--libgo/go/go/build/doc.go2
-rw-r--r--libgo/go/go/doc/reader.go2
-rw-r--r--libgo/go/go/doc/testdata/error2.1.golden2
-rw-r--r--libgo/go/go/doc/testdata/error2.go2
-rw-r--r--libgo/go/go/printer/nodes.go7
-rw-r--r--libgo/go/go/printer/printer_test.go29
-rw-r--r--libgo/go/go/scanner/errors.go2
-rw-r--r--libgo/go/go/scanner/scanner.go2
-rw-r--r--libgo/go/html/template/content.go2
-rw-r--r--libgo/go/html/template/url.go2
-rw-r--r--libgo/go/image/jpeg/reader.go28
-rw-r--r--libgo/go/image/jpeg/writer.go48
-rw-r--r--libgo/go/image/jpeg/writer_test.go82
-rw-r--r--libgo/go/image/names.go2
-rw-r--r--libgo/go/io/io.go12
-rw-r--r--libgo/go/log/syslog/syslog.go12
-rw-r--r--libgo/go/log/syslog/syslog_test.go40
-rw-r--r--libgo/go/math/all_test.go11
-rw-r--r--libgo/go/math/big/nat.go2
-rw-r--r--libgo/go/math/bits.go2
-rw-r--r--libgo/go/math/remainder.go2
-rw-r--r--libgo/go/mime/grammar.go2
-rw-r--r--libgo/go/mime/multipart/multipart.go2
-rw-r--r--libgo/go/net/dial.go2
-rw-r--r--libgo/go/net/fd.go4
-rw-r--r--libgo/go/net/file.go22
-rw-r--r--libgo/go/net/http/client.go95
-rw-r--r--libgo/go/net/http/client_test.go52
-rw-r--r--libgo/go/net/http/example_test.go2
-rw-r--r--libgo/go/net/http/export_test.go8
-rw-r--r--libgo/go/net/http/fs.go132
-rw-r--r--libgo/go/net/http/fs_test.go263
-rw-r--r--libgo/go/net/http/header.go40
-rw-r--r--libgo/go/net/http/httptest/server.go14
-rw-r--r--libgo/go/net/http/httputil/dump.go2
-rw-r--r--libgo/go/net/http/pprof/pprof.go8
-rw-r--r--libgo/go/net/http/range_test.go22
-rw-r--r--libgo/go/net/http/serve_test.go46
-rw-r--r--libgo/go/net/http/server.go33
-rw-r--r--libgo/go/net/http/transport.go111
-rw-r--r--libgo/go/net/http/transport_test.go115
-rw-r--r--libgo/go/net/iprawsock.go4
-rw-r--r--libgo/go/net/iprawsock_plan9.go4
-rw-r--r--libgo/go/net/iprawsock_posix.go4
-rw-r--r--libgo/go/net/mail/message.go3
-rw-r--r--libgo/go/net/net_posix.go110
-rw-r--r--libgo/go/net/rpc/jsonrpc/all_test.go8
-rw-r--r--libgo/go/net/rpc/server.go11
-rw-r--r--libgo/go/net/sockopt.go16
-rw-r--r--libgo/go/os/error_plan9.go21
-rw-r--r--libgo/go/os/error_posix.go21
-rw-r--r--libgo/go/os/error_test.go27
-rw-r--r--libgo/go/os/error_windows.go21
-rw-r--r--libgo/go/os/exec.go11
-rw-r--r--libgo/go/os/exec/exec.go8
-rw-r--r--libgo/go/os/exec/exec_test.go72
-rw-r--r--libgo/go/os/exec_plan9.go4
-rw-r--r--libgo/go/os/exec_posix.go5
-rw-r--r--libgo/go/os/exec_unix.go4
-rw-r--r--libgo/go/os/exec_windows.go4
-rw-r--r--libgo/go/os/file_posix.go11
-rw-r--r--libgo/go/os/file_unix.go13
-rw-r--r--libgo/go/os/os_test.go10
-rw-r--r--libgo/go/os/types.go2
-rw-r--r--libgo/go/path/path.go3
-rw-r--r--libgo/go/path/path_test.go1
-rw-r--r--libgo/go/reflect/all_test.go23
-rw-r--r--libgo/go/reflect/value.go3
-rw-r--r--libgo/go/regexp/regexp.go9
-rw-r--r--libgo/go/runtime/pprof/pprof.go2
-rw-r--r--libgo/go/runtime/pprof/pprof_test.go19
-rw-r--r--libgo/go/strconv/atoi.go22
-rw-r--r--libgo/go/sync/waitgroup.go3
-rw-r--r--libgo/go/sync/waitgroup_test.go2
-rw-r--r--libgo/go/syscall/env_windows.go20
-rw-r--r--libgo/go/syscall/exec_unix.go62
-rw-r--r--libgo/go/syscall/exec_windows.go20
-rw-r--r--libgo/go/syscall/security_windows.go30
-rw-r--r--libgo/go/syscall/syscall.go39
-rw-r--r--libgo/go/syscall/syscall_linux_386.go8
-rw-r--r--libgo/go/testing/testing.go87
-rw-r--r--libgo/go/text/tabwriter/tabwriter.go2
-rw-r--r--libgo/go/text/template/doc.go2
-rw-r--r--libgo/go/text/template/exec_test.go2
-rw-r--r--libgo/go/text/template/funcs.go4
-rw-r--r--libgo/go/text/template/parse/lex.go5
-rw-r--r--libgo/go/text/template/parse/lex_test.go4
-rw-r--r--libgo/go/time/time.go6
-rw-r--r--libgo/runtime/chan.c16
-rw-r--r--libgo/runtime/cpuprof.c14
-rw-r--r--libgo/runtime/go-caller.c7
-rw-r--r--libgo/runtime/print.c4
-rw-r--r--libgo/runtime/runtime.c12
-rw-r--r--libgo/runtime/runtime.h1
-rw-r--r--libitm/ChangeLog6
-rw-r--r--libitm/config/x86/sjlj.S3
-rw-r--r--libitm/config/x86/target.h8
-rw-r--r--libstdc++-v3/ChangeLog108
-rw-r--r--libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver3
-rw-r--r--libstdc++-v3/include/c_global/ccomplex6
-rw-r--r--libstdc++-v3/include/c_global/cfloat7
-rw-r--r--libstdc++-v3/include/c_global/cstdint19
-rw-r--r--libstdc++-v3/include/c_global/cstdlib49
-rw-r--r--libstdc++-v3/include/c_global/cwctype19
-rw-r--r--libstdc++-v3/include/c_std/cstdlib16
-rw-r--r--libstdc++-v3/include/ext/concurrence.h39
-rw-r--r--libstdc++-v3/include/ext/random8
-rw-r--r--libstdc++-v3/include/ext/random.tcc4
-rw-r--r--libstdc++-v3/include/std/array49
-rw-r--r--libstdc++-v3/include/std/mutex40
-rw-r--r--libstdc++-v3/include/std/type_traits203
-rw-r--r--libstdc++-v3/include/tr2/dynamic_bitset4
-rw-r--r--libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc4
-rw-r--r--libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc17
-rw-r--r--libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc17
-rw-r--r--libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc736
-rw-r--r--libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_2.cc76
-rw-r--r--libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc4
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc48
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc14
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc6
-rw-r--r--libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/headers/cstdlib/54686.c32
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_01.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_00_03.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_01_03.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_02_03.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/extended/cstring_plus.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/extended/cstring_questionmark.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_any.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_00_03.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_01_03.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc (renamed from libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_02_03.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/default.cc (renamed from libstdc++-v3/testsuite/28_regex/basic_regex/regex.cc)0
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc52
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_regex.h130
647 files changed, 27607 insertions, 8559 deletions
diff --git a/ChangeLog b/ChangeLog
index 48c9e06b1..eb44ef694 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2012-10-04 Lawrence Crowl <crowl@google.com>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
+2012-10-01 Cary Coutant <ccoutant@google.com>
+
+ * MAINTAINERS: Add myself as dwarf debugging code maintainer.
+
2012-09-28 Ian Lance Taylor <iant@google.com>
* Makefile.def: Make all-target-libgo depend on
diff --git a/MAINTAINERS b/MAINTAINERS
index 4a6d8c591..8d816b1b5 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -185,6 +185,7 @@ caller-save.c Jeff Law law@redhat.com
callgraph Jan Hubicka jh@suse.cz
debugging code Jim Wilson wilson@tuliptree.org
dwarf debugging code Jason Merrill jason@redhat.com
+dwarf debugging code Cary Coutant ccoutant@google.com
c++ runtime libs Paolo Carlini paolo.carlini@oracle.com
c++ runtime libs Gabriel Dos Reis gdr@integrable-solutions.net
c++ runtime libs Ulrich Drepper drepper@gmail.com
@@ -342,6 +343,7 @@ R. Kelley Cook kcook@gcc.gnu.org
Christian Cornelssen ccorn@cs.tu-berlin.de
François-Xavier Coudert fxcoudert@gcc.gnu.org
Cary Coutant ccoutant@google.com
+Lawrence Crowl crowl@google.com
Ian Dall ian@beware.dropbear.id.au
David Daney david.daney@caviumnetworks.com
Bud Davis jmdavis@link.com
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 9e619d077..d5ec0bab4 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,11 @@
+2012-10-06 Diego Novillo <dnovillo@google.com>
+
+ * testsuite-management/x86_64-unknown-linux-gnu.xfail: Update.
+
+2012-10-02 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * check_GNU_style.sh: Remove temporay file upon exit.
+
2012-09-26 Joern Rennecke <joern.rennecke@embecosm.com>
* contrib-list.mk (LIST): Remove arm-freebsd6, arm-linux,
diff --git a/contrib/check_GNU_style.sh b/contrib/check_GNU_style.sh
index 8fb579fd1..b7f1c9d93 100755
--- a/contrib/check_GNU_style.sh
+++ b/contrib/check_GNU_style.sh
@@ -37,6 +37,10 @@ test $# -eq 0 && usage
tmp=check_GNU_style.tmp
+# Remove $tmp on exit and various signals.
+trap "rm -f $tmp" 0
+trap "rm -f $tmp ; exit 1" 1 2 3 5 9 13 15
+
# Grep
g (){
msg="$1"
diff --git a/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail b/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
index b4e598722..59b3f912b 100644
--- a/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
+++ b/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
@@ -1,6 +1,7 @@
XPASS: gcc.dg/Wstrict-overflow-18.c (test for bogus messages, line 20)
UNRESOLVED: gcc.dg/attr-weakref-1.c compilation failed to produce executable
FAIL: gcc.dg/attr-weakref-1.c (test for excess errors)
+FAIL: gcc.dg/builtin-object-size-8.c execution test
XPASS: gcc.dg/guality/example.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/example.c -O2 execution test
XPASS: gcc.dg/guality/example.c -O0 execution test
@@ -16,59 +17,38 @@ XPASS: gcc.dg/guality/inline-params.c -O2 execution test
XPASS: gcc.dg/guality/inline-params.c -O3 -g execution test
XPASS: gcc.dg/guality/inline-params.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/inline-params.c -O3 -fomit-frame-pointer execution test
-XPASS: gcc.dg/guality/inline-params.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
XPASS: gcc.dg/guality/inline-params.c -Os execution test
XPASS: gcc.dg/guality/pr41447-1.c -O2 execution test
-XPASS: gcc.dg/guality/pr41447-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
-XPASS: gcc.dg/guality/pr41447-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O1 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O3 -fomit-frame-pointer execution test
XPASS: gcc.dg/guality/pr41447-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O3 -g execution test
XPASS: gcc.dg/guality/pr41447-1.c -Os execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O1 execution test
XPASS: gcc.dg/guality/pr41616-1.c -O3 -fomit-frame-pointer execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O1 execution test
XPASS: gcc.dg/guality/pr41616-1.c -O2 execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/pr41616-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41616-1.c -Os execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/pr41616-1.c -O3 -g execution test
XPASS: gcc.dg/inline_3.c (test for excess errors)
XPASS: gcc.dg/inline_4.c (test for excess errors)
-FAIL: gcc.dg/pr52558-2.c scan-tree-dump-times lim1 "MEM.*g_2_lsm_flag" 1
-FAIL: gcc.dg/tm/reg-promotion.c scan-tree-dump-times lim1 "MEM count_lsm.. count_lsm_flag" 1
FAIL: gcc.dg/torture/pr51106-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (test for excess errors)
FAIL: gcc.dg/torture/pr51106-2.c -O3 -g (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O0 (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -O1 (internal compiler error)
FAIL: gcc.dg/torture/pr51106-2.c -O0 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -g (internal compiler error)
FAIL: gcc.dg/torture/pr51106-2.c -O1 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -Os (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -fomit-frame-pointer (internal compiler error)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none (internal compiler error)
FAIL: gcc.dg/torture/pr51106-2.c -Os (test for excess errors)
FAIL: gcc.dg/torture/pr51106-2.c -O3 -fomit-frame-pointer (test for excess errors)
+FAIL: gcc.dg/torture/pr51106-2.c -O2 (test for excess errors)
XPASS: gcc.dg/unroll_2.c (test for excess errors)
XPASS: gcc.dg/unroll_3.c (test for excess errors)
XPASS: gcc.dg/unroll_4.c (test for excess errors)
-FAIL: gcc.target/i386/pad-10.c scan-assembler-not nop
-FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin (internal compiler error)
-UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects
-FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error)
-UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
-FAIL: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin (internal compiler error)
-UNRESOLVED: gfortran.dg/lto/pr45586 f_lto_pr45586_0.o-f_lto_pr45586_0.o execute -O0 -flto -flto-partition=none -fuse-linker-plugin
-UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -flto-partition=none -fuse-linker-plugin
-UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
-FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin (internal compiler error)
-UNRESOLVED: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o execute -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects
-FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin (internal compiler error)
-FAIL: gfortran.dg/lto/pr45586-2 f_lto_pr45586-2_0.o-f_lto_pr45586-2_0.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects (internal compiler error)
FAIL: gnat.dg/array11.adb (test for warnings, line 12)
FAIL: gnat.dg/object_overflow.adb (test for warnings, line 8)
FAIL: libmudflap.c++/pass55-frag.cxx (-O2) execution test
FAIL: libmudflap.c++/pass55-frag.cxx ( -O) execution test
FAIL: libmudflap.c++/pass55-frag.cxx (-O3) execution test
+FAIL: sourcelocation output - source compiled test
+FAIL: sourcelocation -findirect-dispatch output - source compiled test
+FAIL: sourcelocation -O3 output - source compiled test
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d338ee37d..8f944d7fd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,725 @@
+2012-10-08 Hans-Peter Nilsson <hp@bitrange.com>
+
+ * config/mmix/mmix.c (mmix_output_octa): Don't assume
+ HOST_WIDEST_INT_PRINT_HEX starts with "0x". Instead use
+ HOST_WIDE_INT_PRINT_HEX_PURE, falling back to
+ HOST_WIDEST_INT_PRINT_UNSIGNED.
+
+2012-10-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * machmode.h (GET_MODE_UNIT_PRECISION): New macro.
+ * simplify-rtx.c (simplify_truncation): New function,
+ extracted from simplify_subreg and (in small part) from
+ simplify_unary_operation_1.
+ (simplify_unary_operation_1) <TRUNCATE>: Use it. Remove sign bit
+ test for !TRULY_NOOP_TRUNCATION_MODES_P.
+ (simplify_subreg): Use simplify_truncate for lowpart subregs
+ where both the inner and outer modes are scalar integers.
+ * config/mips/mips.c (mips_truncated_op_cost): New function.
+ (mips_rtx_costs): Adjust test for BADDU.
+ * config/mips/mips.md (*baddu_di<mode>): Push truncates to operands.
+
+2012-10-07 Jan Hubicka <jh@suse.cz>
+
+ * ipa-inline-analysis.c (do_estimate_edge_time): Return actual
+ time spent by the inlined sequence.
+ (do_estimate_edge_growth): Rename to ...
+ (do_estimate_edge_time): ... this one; return size of inlined
+ sequence.
+ * ipa-inline.h (do_estimate_edge_size): New.
+ (do_estimate_edge_growth): Remove.
+ (estimate_edge_size): New function.
+ (estimate_edge_growth): Use it.
+
+2012-10-07 Jan Hubicka <jh@suse.cz>
+
+ * lto-cgraph.c (lto_symtab_encoder_new): New parameter FOR_INPUT.
+ (lto_symtab_encoder_delete): Update.
+ (lto_symtab_encoder_encode): Update.
+ (compute_ltrans_boundary): Update.
+ (input_symtab): Update.
+ * lto-streamer.h (lto_symtab_encoder_new): Update.
+
+2012-10-07 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips-protos.h (mips_split_type): New enum.
+ (mips_split_64bit_move_p, mips_split_doubleword_move): Delete.
+ (mips_split_move_p, mips_split_move, mips_split_move_insn_p)
+ (mips_split_move_insn): Declare.
+ * config/mips/mips.c (mips_tuning_info): New variable.
+ (mips_load_store_insns): Use mips_split_move_insn_p instead of
+ mips_split_64bit_move_p.
+ (mips_emit_move_or_split, mips_mult_move_p): New functions.
+ (mips_split_64bit_move_p): Rename to...
+ (mips_split_move_p): ...this and take a mips_split_type argument.
+ Generalize to all moves. Call mips_mult_move_p.
+ (mips_split_doubleword_move): Rename to...
+ (mips_split_move): ...this and take a mips_split_type argument.
+ Assert that mips_split_move_p holds.
+ (mips_insn_split_type, mips_split_move_insn_p, mips_split_move_insn):
+ New functions.
+ (mips_output_move): Use mips_split_move_p instead of
+ mips_split_64bit_move_p. Handle MULT $0, $0 moves.
+ (mips_save_reg): Use mips_emit_move_or_split.
+ (mips_sim_reset): Assign to curr_state. Call targetm.sched.init
+ and advance_state.
+ (mips_sim_init): Call targetm.sched.init_dfa_pre_cycle_insn and
+ targetm.sched.init_dfa_post_cycle_insn, if defined.
+ (mips_sim_next_cycle): Assign to curr_state. Use advance_state
+ instead of state_transition.
+ (mips_sim_issue_insn): Assign to curr_state. Use
+ targetm.sched.variable_issue to see how many more insns
+ can be issued.
+ (mips_seq_time, mips_mult_zero_zero_cost)
+ (mips_set_fast_mult_zero_zero_p, mips_set_tuning_info)
+ (mips_expand_to_rtl_hook): New functions.
+ (TARGET_EXPAND_TO_RTL_HOOK): Define.
+ * config/mips/mips.md (move_type): Add imul.
+ (type): Map imul move_types to imul.
+ (*movdi_32bit, *movti): Add imul alternatives.
+ Use mips_split_move_insn_p and mips_split_move_insn instead of
+ mips_split_64bit_move_p and mips_split_doubleword_move in move
+ splitters.
+
+2012-10-06 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config/rs6000/rs6000.c (print_operand) ['A']: Delete.
+
+2012-10-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52764
+ * ginclude/stdint-wrap.h: In C++11 if __STDC_HOSTED__ define
+ __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS.
+ * ginclude/stdint-gcc.h: In C++11 unconditionally define
+ limit and constant macros.
+
+2012-10-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54249
+ * ginclude/stddef.h: In C++11 mode declare nullptr_t in the global
+ namespace.
+
+2012-10-06 Jan Hubicka <jh@suse.cz>
+
+ PR lto/53831
+ PR lto/54776
+ * lto-streamer-out.c (produce_symtab): Cleanup; drop v1 API hack.
+
+2012-10-06 Dehao Chen <dehao@google.com>
+
+ PR debug/54826
+ * gimple-low.c (lower_stmt): Set the block for call args.
+
+2012-10-06 Jan Hubicka <jh@suse.cz>
+
+ * doc/invoke.texi (-fprofile-report): Document.
+ * common.opt (-fprofile-report): New option.
+ * toplev.c (finalize): Call dump_profile_report.
+ * toplev.h (profile_report): Declare.
+ * passes.c (profile_record): New static var.
+ (check_profile_consistency): New function.
+ (dump_profile_record): New function.
+ (execute_one_ipa_transform_pass): Call check_profile_consistency.
+ (execute_one_pass): Likewise.
+
+2012-10-06 Jan Hubicka <jh@suse.cz>
+
+ PR lto/54790
+ * lto-streamer.h (lto_symtab_register_decl, lto_symtab_get_resolution,
+ lto_mark_nothrow_fndecl, lto_fixup_nothrow_decls): Remove.
+ * lto-symtab.c (lto_symtab_register_decl): Remove.
+
+2012-10-06 Andreas Schwab <schwab@linux-m68k.org>
+
+ PR rtl-optimization/54739
+ * config/m68k/m68k.md (anddi3, iordi3, xordi3, one_cmpldi2):
+ Remove.
+
+2012-10-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54760
+ * config/sh/sh.md (define_constants): Add UNSPECV_GBR.
+ (get_thread_pointer, set_thread_pointer): New expanders.
+ (load_gbr): Rename to store_gbr. Remove GBR_REG use.
+ (store_gbr): New insn.
+ * config/sh/sh.c (prepare_move_operands): Use gen_store_gbr instead of
+ gen_load_gbr in TLS_MODEL_LOCAL_EXEC case.
+ (sh1_builtin_p): New function.
+ (signature_args): Add SH_BLTIN_VP.
+ (bdesc): Add __builtin_thread_pointer and __builtin_set_thread_pointer.
+
+2012-10-05 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ PR rtl-optimization/54739
+ * config/pa/pa.md: Remove DImode and, not and, ior and xor patterns
+ for 32-bit targets. Adjust expanders.
+
+ * config/pa/pa.md: Adjust unamed HImode add insn pattern.
+
+2012-10-05 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.c (builtin_description): Add is_enabled member.
+ (shmedia_builtin_p): New function.
+ (bdesc): Use shmedia_builtin_p for existing built-ins.
+ (sh_media_init_builtins, sh_init_builtins): Merge into single function
+ sh_init_builtins. Add is_enabled checking. Move variable declarations
+ to where they are actually used.
+ (sh_media_builtin_decl, sh_builtin_decl): Merge into single function
+ sh_builtin_decl. Add is_enabled checking.
+ (sh_expand_builtin): Move variable declarations to where they are
+ actually used.
+
+2012-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ * tree-inline.c (expand_call_inline): Move VAR_DECLs with
+ PARM_DECL origins from remapped DECL_INITIAL's BLOCK_VARS
+ into id->block's BLOCK_VARS.
+
+ PR debug/54519
+ * ipa-split.c (split_function): Add debug args and
+ debug source and normal stmts for args_to_skip which are
+ gimple regs.
+ * tree-inline.c (copy_debug_stmt): When inlining, adjust
+ source debug bind stmts to debug binds of corresponding
+ DEBUG_EXPR_DECL.
+
+2012-10-05 Georg-Johann Lay <avr@gjlay.de>
+
+ * config/avr/avr.md: Fix indentations of insn C snippets.
+
+2012-10-05 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/54811
+ * tree-ssa-live.c (clear_unused_block_pointer_1): Look at
+ DECL_DEBUG_EXPR again.
+
+2012-10-05 Jan Hubicka <jh@suse.cz>
+ Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/33763
+ * tree-inline.c (expand_call_inline): Silently ignore always_inline
+ attribute for redefined extern inline functions.
+
+2012-10-04 Jan Hubicka <jh@suse.cz>
+
+ * tree-vectorizer.h (vect_estimate_min_profitable_iters): Remove.
+ * tree-vect-loop.c (vect_estimate_min_profitable_iters): Declare here.
+ (vect_analyze_loop_operations): Use loop count estimate to rule out
+ unprofitable vectorization.
+ (vect_estimate_min_profitable_iters): Return ret_min_profitable_estimate.
+
+2012-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/54810
+ * tree-vrp.c (register_edge_assert_for_2): Handle
+ NAME = (unsigned) NAME2; if (NAME cmp CST) for
+ narrowing casts to unsigned integral type like
+ NAME = NAME2 & CST2; if (NAME cmp CST) where CST2
+ is the max value of the unsigned integral type.
+
+2012-10-04 Jeff Law <law@redhat.com>
+
+ * PR target/50356
+ * config/h8300/h8300.c (h8300_rtx_costs): Fix typo in CONST_INT case.
+
+2012-10-04 Jason Merrill <jason@redhat.com>
+
+ * config/rs6000/rs6000.c (rs6000_code_end): Protect the use of
+ ASM_WEAKEN_DECL with #if RS6000_WEAK.
+
+2012-10-04 Basile Starynkevitch <basile@starynkevitch.net>
+
+ * gengtype.c (walk_type): Emit mark_hook when inside a
+ struct of a union member.
+
+2012-10-04 Georg-Johann Lay <avr@gjlay.de>
+
+ * config/avr/predicates.md (flash_operand): New predicate.
+ * config/avr/avr.md (reload_in<mode>): Use it in operand 1 instead
+ of memory_operand.
+
+2012-10-04 Tobias Burnus <burnus@net-b.de>
+
+ * gcc.c (record_temp_file, add_sysrooted_prefix, process_command,
+ do_self_spec, compare_debug_dump_opt_spec_function): Plug memleaks.
+ (do_spec_1): Ditto, fix out-of-bound access.
+ * opts.c (common_handle_option): Plug memleak.
+
+2012-10-04 Jason Merrill <jason@redhat.com>
+
+ * config/darwin.c (darwin_assemble_visibility): Treat
+ VISIBILITY_INTERNAL as hidden.
+
+ * config/darwin-c.c (find_subframework_file): Add missing const.
+ (framework_construct_pathname): Likewise.
+
+2012-10-04 Florian Weimer <fweimer@redhat.com>
+
+ * doc/cpp.texi (Pragmas): Document #pragma GCC warning, #pragma
+ GCC error.
+
+2012-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/54735
+ * tree-ssa-pre.c (do_pre): Make sure to update virtual SSA form before
+ cleaning up the CFG.
+
+2012-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR lto/47799
+ * tree-streamer-out.c (write_ts_block_tree_pointers): For
+ inlined functions outer scopes write the ultimate origin
+ as BLOCK_ABSTRACT_ORIGIN and BLOCK_SOURCE_LOCATION.
+ Do not stream the fragment chains.
+ * tree-streamer-in.c (lto_input_ts_block_tree_pointers): Likewise.
+ * dwarf2out.c (gen_subprogram_die): Handle NULL DECL_INITIAL.
+ (dwarf2out_decl): Always output DECL_ABSTRACT function decls.
+
+2012-10-04 Arnaud Charlet <charlet@adacore.com>
+
+ * dumpfile.h, dumpfile.c: Remove TDI_ada.
+
+2012-10-04 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ * config/i386/i386.c (ix86_dep_by_shift_count_body) : Add
+ check on reload_completed since it can be invoked before
+ register allocation phase in pre-reload schedule.
+ (ia32_multipass_dfa_lookahead) : Do not use dfa_lookahead for pre-reload
+ schedule to save compile time.
+ (ix86_sched_reorder) : Do not perform ready list reordering for pre-reload
+ schedule to save compile time.
+ (insn_is_function_arg) : New function. Returns true if lhs of insn is
+ HW function argument register.
+ (add_parameter_dependencies) : New function. Add output dependencies
+ for chain of function adjacent arguments if only there is a move to
+ likely spilled HW registers. Return first argument if at least one
+ dependence was added or NULL otherwise.
+ (avoid_func_arg_motion) : New function. Add output or anti dependency
+ from insn to first_arg to restrict code motion.
+ (add_dependee_for_func_arg) : New function. Avoid cross block motion of
+ function argument through adding dependency from the first non-jump
+ insn in bb.
+ (ix86_dependencies_evaluation_hook) : New function. Hook for pre-reload schedule:
+ avoid motion of function arguments passed in passed in likely spilled
+ HW registers.
+ (ix86_adjust_priority) : New function. Hook for pre-reload schedule: set priority
+ of moves from likely spilled HW registers to maximum to schedule them
+ as soon as possible.
+ (ix86_sched_init_global): Do not perform multipass scheduling for pre-reload
+ schedule to save compile time.
+
+2012-10-04 Uros Bizjak <ubizjak@gmail.com>
+
+ * configure.ac (noexception_flags): Add -fasynchronous-unwind-tables.
+ * configure: Regenerate.
+
+2012-10-04 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ * config/sh/sh.c (sh_can_use_simple_return_p): Return false for
+ SHmedia and SHcompact using call cookie.
+ * config/sh/sh.md (epilogue): Emit non-inlined return insns for
+ SHmedia and SHcompact using call cookie.
+
+2012-10-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * config/sh/sh.md (*mov_t_msb_neg): New insn and two accompanying
+ unnamed split patterns.
+
+2012-10-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/50457
+ * config/sh/sh.c (parse_validate_atomic_model_option): Handle name
+ strings in sh_atomic_model.
+ * config/sh/sh.h (TARGET_CPU_CPP_BUILTINS): Move macro implementation
+ to ...
+ * config/sh/sh-c.c (sh_cpu_cpp_builtins): ... this new function.
+ Add __SH1__ and __SH2__ defines. Add __SH_ATOMIC_MODEL_*__ define.
+ * config/sh/sh-protos.h (sh_atomic_model): Add name and cdef_name
+ variables.
+ (sh_cpu_cpp_builtins): Declare new function.
+
+2012-10-03 Dehao Chen <dehao@google.com>
+
+ PR middle-end/54782
+ * tree-cfg.c (move_block_to_fn): Update lexical block for phi_args.
+
+2012-10-03 Vladimir Makarov <vmakarov@redhat.com>
+
+ * reginfo.c (max_regno_since_last_resize): New.
+ (reg_preferred_class, reg_alternate_class): Add assert.
+ (allocate_reg_info): Initialize allocated reg info.
+ (resize_reg_info): Make bigger reg_info and initialize new memory.
+ (reginfo_init): Initialize max_regno_since_last_resize.
+ (setup_reg_classes): Change assert.
+
+2012-10-03 Andrew W. Nosenko <andrew.w.nosenko@gmail.com>
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Fix logic
+ in SSE and YMM state support check for -march=native.
+
+2012-10-03 Nick Clifton <nickc@redhat.com>
+
+ * config/rx/rx.c (struct decl_chain): New local structure.
+ (warned_decls): New local variable. Contains a stack of decls for
+ which warnings have been issued.
+ (add_warned_decl): Adds a decl to the stack.
+ (already_warned): Returns true if a given decl is on the stack.
+ (rx_set_current_function): Issue a warning if multiple fast
+ interrupt handlers are defined.
+ * config/rx/rx.opt (mwarn-multiple-fast-interrupts): New option.
+ * doc/invoke.texi: Document the option.
+
+2012-10-03 Mark Kettenis <kettenis@openbsd.org>
+
+ * config.gcc (*-*-openbsd4.[3-9]|*-*-openbsd[5-9]*): Set
+ default_use_cxa_atexit to yes.
+
+2012-10-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/54792
+ * sched-deps.c (find_modifiable_mems): Scan also TAIL insn.
+
+2012-10-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/54785
+ * doc/invoke.texi: Document -mprefer-avx128.
+
+2012-10-02 Andrew Pinski <apinski@cavium.com>
+
+ * simplify-rtx.c (simplify_unary_operation_1 <case TRUNCATE>):
+ Don't optimize a truncate of a mem if it is a vector mode.
+
+2012-10-02 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/54551
+ * Makefile.in (VALTRACK_H): Add hash-table.h.
+ * valtrack.h: Include hash-table.h.
+ (struct dead_debug_global_entry): New.
+ (struct dead_debug_hash_descr): New.
+ (struct dead_debug_global): New.
+ (struct dead_debug): Rename to...
+ (struct dead_debug_local): ... this. Adjust all uses.
+ (dead_debug_global_init, dead_debug_global_finish): New.
+ (dead_debug_init): Rename to...
+ (dead_debug_local_init): ... this. Adjust all callers.
+ (dead_debug_finish): Rename to...
+ (dead_debug_local_finish): ... this. Adjust all callers.
+ * valtrack.c (dead_debug_global_init): New.
+ (dead_debug_init): Rename to...
+ (dead_debug_local_init): ... this. Take global parameter.
+ Save it and initialize used bitmap from it.
+ (dead_debug_global_find, dead_debug_global_insert): New.
+ (dead_debug_global_replace_temp): New.
+ (dead_debug_promote_uses): New.
+ (dead_debug_finish): Rename to...
+ (dead_debug_local_finish): ... this. Promote remaining uses.
+ (dead_debug_global_finish): New.
+ (dead_debug_add): Try to replace global temps first.
+ (dead_debug_insert_temp): Support global replacements.
+ * dce.c (word_dce_process_block, dce_process_block): Add
+ global_debug parameter. Pass it on.
+ (fast_dce): Initialize, pass on and finalize global_debug.
+ * df-problems.c (df_set_unused_notes_for_mw): Adjusted.
+ (df_create_unused_notes, df_note_bb_compute): Likewise.
+ (df_note_compute): Justify local-only dead debug analysis.
+
+2012-10-02 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/53135
+ * dwarf2out.c (value_format): Use block4 for dw_val_class_loc
+ when needed.
+
+2012-10-02 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/54177
+ * var-tracking.c (vt_add_function_parameter): Bail if
+ var_lowpart fails.
+
+2012-10-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/54741
+ * config/i386/driver-i386.c (XCR_XFEATURE_ENABLED_MASK): New.
+ (XSTATE_FP): Likewise.
+ (XSTATE_SSE): Likewise.
+ (XSTATE_YMM): Likewise.
+ (host_detect_local_cpu): Disable AVX, AVX2, FMA, FMA4 and XOP if
+ SSE and YMM states aren't supported.
+
+2012-10-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.md (*baddu_si_eb, *baddu_si_el): Merge into...
+ (*baddu_si): ...this new pattern.
+
+2012-10-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * ira-int.h (target_ira_int): Add x_ira_useful_class_mode_regs.
+ (ira_useful_class_mode_regs): New macro.
+ * ira.c (clarify_prohibited_class_mode_regs): Set up
+ ira_useful_class_mode_regs.
+ * ira-color.c (setup_profitable_hard_regs): Use it to initialise
+ profitable_hard_regs.
+
+2012-10-02 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * ira.h (target_ira): Add x_ira_class_singleton.
+ (ira_class_singleton): New macro.
+ * ira.c (setup_prohibited_class_mode_regs): Set up ira_class_singleton.
+ * ira-build.c (update_conflict_hard_reg_costs): Use
+ ira_class_singleton to check for classes with a single
+ allocatable register.
+ * ira-lives.c (ira_implicitly_set_insn_hard_regs): Likewise.
+ (single_reg_class): Likewise. When more than one class is specified,
+ check whether they have the same singleton register.
+ (process_single_reg_class_operands): Require single_reg_class
+ to return NO_REGS or a class with a single allocatable register.
+ Obtain that register from ira_class_singleton.
+
+2012-10-02 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_option_override_internal): If
+ -mcpu=<xxx> is not specified and the compiler is not configured
+ using --with-cpu=<xxx>, use the bits from the TARGET_DEFAULT to
+ set the initial options.
+
+2012-10-02 Sharad Singhai <singhai@google.com>
+
+ PR testsuite/54772
+ * tree-vect-stmts.c (vectorizable_operation): Add missing return.
+
+2012-10-02 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/rs6000.c (rs6000_option_override_internal): Do not
+ set TARGET_ALTIVEC_VRSAVE for TARGET_ELF.
+ (rs6000_stack_info): Only set vrsave_mask if TARGET_ALTIVEC_VRSAVE.
+
+2012-10-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/54713
+ * expr.c (categorize_ctor_elements_1): Don't assume purpose is
+ non-NULL.
+ * tree-cfg.c (verify_gimple_assign_single): Add verification of
+ vector CONSTRUCTORs.
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): For VECTOR_TYPE
+ CONSTRUCTORs, don't do anything if element type is VECTOR_TYPE,
+ and don't check index.
+ * tree-vect-slp.c (vect_get_constant_vectors): VIEW_CONVERT_EXPR ctor
+ elements first if their type isn't compatible with vector element type.
+
+2012-10-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree.h (DECL_NONLOCAL_FRAME): New macro.
+ * tree-nested.c (get_frame_type): Set DECL_NONLOCAL_FRAME.
+ * tree-streamer-in.c (unpack_ts_decl_common_value_fields): Stream in
+ DECL_NONLOCAL_FRAME flag.
+ * tree-streamer-out.c (pack_ts_decl_common_value_fields): Stream out
+ DECL_NONLOCAL_FRAME flag.
+
+2012-10-02 Marc Glisse <marc.glisse@inria.fr>
+
+ * tree-ssa-forwprop.c (forward_propagate_into_cond): Don't use
+ boolean_type_node for vectors.
+
+2012-10-01 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (toplevel): Include dumpfile.h.
+ (rs6000_density_test): Rework to accommodate 09-30 change by
+ Sharad Singhai.
+
+ * config/rs6000/t-rs6000 (rs6000.o): Add dumpfile.h dependency.
+
+2012-10-01 Dehao Chen <dehao@google.com>
+
+ PR middle-end/54759
+ * tree-vect-loop-manip.c (slpeel_make_loop_iterate_ntimes): Use
+ LOCATION_LOCUS to compare with UNKNOWN_LOCATION.
+ (slpeel_tree_peel_loop_to_edge): Likewise.
+ * tree-vectorizer.c (vectorize_loops): Likewise.
+
+2012-10-01 Andrew MacLeod <amacleod@redhat.com>
+
+ PR target/54087
+ * optabs.c (expand_atomic_fetch_op_no_fallback): New. Factored code
+ from expand_atomic_fetch_op.
+ (expand_atomic_fetch_op): Try atomic_{add|sub} operations in terms of
+ the other one if direct opcode fails.
+
+2012-10-01 Uros Bizjak <ubizjak@gmail.com>
+
+ PR rtl-optimization/54457
+ * simplify-rtx.c (simplify_subreg):
+ Simplify (subreg:M (op:N ((x:N) (y:N)), 0)
+ to (op:M (subreg:M (x:N) 0) (subreg:M (x:N) 0)), where
+ the outer subreg is effectively a truncation to the original mode M.
+
+2012-10-01 Richard Guenther <rguenther@suse.de>
+
+ * builtins.def (ATTR_MATHFN_FPROUNDING): Do not use no-vops
+ with -frounding-math.
+ * builtin-attrs.def (ATTR_PURE_NOTHROW_NOVOPS_LIST): Remove.
+ (ATTR_PURE_NOTHROW_NOVOPS_LEAF_LIST): Likewise.
+
+2012-10-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree.h (copy_mem_ref_info): Delete.
+ * tree-ssa-address.c (copy_mem_ref_info): Likewise.
+ (maybe_fold_tmr): Copy flags manually.
+ * tree-ssa-loop-im.c (simple_mem_ref_in_stmt): Rewrite.
+
+2012-10-01 Marc Glisse <marc.glisse@inria.fr>
+
+ * simplify-rtx.c (simplify_binary_operation_1) <VEC_SELECT>:
+ Detect the identity.
+ <VEC_CONCAT>: Handle VEC_SELECTs from the same vector.
+
+2012-10-01 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/50457
+ * config/sh/sh.opt (matomic-model): New option.
+ (msoft-atomic): Mark as deprecated and alias to
+ matomic-model=soft-gusa.
+ (mhard-atomic): Delete.
+ * config/sh/predicates.md (gbr_displacement): New predicate.
+ * config/sh/sh-protos.h (sh_atomic_model): New struct.
+ (selected_atomic_model): New declaration.
+ (TARGET_ATOMIC_ANY, TARGET_ATOMIC_STRICT, TARGET_ATOMIC_SOFT_GUSA,
+ TARGET_ATOMIC_HARD_LLCS, TARGET_ATOMIC_SOFT_TCB,
+ TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX, TARGET_ATOMIC_SOFT_IMASK):
+ New macros.
+ * config/sh/linux.h (SUBTARGET_OVERRIDE_OPTIONS): Adapt setting to
+ default atomic model.
+ * config/sh/sh.c (selected_atomic_model_): New global variable.
+ (selected_atomic_model, parse_validate_atomic_model_option): New
+ functions.
+ (sh_option_override): Replace atomic selection checks with call to
+ parse_validate_atomic_model_option.
+ * config/sh/sh.h (TARGET_ANY_ATOMIC, UNSUPPORTED_ATOMIC_OPTIONS,
+ UNSUPPORTED_HARD_ATOMIC_CPU): Delete.
+ (DRIVER_SELF_SPECS): Remove atomic checks.
+ config/sh/sync.md: Update documentation comments.
+ (atomic_compare_and_swap<mode>, atomic_exchange<mode>,
+ atomic_fetch_<fetchop_name><mode>, atomic_fetch_nand<mode>,
+ atomic_<fetchop_name>_fetch<mode>, atomic_nand_fetch<mode>): Use
+ TARGET_ATOMIC_ANY as condition. Add TARGET_ATOMIC_STRICT check for
+ SH4A case. Handle new TARGET_ATOMIC_SOFT_TCB and
+ TARGET_ATOMIC_SOFT_IMASK cases.
+ (atomic_test_and_set): Handle new TARGET_ATOMIC_SOFT_TCB and
+ TARGET_ATOMIC_SOFT_IMASK cases.
+ (atomic_compare_and_swapsi_hard, atomic_exchangesi_hard,
+ atomic_fetch_<fetchop_name>si_hard, atomic_fetch_nandsi_hard,
+ atomic_<fetchop_name>_fetchsi_hard, atomic_nand_fetchsi_hard):
+ Add TARGET_ATOMIC_STRICT check.
+ (atomic_compare_and_swap<mode>_hard, atomic_exchange<mode>_hard,
+ atomic_fetch_<fetchop_name><mode>_hard, atomic_fetch_nand<mode>_hard,
+ atomic_<fetchop_name>_fetch<mode>_hard, atomic_nand_fetch<mode>_hard,
+ atomic_test_and_set_hard): Use TARGET_ATOMIC_HARD_LLCS condition.
+ (atomic_compare_and_swap<mode>_soft, atomic_exchange<mode>_soft,
+ atomic_fetch_<fetchop_name><mode>_soft, atomic_fetch_nand<mode>_soft,
+ atomic_<fetchop_name>_fetch<mode>_soft, atomic_nand_fetch<mode>_soft,
+ atomic_test_and_set_soft): Append _gusa to the insn names and use
+ TARGET_ATOMIC_SOFT_GUSA as condition.
+ (atomic_compare_and_swap<mode>_soft_tcb,
+ atomic_exchange<mode>_soft_tcb,
+ atomic_fetch_<fetchop_name><mode>_soft_tcb,
+ atomic_fetch_nand<mode>_soft_tcb,
+ atomic_<fetchop_name>_fetch<mode>_soft_tcb,
+ atomic_nand_fetch<mode>_soft_tcb, atomic_test_and_set_soft_tcb):
+ New insns.
+ (atomic_compare_and_swap<mode>_soft_imask,
+ atomic_exchange<mode>_soft_imask,
+ atomic_fetch_<fetchop_name><mode>_soft_imask,
+ atomic_fetch_nand<mode>_soft_imask,
+ atomic_<fetchop_name>_fetch<mode>_soft_imask,
+ atomic_nand_fetch<mode>_soft_imask, atomic_test_and_set_soft_imask):
+ New insns.
+ * doc/invoke.texi (SH Options): Document new matomic-model option.
+ Remove msoft-atomic and mhard-atomic options.
+
+2012-10-01 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ PR target/54746
+ * config/s390/s390.c (s390_option_override): Add missing break.
+
+2012-09-30 Sharad Singhai <singhai@google.com>
+
+ * dumpfile.c: New file with parts moved from tree-dump.c.
+ (pflags): New variable.
+ (alt_flags): Ditto.
+ (alt_dump_file): Ditto.
+ (dump_files): Update to include additional fields.
+ (struct dump_option_value_info): Add additional entries.
+ (get_dump_file_name): Use command line filename if available.
+ (dump_open_alternate_stream): New function.
+ (dump_loc): Ditto.
+ (dump_gimple_stmt): Ditto.
+ (dump_gimple_stmt_loc): Ditto.
+ (dump_generic_expr): Ditto.
+ (dump_generic_expr_loc): Ditto.
+ (dump_printf): Ditto.
+ (dump_printf_loc): Ditto.
+ (dump_start): Ditto.
+ (dump_finish): Ditto.
+ (dump_begin): Ditto.
+ (dump_enabled_p): Return true if either of the dump types is enabled.
+ (dump_initialized_p): Return true if either type of dump is
+ initialized.
+ (dump_end): Do not close standard streams.
+ (dump_enable_all): Handle filenames for regular dumps.
+ (dump_switch_p_1): Handle command-line dump filenames.
+ (opt_info_enable_all): New function.
+ (opt_info_switch_p_1): Ditto.
+ (opt_info_switch_p): Ditto.
+ (dump_kind_p): Ditto.
+ (dump_basic_block): Ditto.
+ (dump_combine_total_stats): Ditto.
+ (dump_remap_tree_vectorizer_verbose): Ditto.
+ * gimple-pretty-print.h: Rename dump_gimple_stmt to
+ pp_gimple_stmt_1. All callers updated.
+
+2012-09-30 Sharad Singhai <singhai@google.com>
+
+ * doc/invoke.texi: Add documentation for the new -fopt-info option.
+ * tree-dump.c: Move general dump file related functionality into
+ dumpfile.c. Remove unneeded headers.
+ * tree-dump.h: Move function declarations into dumpfile.h.
+ * dumpfile.h: Include "line-map.h". Add defines for MSG flags.
+ (struct dump_file_info): Move here from tree-dump.c. Rename flags
+ to pflags, state to pstate, stream to pstream, filename to
+ pfilename. All callers updated. Add alt_flags, alt_state,
+ alt_filenmae, alt_stream.
+ * tree-vectorizer.c: Include "dumpfile.h". Remove vect_dump.
+ (vect_set_dump_settings): Remove.
+ (vect_print_dump_info): Ditto.
+ * tree-vectorizer.h: Remove declaration of vect_dump and
+ vect_print_dump_info.
+ * tree-vect-loop.c: Include "dumpfile.h". Use new dump style.
+ * tree-vect-data-refs.c: Ditto.
+ * tree-vect-stmts.c: Ditto.
+ * tree-vect-slp.c: Ditto.
+ * tree-vect-patterns.c: Ditto.
+ * tree-vect-loop-manip.c: Ditto.
+ * opts.c (vect_set_verbosity_level): Remove.
+ (common_handle_option): Handle -fopt-info flag. Deprecate
+ -ftree-vectorizer-verbose.
+ * tree-parloops.c (gather_scalar_reductions): Remove reference to
+ vect_dump.
+ * flag-types.h: Remove vect_verbosity_levels.
+ * common.opt: Add -fopt-info. Deprecate -ftree-vectorizer-verbose.
+ * opts-global.c (dump_remap_tree_vectorizer_verbose): New function.
+ (handle_common_deferred_options): Handle -fopt-info and
+ -ftree-vectorizer-verbose.
+ * Makefile.in: Add dumpfile.o.
+ (tree-dump.o): Update dependencies.
+ (tree-vect-loop.o): Ditto.
+ (tree-vect-loop-manip.o): Ditto.
+ (tree-vect-slp.o): Ditto.
+ (tree-vect-stmts.o): Ditto.
+ (tree-vectorizer.o): Ditto.
+ (opts.o): Ditto.
+ * passes.c (finish_optimization_passes): Instead of using
+ dump_begin/dump_end, use dump_start/dump_finish. Do not use dump_file.
+ (pass_init_dump_file): Ditto.
+
2012-09-30 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/38449:
@@ -133,7 +855,8 @@
Undo r185605 (mostly):
* config/avr/avr-protos.h (avr_load_lpm): Remove.
- * config/avr/avr.c (avr_load_libgcc_p): Don't restrict to __flash loads.
+ * config/avr/avr.c (avr_load_libgcc_p): Don't restrict to __flash
+ loads.
(avr_out_lpm): Also handle loads > 1 byte.
(avr_load_lpm): Remove.
(avr_find_unused_d_reg): New static function.
@@ -201,8 +924,7 @@
PR target/54703
* simplify-rtx.c (simplify_binary_operation_1): Perform
- (x - (x & y)) -> (x & ~y) optimization only for integral
- modes.
+ (x - (x & y)) -> (x & ~y) optimization only for integral modes.
2012-09-27 Marc Glisse <marc.glisse@inria.fr>
@@ -258,7 +980,8 @@
* target.def (mode_dependent_address_p): Add addr_space_t parameter.
* targhooks.h (default_mode_dependent_address_p): Ditto.
* targhooks.c (default_mode_dependent_address_p): Ditto.
- * expr.c (convert_move): Pass address space to mode_dependent_address_p.
+ * expr.c (convert_move): Pass address space to
+ mode_dependent_address_p.
* combine.c (combine_simplify_rtx): Ditto.
(make_extraction): Ditto.
(simplify_shift_const_1): Ditto.
@@ -361,7 +1084,7 @@
PR target/54641
* config/avr/t-avr: Use ALL_COMPILERFLAGS instead of ALL_CFLAGS
for sources compiled with COMPILER.
-
+
2012-09-25 Richard Guenther <rguenther@suse.de>
PR lto/54625
@@ -375,8 +1098,7 @@
one bit precision properly.
PR other/54692
- * configure.ac (CFLAGS, CXXFLAGS): Remove -Ofast or -Og
- properly.
+ * configure.ac (CFLAGS, CXXFLAGS): Remove -Ofast or -Og properly.
* configure: Regenerated.
2012-09-25 Georg-Johann Lay <avr@gjlay.de>
@@ -398,8 +1120,7 @@
2012-09-24 Dehao Chen <dehao@google.com>
- * tree-cfg.c (move_stmt_op): Reset the expr block only
- when necessary.
+ * tree-cfg.c (move_stmt_op): Reset the expr block only when necessary.
(move_block_to_fn): Reset the edge's goto block even
when the goto locus is unknown.
@@ -506,7 +1227,7 @@
2012-09-24 Janis Johnson <janisjo@codesourcery.com>
- doc/sourcebuild.texi (Selectors): Document the use of target
+ * doc/sourcebuild.texi (Selectors): Document the use of target
and xfail used together.
2012-09-24 Richard Guenther <rguenther@suse.de>
@@ -3515,14 +4236,6 @@
(inline_read_section): Stream in loop_iterations.
(inline_write_summary): Stream out loop_iterations.
-2012-08-20 Florian Weimer <fweimer@redhat.com>
-
- PR c++/19351
- * call.c (build_operator_new_call): Add size_check argument and
- evaluate it.
- * cp-tree.h (build_operator_new_call): Adjust declaration.
- * init.c (build_new_1): Compute array size check and apply it.
-
2012-08-20 Oleg Endo <olegendo@gcc.gnu.org>
PR target/54089
@@ -3811,7 +4524,7 @@
2012-08-17 Nick Clifton <nickc@redhat.com>
- * config/fr30/fr30.md (cbranchsi4): Remove mode from comparison.
+ * config/fr30/fr30.md (cbranchsi4): Remove mode from comparison.
(branch_true): Likewise.
(branch_false): Likewise.
@@ -17435,7 +18148,7 @@
* config/arm/linux-eabi.h (GLIBC_DYNAMIC_LINKER_SOFT_FLOAT): Define.
(GLIBC_DYNAMIC_LINKER_HARD_FLOAT): Define.
(GLIBC_DYNAMIC_LINKER_DEFAULT): Define.
- (GLIBC_DYNAMIC_LINKER): Redefine to use the hard float path.
+ (GLIBC_DYNAMIC_LINKER): Redefine to use the hard float path.
2012-04-25 Sriraman Tallam <tmsriram@google.com>
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 3be6b6d4d..3bda1e32d 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20121001
+20121008
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index b036e884e..77ba4df29 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -888,7 +888,8 @@ CGRAPH_H = cgraph.h $(VEC_H) $(TREE_H) $(BASIC_BLOCK_H) $(FUNCTION_H) \
cif-code.def ipa-ref.h ipa-ref-inline.h $(LINKER_PLUGIN_API_H)
DF_H = df.h $(BITMAP_H) $(REGSET_H) sbitmap.h $(BASIC_BLOCK_H) \
alloc-pool.h $(TIMEVAR_H)
-VALTRACK_H = valtrack.h $(BITMAP_H) $(DF_H) $(RTL_H) $(BASIC_BLOCK_H)
+VALTRACK_H = valtrack.h $(BITMAP_H) $(DF_H) $(RTL_H) $(BASIC_BLOCK_H) \
+ $(HASH_TABLE_H)
RESOURCE_H = resource.h hard-reg-set.h $(DF_H)
DDG_H = ddg.h sbitmap.h $(DF_H)
GCC_H = gcc.h version.h $(DIAGNOSTIC_CORE_H)
@@ -916,7 +917,7 @@ MKDEPS_H = $(srcdir)/../libcpp/include/mkdeps.h
SYMTAB_H = $(srcdir)/../libcpp/include/symtab.h $(OBSTACK_H)
CPP_ID_DATA_H = $(CPPLIB_H) $(srcdir)/../libcpp/include/cpp-id-data.h
CPP_INTERNAL_H = $(srcdir)/../libcpp/internal.h $(CPP_ID_DATA_H)
-TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H)
+TREE_DUMP_H = tree-dump.h $(SPLAY_TREE_H) dumpfile.h
TREE_PASS_H = tree-pass.h $(TIMEVAR_H) dumpfile.h
TREE_FLOW_H = tree-flow.h tree-flow-inline.h tree-ssa-operands.h \
$(BITMAP_H) sbitmap.h $(BASIC_BLOCK_H) $(GIMPLE_H) \
@@ -1193,6 +1194,7 @@ OBJS = \
domwalk.o \
double-int.o \
dse.o \
+ dumpfile.o \
dwarf2asm.o \
dwarf2cfi.o \
dwarf2out.o \
@@ -2182,9 +2184,8 @@ tree.o: tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(TREE_PASS_H) $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) $(CGRAPH_H) \
$(EXCEPT_H) debug.h intl.h tree-diagnostic.h $(TREE_PRETTY_PRINT_H) \
$(COMMON_TARGET_H)
-tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
- $(TREE_H) langhooks.h toplev.h $(SPLAY_TREE_H) $(TREE_DUMP_H) \
- tree-iterator.h $(TREE_PASS_H) $(DIAGNOSTIC_H)
+tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) $(TM_H) $(TREE_H) \
+ langhooks.h $(TREE_DUMP_H) tree-iterator.h
tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) $(RTL_H) $(FLAGS_H) $(PARAMS_H) $(INPUT_H) insn-config.h \
$(HASHTAB_H) langhooks.h $(TREE_INLINE_H) $(CGRAPH_H) \
@@ -2544,12 +2545,12 @@ graphite-optimize-isl.o : graphite-optimize-isl.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h dumpfile.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(SCEV_H) \
sese.h graphite-poly.h
tree-vect-loop.o: tree-vect-loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) \
+ $(TM_H) $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) dumpfile.h \
$(CFGLOOP_H) $(EXPR_H) $(RECOG_H) $(OPTABS_H) \
$(DIAGNOSTIC_CORE_H) $(SCEV_H) $(TREE_VECTORIZER_H) \
$(GIMPLE_PRETTY_PRINT_H) $(TARGET_H) $(TREE_DATA_REF_H)
tree-vect-loop-manip.o: tree-vect-loop-manip.c $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) \
+ coretypes.h dumpfile.h $(TM_H) $(GGC_H) $(TREE_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) $(CFGLOOP_H) $(DIAGNOSTIC_CORE_H) \
$(SCEV_H) $(TREE_VECTORIZER_H) langhooks.h $(GIMPLE_PRETTY_PRINT_H)
tree-vect-patterns.o: tree-vect-patterns.c $(CONFIG_H) $(SYSTEM_H) \
@@ -2558,8 +2559,8 @@ tree-vect-patterns.o: tree-vect-patterns.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_FLOW_H) $(CFGLOOP_H) $(EXPR_H) $(OPTABS_H) $(PARAMS_H) \
$(TREE_DATA_REF_H) $(TREE_VECTORIZER_H) $(RECOG_H) $(DIAGNOSTIC_CORE_H) \
$(GIMPLE_PRETTY_PRINT_H)
-tree-vect-slp.o: tree-vect-slp.c $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) $(BASIC_BLOCK_H) \
+tree-vect-slp.o: tree-vect-slp.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ dumpfile.h $(TM_H) $(GGC_H) $(TREE_H) $(TARGET_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(CFGLOOP_H) \
$(EXPR_H) $(RECOG_H) $(OPTABS_H) $(TREE_VECTORIZER_H) \
$(GIMPLE_PRETTY_PRINT_H) $(TREE_DATA_REF_H) langhooks.h
@@ -2574,7 +2575,7 @@ tree-vect-data-refs.o: tree-vect-data-refs.c $(CONFIG_H) $(SYSTEM_H) \
$(EXPR_H) $(OPTABS_H) $(SCEV_H) $(TREE_VECTORIZER_H) \
$(DIAGNOSTIC_CORE_H) $(TM_P_H) $(GIMPLE_PRETTY_PRINT_H)
tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TM_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \
+ dumpfile.h $(TM_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \
$(CFGLOOP_H) $(TREE_PASS_H) $(TREE_VECTORIZER_H) \
$(TREE_PRETTY_PRINT_H)
tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) \
@@ -2623,7 +2624,7 @@ diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
version.h $(DEMANGLE_H) $(INPUT_H) intl.h $(BACKTRACE_H) $(DIAGNOSTIC_H) \
diagnostic.def
opts.o : opts.c $(OPTS_H) $(OPTIONS_H) $(DIAGNOSTIC_CORE_H) $(CONFIG_H) $(SYSTEM_H) \
- coretypes.h $(TM_H) \
+ coretypes.h dumpfile.h $(TM_H) \
$(DIAGNOSTIC_H) insn-attr-common.h intl.h $(COMMON_TARGET_H) \
$(FLAGS_H) $(PARAMS_H) opts-diagnostic.h
opts-global.o : opts-global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
@@ -2923,6 +2924,8 @@ dce.o : dce.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) $(EXCEPT_H) $(DF_H) cselib.h \
$(DBGCNT_H) dce.h $(VALTRACK_H) $(TREE_PASS_H) $(DBGCNT_H) $(TM_P_H) \
$(EMIT_RTL_H)
+dumpfile.o: dumpfile.c dumpfile.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(DIAGNOSTIC_CORE_H) $(GIMPLE_PRETTY_PRINT_H) $(TREE_H)
dse.o : dse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(TM_P_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \
$(RECOG_H) $(EXPR_H) $(DF_H) cselib.h $(DBGCNT_H) \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 6c8364d5b..1a9ff91cf 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,1292 @@
+2012-10-05 Robert Dewar <dewar@adacore.com>
+
+ * sem_ch7.adb: Minor reformatting.
+
+2012-10-05 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma, case Persistent_BSS): check for
+ a duplicate pragma before Rep_Item_Too_Late to prevent spurious
+ messages about duplicate pragmas.
+
+2012-10-05 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_util.adb (Find_Init_Call): If the successor of the
+ object declaration is a block, check whether it contains the
+ initialization call, because it may have been created by actuals
+ that use the secondary stack.
+
+2012-10-05 Thomas Quinot <quinot@adacore.com>
+
+ * sem_dim.adb, errout.adb, errout.ads (Analyze_Dimension_Call): Add
+ guard against abnormal tree resulting from a previously diagnosed
+ illegality.
+
+2012-10-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * freeze.adb (Freeze_Expression): Rename local variable Cspc to Spec
+ and update all refs to it. Do not freeze an entity outside a subprogram
+ body when the original context is an expression function.
+
+2012-10-05 Robert Dewar <dewar@adacore.com>
+
+ * gnat1drv.adb (Adjust_Global_Switches): Default for overflow checking
+ is suppressed, even if backend overflow/divide checks are enabled.
+
+2012-10-05 Ed Schonberg <schonberg@adacore.com>
+
+ * einfo.adb (Set_Invariant_Procedure, Set_Predicate_Function):
+ chain properly subprograms on Subprograms_For_Type list.
+ * sem_ch13.ads; (Build_Invariant_Procedure_Declaration): new
+ procedure, to create declaration for invariant procedure
+ independently of the construction of the body, so that it can
+ be called within expression functions.
+ * sem_ch13.adb (Build_Invariant_Procedure): code cleanup. The
+ declaration may already have been generated at the point an
+ explicit invariant aspect is encountered.
+ * sem_prag.adb; (Analyze_Pragma, case Invariant): create declaration
+ for invariant procedure.
+ * sem_ch7.adb (Analyze_Package_Specification): clean up call to
+ build invariant procedure.
+ (Preserve_Full_Attributes): propagate information about invariants
+ if they appear on a completion,
+
+2012-10-05 Pascal Obry <obry@adacore.com>
+
+ * gnat_ugn.texi: Update documentation to lift Microsoft C
+ restriction.
+
+2012-10-05 Robert Dewar <dewar@adacore.com>
+
+ * sem_util.adb (Has_One_Matching_Field): Handle case of lone
+ discriminant.
+
+2012-10-05 Yannick Moy <moy@adacore.com>
+
+ * checks.adb (Minimize_Eliminate_Overflow_Checks): Correct code
+ for the division operation and exponent operation. Adjust bound
+ for the mod and rem operations.
+
+2012-10-05 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb, checks.ads, s-tassta.adb, s-stposu.adb, s-spsufi.adb,
+ s-spsufi.ads, exp_ch4.adb: Minor reformatting.
+
+2012-10-05 Yannick Moy <moy@adacore.com>
+
+ * switch-c.adb, checks.adb, checks.ads, sem_prag.adb, exp_ch4.adb,
+ osint.adb: Minor correction of typos, and special case for Alfa mode.
+
+2012-10-05 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * s-spsufi.adb: Add with clause for Ada.Unchecked_Deallocation.
+ Add with and use clauses for System.Finalization_Masters.
+ (Finalize_And_Deallocate): Add an instance of
+ Ada.Unchecked_Deallocation. Merge the code from the now obsolete
+ Finalize_Subpool into this routine.
+ * s-spsufi.ads: Add pragma Preelaborate.
+ * s-stposu.adb: Remove with clause for
+ Ada.Unchecked_Deallocation; Add with and use clauses for
+ System.Storage_Pools.Subpools.Finalization; (Finalize_Pool):
+ Update the comment on all actions takes with respect to a subpool
+ finalization. Finalize and deallocate each individual subpool.
+ (Finalize_Subpool): Removed.
+ (Free): Removed;
+ (Detach): Move from package body to spec.
+ * s-stposu.ads (Detach): Move from package body to spec.
+ (Finalize_Subpool): Removed.
+
+2012-10-05 Arnaud Charlet <charlet@adacore.com>
+
+ * s-tassta.adb: Update comments.
+ (Vulnerable_Complete_Master): If Free_On_Termination is set, do
+ nothing, and let the task free itself if not already done.
+
+2012-10-04 Robert Dewar <dewar@adacore.com>
+
+ * sem_res.adb (Resolve_Set_Membership): Warn on duplicates.
+
+2012-10-04 Emmanuel Briot <briot@adacore.com>
+
+ * g-comlin.adb (Getopt): Fix value of Full_Switch returned in case of
+ invalid switch.
+
+2012-10-04 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Make-lang.in: Update dependencies.
+
+2012-10-04 Robert Dewar <dewar@adacore.com>
+
+ * sem_eval.adb (Fold_Str, Fold_Uint, Fold_Ureal): Reset static
+ expression state after Resolve call.
+
+2012-10-04 Robert Dewar <dewar@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma. case Warnngs): Don't make entry
+ in the table for Warnings Off pragmas if within an instance.
+
+2012-10-04 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch9.adb (Analyze_Entry_Body): Transfer
+ Has_Pragma_Unreferenced flag from entry formal to corresponding
+ entity in body, to prevent spurious warnings when pragma is
+ present.
+
+2012-10-04 Robert Dewar <dewar@adacore.com>
+
+ * s-bignum.adb (Big_Exp): Raise Storage_Error for ludicrously
+ large results.
+
+2012-10-04 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Check_Duplicate_Aspects): Diagnose properly
+ aspects that appear in the partial and the full view of a type.
+
+2012-10-04 Robert Dewar <dewar@adacore.com>
+
+ * sinfo.ads (N_Return_Statement): Removed.
+
+2012-10-04 Tristan Gingold <gingold@adacore.com>
+
+ * init.c (__gl_zero_cost_exceptions): Comment it as not used
+ anymore.
+ * bindgen.adb (Gen_Adainit): Do not emit Zero_Cost_Exceptions
+ anymore.
+
+2012-10-04 Thomas Quinot <quinot@adacore.com>
+
+ * prep.adb, prepcomp.adb, gprep.adb, opt.ads: New preprocessor switch
+ -a (all source text preserved).
+
+2012-10-04 Vincent Celier <celier@adacore.com>
+
+ * prj-proc.adb (Recursive_Process): Use project directory
+ display path name as the value of 'Project_Dir.
+
+2012-10-04 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch4.adb (Expand_Compare_Minimize_Eliminate_Overflow):
+ Deal with case where we get a bignum operand and cannot do a
+ range analysis.
+ * sem_eval.adb (Why_Not_Static): Deal with bignum operands
+
+2012-10-04 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch4.adb (Find_Unary_Types): Within an instance, an
+ interpretation that involves a predefied arithmetic operator is
+ not a candidate if the corresponding generic formal type is not
+ a numeric type.
+ * sem_util.ads, sem_util.adb (Corresonding_Generic_Type): If a
+ type is a generic actual type within an instance, return the
+ corresponding formal in the generic unit, otherwise return
+ Any_Type.
+
+2012-10-04 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Minimize_Eliminate_Overflow_Checks): Dont reanalyze
+ if/case expression if nothing has changed (just reexpand). Stops
+ case expression from generating incorrect temporary.
+ * exp_ch4.adb (Expand_Compare_Minimize_Eliminate_Overflow):
+ Fix cut and paste typo for range analysis in NE (not equal) case.
+ * sem_eval.adb (Compile_Time_Compare): Small optimization to
+ catch some more cases.
+ * types.ads (Suppressed_Or_Checked): New subtype of
+ Overflow_Check_Type.
+
+2012-10-04 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb (Set_CPP_Constructors_Old): Removed.
+ (Set_CPP_Constructors): Code cleanup.
+
+2012-10-04 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch10.adb (Is_Ancestor_Unit): Make global, for use elsewhere.
+ (Install_Private_with_Clauses): if clause is private and limited,
+ do not install the limited view if the library unit is an ancestor
+ of the unit being compiled. This unusual configuration occurs
+ when compiling a unit DDP, when an ancestor P of DDP has a
+ private limited with clause on a descendant of P that is itself
+ an ancestor of DDP.
+
+2012-10-04 Vincent Celier <celier@adacore.com>
+
+ * prj-proc.adb (Process_Package_Declaration): Use project
+ directory display path name as the value of 'Project_Dir.
+
+2012-10-04 Gary Dismukes <dismukes@adacore.com>
+
+ * exp_util.adb (Build_Allocate_Deallocate_Proc): The subpool can be
+ given by an arbitrary name, so copy the tree to make the call's actual.
+
+2012-10-04 Robert Dewar <dewar@adacore.com>
+
+ * s-exnllf.adb, s-exnllf.ads: Minor reformatting.
+
+2012-10-04 Thomas Quinot <quinot@adacore.com>
+
+ * exp_ch6.adb: Minor reformatting.
+
+2012-10-04 Pascal Obry <obry@adacore.com>
+
+ * projects.texi: Use consistently @command{} when referencing
+ commands. Fix typos.
+
+2012-10-03 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (New_Overloaded_Entity): call
+ Append_Inherited_Subprogram when appropriate.
+ * sem_dim.adb (Analyze_Dimension_Call): Do not perform dimensional
+ analysis if call has previous semantic error.
+ * sem_util.ads, sem_util.adb (Append_Inherited_Subprogram):
+ new subprogram to handle properly the visibility of inherited
+ operations that are primitives of a type extension, when the
+ parent type and operations are declared in the same visible part.
+
+2012-10-03 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Minimize_Eliminate_Overflow_Checks): Properly
+ handle case of top level expression within type conversion
+ * gnat1drv.adb (Adjust_Global_Switches): Set SUPPRESSED as
+ default for overflow checking for -gnatg mode (includes run-time).
+ * sem_res.adb (Resolve_Type_Conversion): Avoid bogus warnings
+ about redundant conversions from MINIMIZED/EXTENDED mode checking
+
+2012-10-03 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Allocator_Expression): Minor code
+ reorganization and cleanup. Done to ensure proper management of
+ the C++ constructor covering tagged and untagged types and also
+ non-default constructors.
+ * exp_ch6.ads, exp_ch6.adb (Make_CPP_Constructor_Call_In_Allocator):
+ New subprogram.
+
+2012-10-03 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch6.adb: Minor typo fix.
+
+2012-10-03 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Apply_Arithmetic_Overflow_Minimized_Eliminated):
+ Set Top_Level properly (to False) for operand of range of
+ membership test.
+ * exp_ch4.adb (Expand_Membership_Minimize_Eliminate_Overflow):
+ Fix crash with -gnato3 and membership operations.
+ (Expand_Membership_Minimize_Eliminate_Overflow): Fix error message
+ and wrong results for -gnato3 large expression and predicated
+ subtype.
+ (Expand_Membership_Minimize_Eliminate_Overflow): Use
+ expression action node to avoid using insert actions (bombs in
+ some cases).
+ (Expand_Compare_Minimize_Eliminate_Overflow): Use expression action
+ node to avoid using insert actions (bombs in some cases).
+
+2012-10-03 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb (Set_CPP_Constructors_Old): Handle constructor of
+ untagged type that has all its parameters with defaults and hence it
+ covers the default constructor.
+
+2012-10-03 Yannick Moy <moy@adacore.com>
+
+ * checks.adb, sem_prag.adb, s-bignum.ads: Minor typo fixes.
+
+2012-10-03 Thomas Quinot <quinot@adacore.com>
+
+ * g-socket.adb (Connect_Socket, version with timeout): When the
+ newly-connected socket is reported as available for writing, check
+ whether it has a pending asynchronous error prior to returning.
+
+2012-10-03 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (Check_Conformance): Additional info when subtype
+ conformance fails, due to a missing null exclusion indicatar in
+ a formal that must match a controlling access formal.
+
+2012-10-02 Ben Brosgol <brosgol@adacore.com>
+
+ * gnat_rm.texi: Minor editing.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (Analyze_Function_Return): Reject a return
+ expression whose type is a local access to subprogram type.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * sem_eval.adb: Minor improvement to Compile_Time_Compare.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Apply_Arithmetic_Overflow_Minimized_Eliminated):
+ Fix base type problem that resulted in improper conversion.
+ (Minimize_Eliminate_Overflow_Checks): Properly handle top
+ level case to avoid unnecessary conversion to bignum or LLI.
+ (Minimize_Eliminate_Overflow_Checks): Implement uniform two phase
+ approach for arithmetic operators and for if/case expressions.
+ * checks.ads: Minor comment fix.
+ * exp_ch4.adb (Minimized_Eliminated_Overflow_Check): New function,
+ implements a uniform way of treating minimized/eliminated checks in
+ two phases.
+ (Expand_Compare_Minimize_Eliminate_Overflow): Fix cut and
+ paste error resulting in wrong results for less than in some
+ cases. (Expand_Membership_Minimize_Eliminate_Overflow):
+ Fix error caused by incorrect capture of operand types.
+ (Expand_Membership_Minimize_Eliminate_Overflow): Fix error in
+ handling of bignum case.
+ (Expand_N_Case_Expression): Implement
+ proper two phase handling (Expand_N_If_Expression): Implement
+ proper two phase handling (Expand_N_Op_Abs): Implement proper
+ two phase handling ditto for all other arithmetic operators
+ * sem_res.adb (Resolve_If_Expression): Avoid introducing
+ unneeded conversions.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * s-bignum.adb (Big_Exp): 0**0 should be 1, not 0.
+ (Big_Exp): Fix possible error for (-1)**0.
+ (Big_Exp): Fix error in computing 2**K for small K.
+ (Big_Mod): Fix wrong sign for negative operands.
+ (Div_Rem): Fix bad results for operands close to 2**63.
+ * s-bignum.ads: Add documentation and an assertion to require
+ LLI size to be 64 bits.
+ * sem_prag.adb (Analyze_Pragma, case Overflow_Checks): Do not
+ allow ELIMINATED if LLI'Size is other than 64 bits.
+ * switch-c.adb (Scan_Switches): Do not allow -gnato3 if LLI'Size
+ is not 64 bits.
+ * switch.ads (Bad_Switch): Add missing pragma No_Return.
+ * gnat_ugn.texi: Added appendix on Overflow Check Handling in GNAT.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * sem_type.adb: Minor reformatting.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * sem_ch8.adb: Minor reformatting.
+
+2012-10-02 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb (Set_CPP_Constructors): Handle constructor with default
+ parameters that covers the default constructor.
+
+2012-10-02 Yannick Moy <moy@adacore.com>
+
+ * s-bignum.adb: Minor stylistic and comment corrections.
+
+2012-10-02 Pascal Obry <obry@adacore.com>
+
+ * prj-util.adb (For_Interface_Sources): Iterate over all sources in
+ aggregate library projects.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch8.adb (Find_Direct_Name): The left-hand side of an
+ assignment may designate a generalized reference.
+
+2012-10-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * types.h (N_Return_Statement): Delete.
+ * gcc-interface/trans.c (gnat_to_gnu): Replace N_Return_Statement with
+ N_Simple_Return_Statement.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * freeze.adb (Freeze_Entity): in a generic context, aspects must
+ be analyzed because they may be queried subsequently within the
+ generic unit, even if no other freezing actions are generated
+ for an entity.
+ * sem_ch13.adb (Analyze_Aspects_At_Freeze_Point): iterator
+ aspects must be analyzed because they are delayed aspects and
+ the corresponding attribute definition clause may not have been
+ analyzed yet.
+
+2012-10-02 Yannick Moy <moy@adacore.com>
+
+ * gnat_rm.texi: Minor editing.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * sinfo.adb, sinfo.ads, sem_util.adb, sem_util.ads, types.h,
+ exp_ch4.adb, exp_ch6.adb: Get rid of internal use of N_Return_Statement.
+
+2012-10-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * types.h: Minor cosmetic fix.
+
+2012-10-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interfaces/decl.c (elaborate_expression_1): Use the variable for
+ bounds of loop iteraration scheme only for locally defined subtypes.
+
+ * gcc-interface/trans.c (gigi): Fix formatting.
+ (build_return_expr): Apply the NRV optimization only for BLKmode.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * sinfo.ads: Remove refs of N_Conditional_Expression and
+ N_Parameterized_Expression.
+
+2012-10-02 Thomas Quinot <quinot@adacore.com>
+
+ * exp_aggr.adb (Get_Component_Val): Rewrite code that computes
+ justification of bits in enclosing word in an attempt to make
+ it clearer.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * par_sco.adb, sem_ch3.adb, layout.adb, exp_ch7.adb, exp_imgv.adb,
+ exp_util.adb, exp_util.ads, exp_attr.adb, sinfo.adb, sinfo.ads,
+ exp_ch9.adb, style.ads, scos.ads, debug.adb, einfo.ads, scng.adb,
+ checks.adb, checks.ads, sem.adb, par-ch4.adb, sem_util.adb, types.h,
+ sem_res.adb, expander.adb, scans.ads, par.adb, exp_ch2.adb,
+ gnat1drv.adb, stylesw.ads, sem_elab.adb, exp_ch4.adb, exp_ch4.ads,
+ exp_ch6.adb, sem_ch4.adb, sem_ch4.ads, sem_ch6.adb,
+ opt.ads, sem_eval.adb, sem_eval.ads, exp_intr.adb, sprint.adb,
+ sprint.ads, styleg.ads: Change name Conditional_Expression to
+ If_Expression.
+ * gcc-interface/trans.c (gnat_to_gnu): Replace
+ N_Conditional_Expression by N_If_Expression.
+ * gcc-interface/Make-lang.in: Update dependencies.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Op_Expon): Use expression with actions
+ for x ** 4.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch5.adb: (Analyze_Iterator_Specification): If container
+ has a variable indexing aspect, the element is a variable and
+ is modifiable in the loop. This check is also performed when the
+ loop is expanded, but it must be done in semantic analysis when
+ expansion is disabled, for example for ASIS usage.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * lib-xref.adb (Generate_Reference): If a child subprogram
+ has no previous spec, treat a reference to its formals (such
+ as a parameter association) as coming from source in order to
+ generate the proper references and enable gps navigation between
+ reference and declaration.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Apply_Arithmetic_Overflow_Checked_Suppressed):
+ New name for Apply_Arithmetic_Overflow_Normal
+ (Apply_Arithmetic_Overflow_Minimized_Eliminated):
+ Add handling for conditional expressions
+ (Is_Signed_Integer_Arithmetic_Op): Now includes conditional
+ expressions (Minimize_Eliminate_Overflow_Checks): Handle
+ conditional expressions.
+ * checks.ads: Minor comment fixes.
+ * exp_ch4.adb (Expand_N_Case_Expression): Call
+ Apply_Arithmetic_Overflow_Check (Expand_N_Conditional_Expression):
+ Call Apply_Arithmetic_Overflow_Check
+ * s-bignum.adb (Normalize): Remove incorrect precondition.
+ * sem_res.adb (Resolve_Case_Expression): Set Do_Overflow_Check
+ flag (Resolve_Conditional_Expression): Set Do_Overflow_Check flag.
+ * sinfo.adb: Add Do_Overflow_Check for conditional expressions.
+ * sinfo.ads: Minor documentation updates.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Case_Expression): Do not introduce
+ indirections when the type of the alternatives is an access type:
+ more efficient, and removes anomalies when an alternative is
+ statically null.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * aspects.ads: Minor comment addition (Invariant is a GNAT aspect).
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch7.adb, sem_dim.adb, sem_dim.ads, prj-part.adb, checks.adb,
+ freeze.adb, sem_ch4.adb, sem_ch13.adb: Minor reformatting.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * sem_prag.adb (Analyze_Pragma, case Overflow_Checks): Fix
+ typo preventing proper processing of Overflow_Checks pragmas
+ for general case.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch4.adb (Expand_N_Op_Mod): Fix crash in ELIMINATED overflow
+ checks mode when bignum mode is used.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * stylesw.ads, gnat_ugn.texi: Document new style rule for NOT IN.
+ * par-ch4.adb (P_Relational_Operator): Add style check for NOT IN.
+ * style.ads, styleg.adb, styleg.ads (Check_Not_In): New procedure.
+
+2012-10-02 Vincent Pucci <pucci@adacore.com>
+
+ * sem_attr.adb (Analyze_Attribute): Check dimension for attribute
+ Old before it gets expanded.
+ * sem_dim.adb (Analyze_Dimension_Has_Etype): Correctly propagate
+ dimensions for identifier.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch5.adb (Expand_Iterator_Loop): Handle properly the case
+ where the iterator type is derived locally from an instantiation
+ of Ada.Iterators_Interface.
+ * exp_ch7.adb (Establish_Transient_Scope): Do not create a
+ transient scope if within the expansion of an iterator loop,
+ because a transient block already exists.
+
+2012-10-02 Vincent Celier <celier@adacore.com>
+
+ * gnatcmd.adb: Use absolute path for configuration pragmas files
+ * make.adb (Configuration_Pragmas_Switch.Absolute_Path): Moved
+ to Makeutl.
+ * makeutl.ads, makeutl.adb (Absolute_Path): New function, moved from
+ make.adb.
+
+2012-10-02 Vincent Celier <celier@adacore.com>
+
+ * prj-part.adb (Post_Parse_Context_Clause): Resurrect Boolean
+ parameter In_Limited. Check for circularity also if In_Limited
+ is True.
+ (Parse_Single_Project): Call Post_Parse_Context_Clause with
+ In_Limited parameter.
+
+2012-10-02 Bob Duff <duff@adacore.com>
+
+ * checks.adb (Apply_Predicate_Check): Disable check in -gnatc mode.
+
+2012-10-02 Vincent Pucci <pucci@adacore.com>
+
+ * sem_ch6.adb (Analyze_Function_Call): Dimension propagation
+ for function calls moved to Analyze_Dimension_Call.
+ * sem_dim.adb (Analyze_Dimension_Call): Properly propagate the
+ dimensions from the returned type for function calls.
+
+2012-10-02 Vincent Celier <celier@adacore.com>
+
+ * gnatcmd.adb: Take into account any configuration pragma file
+ in the project files for gnat pretty/stub/metric.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch13.adb (Check_Indexing_Functions): Refine several tests
+ on the legality of indexing aspects: Constant_Indexing functions
+ do not have to return a reference type, and given an indexing
+ aspect Func, not all overloadings of Func in the current scope
+ need to be indexing functions.
+
+2012-10-02 Vasiliy Fofanov <fofanov@adacore.com>
+
+ * gnat_ugn.texi: Adjust docs for overflow checks to be VMS-friendly.
+
+2012-10-02 Vincent Celier <celier@adacore.com>
+
+ * switch-m.adb (Normalize_Compiler_Switches): Recognize switches
+ -gnatox and -gnatoxx when x=0/1/2/3.
+
+2012-10-02 Vincent Pucci <pucci@adacore.com>
+
+ * sem_ch4.adb (Analyze_Indexed_Component_Form): Dimension
+ analysis for indexed components added.
+ * sem_ch6.adb (Analyze_Function_Call): Dimension propagation
+ for function calls added.
+ * sem_dim.adb (Analyze_Dimension): Call to
+ Analyze_Dimension_Has_Etype when N is a function call.
+ (Analyze_Dimension_Call): Don't propagate anymore the dimensions
+ for function calls since this is now treated separately in
+ Analyze_Dimension_Has_Etype.
+ (Analyze_Dimension_Has_Etype): For
+ attribute references, propagate the dimensions from the prefix.
+ * sem_dim.ads (Copy_Dimensions): Fix comment.
+
+2012-10-02 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * checks.ads, checks.adb (Apply_Parameter_Aliasing_Checks): New routine.
+ (Apply_Parameter_Aliasing_And_Validity_Checks): This routine
+ has been split into two.
+ (Apply_Parameter_Validity_Checks): New routine.
+ * exp_ch6.adb (Expand_Call): Add checks to verify that actuals
+ do not overlap. The checks are made on the caller side to overcome
+ issues of parameter passing mechanisms.
+ * freeze.adb (Freeze_Entity): Update call to
+ Apply_Parameter_Aliasing_And_Validity_Checks.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch4.adb (Is_Empty_Range): Use bounds of index type
+ to determine whether an array is empty when optimizing
+ a quantified expression over a null range. Use of RM_Size
+ was incorrect. Analyze condition before constant-folding the
+ expression to catch potential errors. Modify the error message
+ to avoid mathematical terminology.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * usage.adb, gnat_rm.texi, vms_data.ads: Add entry for
+ /OVERFLOW_CHECKS=?? generating -gnato?? for control
+ of extended overflow checking.
+ * ug_words: Add entry for -gnato?? for /OVERFLOW_CHECKS=??
+ * gnat_ugn.texi: Add documentation for -gnato?? for control of overflow
+ checking mode.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch4.adb (Analyze_Quantified_Expression): If the iterator in
+ a quantified expression is statically known to be null (e.g. a
+ array with an empty index type) emit a warning.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * sem_dim.adb: Minor code reorganization.
+ * sem_dim.ads: Add comment.
+
+2012-10-02 Robert Dewar <dewar@adacore.com>
+
+ * checks.ads, exp_ch4.adb, checks.adb
+ (Minimize_Eliminate_Overflow_Checks): Add Top_Level parameter to avoid
+ unnecessary conversions to Bignum.
+ Minor reformatting.
+
+2012-10-02 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch6.adb (Process_PPCs): Generate invariant checks for a
+ return value whose type is an access type and whose designated
+ type has invariants. Ditto for in-out parameters and in-parameters
+ of an access type.
+ * exp_ch3.adb (Build_Component_Invariant_Call): Add invariant check
+ for an access component whose designated type has invariants.
+
+2012-10-01 Vincent Pucci <pucci@adacore.com>
+
+ * sem_aggr.adb (New_Copy_Tree_And_Copy_Dimensions): New routine.
+ (Resolve_Record_Aggregate): New_Copy_Tree calls replaced by
+ New_Copy_Tree_And_Copy_Dimensions calls. Move_Dimensions call
+ replaced by Copy_Dimensions call.
+ * sem_dim.adb (Analyze_Dimension_Component_Declaration): Don't
+ remove the dimensions of expression in component declaration anymore.
+ (Copy_Dimensions): New routine.
+ (Move_Dimensions): Add call to Copy_Dimensions.
+ * sem_dim.ads (Copy_Dimensions): New routine.
+ (Move_Dimensions): Spec moved to body of Sem_Dim.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * checks.adb (Apply_Predicate_Check): If the predicate is a
+ static one and the operand is static, evaluate the predicate at
+ compile time.
+ * sem_eval.ads, sem_eval.adb (Eval_Static_Predicate_Check): new
+ procedure, to evaluate a static predicate check whenever possible.
+ * sem_res.adb (Resolve_Type_Conversion): Apply predicate check
+ on the conversion if the target type has predicates.
+
+2012-10-01 Vincent Pucci <pucci@adacore.com>
+
+ * sem_dim.adb (Has_Symbols): Complain if parameter Symbol has been
+ provided by the user in the dimension output call.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Apply_Divide_Checks): New name for
+ Apply_Divide_Check (Minimize_Eliminate_Overflow_Checks):
+ Add code to handle division (and rem and mod) properly.
+ (Apply_Division_Check): New procedure (Apply_Divide_Checks):
+ Use Apply_Division_Check (Apply_Divide_Checks): Use
+ Apply_Arithmetic_Overflow_Minimized_Eliminated.
+ * checks.ads (Apply_Divide_Checks): New name for
+ Apply_Divide_Check, also add clearer documentation for this
+ routine and put in alfa order.
+ * exp_ch4.adb (Apply_Divide_Checks): New name for
+ Apply_Divide_Check.
+ * s-bignum.adb (To_Bignum): Handle largest negative integer
+ properly.
+ * sem.adb (Analyze): Handle overflow suppression correctly
+ (Analyze_List): Handle overflow suppression correctly
+ * sem_res.adb (Analyze_And_Resolve): Handle overflow suppression
+ correctly.
+
+2012-10-01 Vasiliy Fofanov <fofanov@adacore.com>
+
+ * s-oscons-tmplt.c, g-socket.ads: Revert previous change, breaks VMS.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Minimize_Eliminate_Overflow_Checks): Changes
+ for exponentiation.
+ * exp_ch4.adb (Expand_N_Op_Expon): Changes for Minimize/Eliminate
+ overflow checks.
+ * s-bignum.adb (Compare): Fix bad precondition.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch3.adb (Build_Derived_Record_Type): If the derived
+ type has new discriminantss that constrain inherited ones, use
+ the discriminant type in the original declaration to check for
+ conformance, because in the presence of array components with a
+ smaller range that are constrained by the origina discriminant,
+ the compiler will have created a narrower subtype for that
+ discriminant.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Apply_Arithmetic_Overflow_Minimized_Eliminated):
+ Handle case of appearing in range in membership test.
+ * exp_ch4.adb (Expand_Membership_Minimize_Eliminate_Overflow):
+ New procedure (Expand_N_In): Use
+ Expand_Membership_Minimize_Eliminate_Overflow.
+ * rtsfind.ads: Add RE_Bignum_In_LLI_Range.
+ * s-bignum.ads, s-bignum.adb (Bignum_In_LLI_Range): New function.
+ * sinfo.ads, sinfo.adb (No_Minimize_Eliminate): New flag.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * uintp.ads: Minor reformatting.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * checks.adb: Improve warning message.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb: Minor reformatting.
+
+2012-10-01 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch3.adb (Expand_N_Object_Declaration): Suppress tag
+ assignment for initializations that are aggregates.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * exp_ch4.adb (Expand_Compare_Minimize_Eliminate_Overflow):
+ New procedure.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Minimize_Eliminate_Checks): Changes from testing.
+ (Apply_Arithmetic_Overflow_Minimized_Eliminated): Changes
+ from testing.
+ * sinfo.ads: Remove note on not setting Entity field in overflow
+ case since this is no longer true.
+ * Makefile.rtl: Add s-bignum.o
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * Make-generated.in: Correction to previous change for s-oscons
+ target.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * s-bignum.adb (Allocate_Bignum): Reorganize to kill strict
+ aliasing warning.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb (Overflow_Check_Mode): New function
+ (Apply_Overflow_Check): New procedure (Is_Check_Suppressed):
+ Moved here from Sem, Overflow_Check case now specially treated.
+ * checks.ads (Overflow_Check_Mode): New function
+ (Is_Check_Suppressed): Moved here from Sem (more logical)
+ * exp_ch4.adb (Substitute_Valid_Check): Suppress warning about
+ optimization if we are in MINIMIZED or ELIMINATED overflow
+ checking mode and within an assertiom expression.
+ * rtsfind.ads: Add entries for Bignum stuff.
+ * s-bignum.ads, s-bignum.adb: New files.
+ * sem.ads, sem.adb (Is_Check_Suppressed): Moved to Checks, more logical.
+ * sem_prag.adb (Process_Suppress_Unsuppress): New behavior for
+ Unsuppress of Overflow_Check (sets Checked instead of Minimized)
+ * sem_res.adb: Update comments.
+ * sinfo.ads (N_Op): Add documentation on overflow handling.
+ * tbuild.ads, tbuild.adb (Convert_To_And_Rewrite): New procedure.
+ * types.ads (Minimized_Or_Eliminated): New subtype.
+
+2012-10-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * layout.adb (Layout_Type): Do not set twice the address size
+ on an access-to-unconstrained array if Debug_Flag_6 is set.
+
+2012-10-01 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * sem_ch3.adb (Analyze_Declarations): Remove the specialized
+ code which prevents freezing when the declarative list contains
+ a _postconditions body. This is no longer needed because the
+ body is now inserted at the end of the declarations.
+ * sem_ch6.adb (Insert_After_Last_Declaration): New routine.
+ (Insert_Before_First_Source_Declaration): Removed.
+ (Process_PPCs): Insert the _postconditions body at the end of
+ the declarative list to prevent premature freezing of types that
+ appear in the declarations.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * sem_aggr.adb, sem_dim.adb: Minor reformatting.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_prag.adb (Process_Convention, Process_Import_Or_Interface):
+ Adjust test so that when the pragma comes from an aspect
+ specification it only applies to the entity in the original
+ declaration.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * gnat_ugn.texi: Document new command line switch -fada-spec-parent.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * s-oscons-tmplt.c, g-socket.ads: Minor code improvement: use gcc
+ builtin __alignof__ to get the alignment of struct fd_set.
+
+2012-10-01 Vincent Pucci <pucci@adacore.com>
+
+ * exp_ch6.adb (Expand_Call): Remove call to
+ Remove_Dimension_In_Call.
+ * sem_aggr.adb (Resolve_Array_Aggregate): Analyze dimension of
+ components in array aggregate.
+ (Resolve_Aggr_Expr): Propagate dimensions from the original expression
+ Expr to the new created expression New_Expr when resolving the
+ expression of a component in record aggregates.
+ (Resolve_Record_Aggregate): Analyze
+ dimension of components in record (or extension) aggregate.
+ * sem_ch6.adb (Analyze_Subprogram_Specification): Analyze
+ dimension of formals with default expressions in subprogram
+ specification.
+ * sem_ch8.adb (Analyze_Expanded_Name): Analyze dimension of
+ expanded names.
+ (Find_Selected_Component): Analyze dimension of selected component.
+ * sem_dim.adb: Several dimension error messages reformatting.
+ (Dimensions_Msg_Of): New flag Description_Needed in order to
+ differentiate two different sort of dimension error messages.
+ (Dim_Warning_For_Numeric_Literal): New routine.
+ (Exists): New routine.
+ (Move_Dimensions): Routine spec moved to spec file.
+ * sem_dim.ads (String_From_Numeric_Literal): New routine.
+ (Analyze_Dimension): Analyze dimension only when the
+ node comes from source. Dimension analysis for expanded names added.
+ (Analyze_Dimension_Array_Aggregate): New routine.
+ (Analyze_Dimension_Call): New routine.
+ (Analyze_Dimension_Component_Declaration): Warning if default
+ expression is a numeric literal.
+ (Analyze_Dimension_Extension_Or_Record_Aggregate): New routine.
+ (Analyze_Dimension_Formals): New routine.
+ (Analyze_Dimension_Object_Declaration): Warning if default
+ expression is a numeric literal.
+ (Symbol_Of): Return either the dimension subtype symbol or the
+ dimension symbol built by From_Dim_To_Str_Of_Unit_Symbols.
+ * sem_dim.ads (Analyze_Dimension_Array_Aggregate): New routine.
+ (Analyze_Dimension_Call): New routine.
+ (Analyze_Dimension_Extension_Or_Record_Aggregate): New routine.
+ (Analyze_Dimension_Formals): New routine.
+ (Move_Dimensions): Moved from sem_dim.adb.
+ * s-dimmks.ads: Turn off the warnings for dimensioned object
+ declaration. Dimensioned subtypes sorted in alphabetical
+ order. New subtypes Area, Speed, Volume.
+ * s-dmotpr.ads: Turn off the warnings for dimensioned object
+ declaration.
+ * sem_res.adb (Resolve_Call): Analyze dimension for calls.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * Make-generated.in: Minor cleanup of all targets: use
+ MOVE_IF_CHANGE to put generated files in place, to avoid useless
+ recompilations.
+
+2012-10-01 Javier Miranda <miranda@adacore.com>
+
+ * exp_disp.adb (Expand_Dispatching_Call): For functions returning
+ interface types add an implicit conversion to the returned object
+ to force the displacement of the pointer to the returned object
+ to reference the corresponding secondary dispatch table. This
+ is needed to handle well combined calls involving secondary
+ dispatch tables (for example Obj.Prim1.Prim2).
+ * exp_ch4.adb (Expand_Allocator_Expression): Declare internal
+ access type as access to constant or access to variable depending
+ on the context. Found working in this ticket.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * checks.adb (Apply_Predicate_Check): Do not apply check to
+ actual of predicate checking procedure, to prevent infinite
+ recursion.
+
+2012-10-01 Arnaud Charlet <charlet@adacore.com>
+
+ * gcc-interface/Make-lang.in: Update dependencies.
+ (GCC_LINK): Add -static-libstdc++.
+
+2012-10-01 Arnaud Charlet <charlet@adacore.com>
+
+ * a-catizo.adb, a-stwiun.adb, a-cdlili.adb, a-cihama.adb, a-direct.adb,
+ a-coinve.adb, a-calend.adb, a-ciorse.adb, a-coorma.adb, a-cfdlli.adb,
+ a-stzunb-shared.adb, a-cfhase.adb, bindgen.adb, ceinfo.adb, a-tags.adb,
+ einfo.adb, checks.adb, eval_fat.adb, a-cborma.adb, a-stwifi.adb,
+ a-tifiio.adb, a-textio.adb, a-cidlli.adb, a-strunb-shared.adb,
+ a-cimutr.adb, a-calcon.adb, a-exexpr-gcc.adb, a-ciormu.adb,
+ a-stzunb.adb, a-stzsea.adb, a-ngelfu.adb, a-stzfix.adb,
+ a-cihase.adb, a-cohama.adb, a-exetim-posix.adb, a-dirval-vms.adb,
+ a-caldel-vms.adb, a-coorse.adb, errout.adb,
+ a-except.adb, butil.adb, a-dirval-mingw.adb, a-cforma.adb,
+ a-except-2005.adb, a-wtedit.adb, cstand.adb, a-stwiun-shared.adb,
+ a-cbhama.adb, a-direio.adb, clean.adb, a-cborse.adb, back_end.adb,
+ binde.adb, a-exexda.adb, a-comutr.adb, a-ciorma.adb, a-cobove.adb,
+ a-coormu.adb, a-teioed.adb, a-convec.adb, a-wtenau.adb, exp_aggr.adb,
+ a-ztedit.adb, a-cohase.adb, a-exetim-mingw.adb, bcheck.adb,
+ a-dynpri.adb, a-cfhama.adb, a-calfor.adb, a-cbdlli.adb,
+ a-crdlli.adb, a-cbmutr.adb, a-sequio.adb, a-ngcoar.adb, a-cforse.adb,
+ a-strunb.adb, a-calend-vms.adb, a-clrefi.adb, a-cofove.adb,
+ a-ztenau.adb, a-strfix.adb, a-cbhase.adb, a-stzsup.adb: Minor
+ reformatting.
+
+2012-10-01 Vincent Pucci <pucci@adacore.com>
+
+ * s-gearop.adb (Vector_Matrix_Product): Dimensions check fixed. Index
+ of Left in S evaluation fixed.
+
+2012-10-01 Javier Miranda <miranda@adacore.com>
+
+ * sem_ch3.adb (Analyze_Declarations): Avoid
+ premature freezing caused by the internally generated subprogram
+ _postconditions.
+ * checks.adb (Expr_Known_Valid): Float literals are assumed to be valid
+ in VM targets.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * sinput.ads, sinput.adb, sinput-l.adb sinput-c.adb (Sinput): New
+ Instances table, tracking all generic instantiations. Source file
+ attribute Instance replaces previous Instantiation attribute with an
+ index into the Instances table.
+ (Iterate_On_Instances): New generic procedure.
+ (Create_Instantiation_Source): Record instantiations in Instances.
+ (Tree_Read, Tree_Write): Read/write the instance table.
+ * scils.ads, scos.adb (SCO_Instance_Table): New table, contains
+ information copied from Sinput.Instance_Table, but self-contained
+ within the SCO data structures.
+ * par_sco.ads, par_sco.adb (To_Source_Location): Move to library level.
+ (Record_Instance): New subprogram, used by...
+ (Populate_SCO_Instance_Table): New subprogram to fill
+ the SCO instance table from the Sinput one (called by SCO_Output).
+ * opt.ads (Generate_SCO_Instance_Table): New option.
+ * put_scos.adb (Write_Instance_Table): New subprogram, used by...
+ (Put_SCOs): Dump the instance table at the end of SCO information
+ if requested.
+ * get_scos.adb (Get_SCOs): Read SCO_Instance_Table.
+ * types.h: Add declaration for Instance_Id.
+ * back_end.adb (Call_Back_End): Pass instance ids in source file
+ information table.
+ (Scan_Back_End_Switches): -fdebug-instances sets
+ Opt.Generate_SCO_Instance_Table.
+ * gcc-interface/gigi.h: File_Info_Type includes instance id.
+ * gcc-interface/trans.c: Under -fdebug-instances, set instance
+ id in line map from same in file info.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * sem_elab.adb: Minor reformatting
+ (Check_Elab_Call): Minor fix to debugging code
+ (add special circuit for the valid case where a 'Access attribute
+ reference is passed to Check_Elab_Call).
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * exp_ch3.adb: Minor reformatting.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch3.ads (Build_Array_Invariant_Proc): moved to body.
+ * exp_ch3.adb (Build_Array_Invariant_Proc,
+ Build_Record_Invariant_Proc): transform into functions.
+ (Insert_Component_Invariant_Checks): for composite types that have
+ components with specified invariants, build a checking procedure,
+ and make into the invariant procedure of the composite type,
+ or incorporate it into the user- defined invariant procedure if
+ one has been created.
+ * sem_ch3.adb (Array_Type_Declaration): Checking for invariants
+ on the component type is defered to the expander.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * xsnamest.adb, namet.h, sem_ch10.adb, s-oscons-tmplt.c,
+ xoscons.adb: Minor reformatting.
+
+2012-10-01 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * checks.adb (Apply_Parameter_Aliasing_And_Validity_Checks):
+ Do not process subprogram renaminds because a) those cannot
+ have PPC pragmas b) the renamed entity already has the PPCs.
+ (Build_PPC_Pragma): Prepend a PPC pragma for consistency with
+ Process_PPCs.
+ * sem_ch6.adb (Last_Implicit_Declaration): Removed.
+ (Process_PPCs): Insert a post condition body at the start of the
+ declarative region of the related subprogram. This way the body
+ will not freeze anything it shouldn't.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * freeze.adb, sem_ch6.adb, opt.ads, sem_ch13.adb,
+ exp_ch3.adb: Minor reformatting.
+
+2012-10-01 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * checks.adb (Build_PPC_Pragma): A PPC pragma can now be properly
+ associated with a subprogram body.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * aspects.ads: Type_Invariant'class is a valid aspect.
+ * sem_ch6.adb (Is_Public_Subprogram_For): with the exception of
+ initialization procedures, subprograms that do not come from
+ source are not public for the purpose of invariant checking.
+ * sem_ch13.adb (Build_Invariant_Procedure): Handle properly the
+ case of a non-private type in a package without a private part,
+ when the type inherits invariants from its ancestor.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch3.adb (Build_Record_Invariant_Proc): new procedure to
+ generate a checking procedure for record types that may have
+ components whose types have type invariants declared.
+
+2012-10-01 Vincent Pucci <pucci@adacore.com>
+
+ * system-solaris-sparcv9.ads, system-mingw.ads, system-vms_64.ads: Flag
+ Support_Atomic_Primitives set to True.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * impunit.adb: Ada.Locales is a language defined unit.
+
+2012-10-01 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * checks.adb (Apply_Parameter_Aliasing_Checks): Removed.
+ (Apply_Parameter_Aliasing_And_Validity_Checks): New routine.
+ (Apply_Parameter_Validity_Checks): Removed.
+ * checks.ads (Apply_Parameter_Aliasing_Checks): Removed.
+ (Apply_Parameter_Aliasing_And_Validity_Checks): New routine.
+ (Apply_Parameter_Validity_Checks): Removed.
+ * exp_ch6.adb (Expand_Call): Remove the generation of parameter
+ aliasing checks.
+ * freeze.adb: Remove with and use clauses for Validsw.
+ (Freeze_Entity): Update the guard and generation of aliasing
+ and scalar initialization checks for subprogram parameters.
+ * opt.ads: Add new flags Check_Aliasing_Of_Parameters and
+ Check_Validity_Of_Parameters along with comments on usage.
+ * sem_attr.adb (Analyze_Attribute): Pragma Overlaps_Storage is
+ no longer an Ada 2012 feature.
+ * sem_ch4.adb: Remove with and use clauses for Checks and Validsw.
+ (Analyze_Call): Remove the generation of aliasing checks for
+ subprogram parameters.
+ * sem_ch13.adb: Remove with and use clauses for Validsw.
+ (Analyze_Aspect_Specifications): Remove the generation of scalar
+ initialization checks.
+ * switch-c.adb (Scan_Front_End_Switches): Add processing for
+ -gnateA and -gnateV.
+ * usage.adb (Usage): Add information on switches -gnateA and
+ -gnateV. Remove information on validity switches 'l', 'L',
+ 'v' and 'V'.
+ * validsw.adb (Reset_Validity_Check_Options): Remove the
+ reset of flags Validity_Check_Non_Overlapping_Params
+ and Validity_Check_Valid_Scalars_On_Params.
+ (Save_Validity_Check_Options): Remove the processing
+ for flags Validity_Check_Non_Overlapping_Params
+ and Validity_Check_Valid_Scalars_On_Params.
+ (Set_Validity_Check_Options): Remove the processing
+ for flags Validity_Check_Non_Overlapping_Params and
+ Validity_Check_Valid_Scalars_On_Params.
+ * validsw.ads: Remove flags Validity_Check_Non_Overlapping_Params
+ and Validity_Check_Valid_Scalars_On_Params along with their
+ comments on usage.
+
+2012-10-01 Yannick Moy <moy@adacore.com>
+
+ * sem_ch13.adb (Add_Invariants): Analyze the invariant expression
+ as an assertion expression.
+ * sem_ch3.adb / sem_ch3.ads (Preanalyze_Assert_Expression):
+ New procedure that wraps a call to Preanalyze_Spec_Expression
+ for assertion expressions, so that In_Assertion_Expr can be
+ properly adjusted.
+ * sem_prag.adb (Analyze_PPC_In_Decl_Part
+ Check_Precondition_Postcondition Preanalyze_CTC_Args): Call the
+ new Preanalyze_Assert_Expression.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.ads: Minor reformatting.
+
+2012-10-01 Yannick Moy <moy@adacore.com>
+
+ * types.ads, sem_prag.adb, sem.ads: Correct minor typos in comments.
+
+2012-10-01 Vincent Celier <celier@adacore.com>
+
+ * make.adb (Scan_Make_Arg): Only test for "vP" of the option
+ includes at least 3 characters.
+ * gnatcmd.adb (GNATCmd): Ditto.
+
+2012-10-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_ch7.adb, sinfo.ads: Add comments.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb: Remove reference to Enable_Overflow_Checks Use
+ Suppress_Options rather than Scope_Suppress.
+ * gnat1drv.adb (Adjust_Global_Switches): Handle new overflow
+ settings (Adjust_Global_Switches): Initialize Scope_Suppress
+ from Suppress_Options.
+ * opt.adb: Remove Enable_Overflow_Checks (use Suppress_Options
+ instead).
+ * opt.ads: Remove Overflow_Checks_Unsuppressed (not used)
+ Remove Enable_Overflow_Checks (use Suppress_Options instead)
+ Suppress_Options is now current setting (replaces Scope_Suppress).
+ * osint.adb (Initialize): Deal with initializing overflow
+ checking.
+ * par-prag.adb: Add dummy entry for pragma Overflow_Checks.
+ * sem.adb (Semantics): Save and restore In_Assertion_Expr Use
+ Suppress_Options instead of Scope_Suppress.
+ * sem.ads (In_Assertion_Expr): New flag (Scope_Suppress):
+ Removed, use Suppress_Options instead.
+ * sem_eval.adb (Compile_Time_Compare): Return Unknown in
+ preanalysis mode.
+ * sem_prag.adb (Process_Suppress_Unsuppress): Setting of
+ Overflow_Checks_Unsuppressed removed (not used anywhere!)
+ (Analyze_Pragma, case Check): Set In_Assertion_Expression
+ (Analyze_Pragma, case Overflow_Checks): Implement new pragma
+ * snames.ads-tmpl: Add names needed for handling pragma
+ Overflow_Checks
+ * switch-c.adb (Scan_Front_End_Switches) Handle -gnato? and
+ -gnato?? where ? is 0-3
+ * types.ads: Updates and fixes to comment on Suppress_Record.
+
+2012-10-01 Vincent Celier <celier@adacore.com>
+
+ * prj-part.adb (Parse): Remove incorrect comment about checking
+ imported non extending projects from and "extending all"
+ one. Minor correction.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * make.adb, exp_ch3.adb: Minor reformatting.
+
+2012-10-01 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * validsw.adb (Save_Validity_Check_Options): Do not set
+ Validity_Check_Non_Overlapping_Params and
+ Validity_Check_Valid_Scalars_On_Params when -gnatVa is present
+ because the related checks are deemed too aggressive.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_util.ads sem_util.adb (Check_Internal_Protected_Use):
+ reject use of protected procedure or entry within the body of
+ a protected function of the same protected type, when usage is
+ a call, an actual in an instantiation, a or prefix of 'Access.
+ * sem_ch8.adb (Analyze_Subprogram_Renaming): Verify that target
+ object in renaming of protected procedure is a variable, and
+ apply Check_Internal_Protected_Use.
+ * sem_res.adb (Analyze_Call, Analyze_Entry_Call): apply
+ Check_Internal_Protected_Use rather than on-line code.
+ * sem_attr.adb (Analyze_Access_Attribute): Verify that target
+ object in accsss to protected procedure is a variable, and apply
+ Check_Internal_Protected_Use.
+
+2012-10-01 Gary Dismukes <dismukes@adacore.com>
+
+ * sem_ch4.adb (Find_Equality_Types.Try_One_Interp): Exclude the
+ predefined interpretation from consideration if it's for a "/="
+ operator of a tagged type. This will allow Analyze_Equality_Op to
+ rewrite the "/=" as a logical negation of a call to the appropriate
+ dispatching equality function. This needs to be done during
+ analysis rather than expansion for the benefit of ASIS, which
+ otherwise gets the unresolved N_Op_Ne operator from Standard.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * gnatcmd.adb, make.adb (Scan_Make_Arg, Inspect_Switches): Recognize
+ and reject an invalid parameter passed to -vP.
+
+2012-10-01 Yannick Moy <moy@adacore.com>
+
+ * sem_warn.adb (Check_Infinite_Loop_Warning/Test_Ref): Improve
+ the detection of modifications to the loop variable by noting
+ that, if the type of variable is elementary and the condition
+ does not contain a function call, then the condition cannot be
+ modified by side-effects from a procedure call.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * checks.adb: Add comments.
+
+2012-10-01 Javier Miranda <miranda@adacore.com>
+
+ * exp_ch3.adb (Expand_N_Object_Declaration): Improve condition catching
+ never-ending recursion. The previous condition erroneously disabled
+ silently the expansion of the class-wide interface object
+ initialization in cases not involving the recursion.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * make.adb: Minor documentation fix: error messages are sent to
+ stderr, not stdout.
+
+2012-10-01 Hristian Kirtchev <kirtchev@adacore.com>
+
+ * checks.ads, checks.adb (Apply_Parameter_Aliasing_Checks): New routine.
+ (Apply_Parameter_Validity_Checks): New routines.
+ * exp_ch6.adb (Expand_Call): Add aliasing checks to detect
+ overlapping objects.
+ * freeze.adb: Add with and use clauses for Checks and Validsw.
+ (Freeze_Entity): Add checks to detect proper initialization
+ of scalars.
+ * sem_ch4.adb: Add with and use clauses for Checks and Validsw.
+ (Analyze_Call): Add aliasing checks to detect overlapping objects.
+ * sem_ch13.adb: Add with and use clauses for Validsw.
+ (Analyze_Aspect_Specifications): Add checks to detect proper
+ initialization of scalars.
+ * sem_prag.adb (Chain_PPC): Correct the extraction of the
+ subprogram name.
+ * sem_util.adb (Is_Object_Reference): Attribute 'Result now
+ produces an object.
+ * usage.adb (Usage): Add usage lines for validity switches 'l',
+ 'L', 'v' and 'V'.
+ * validsw.adb (Reset_Validity_Check_Options): Include
+ processing for flags Validity_Check_Non_Overlapping_Params and
+ Validity_Check_Valid_Scalars_On_Params. Code reformatting.
+ (Save_Validity_Check_Options): Include processing
+ for flags Validity_Check_Non_Overlapping_Params
+ and Validity_Check_Valid_Scalars_On_Params.
+ (Set_Validity_Check_Options): Add processing for validity switches
+ 'a', 'l', 'L', 'n', 'v' and 'V'. Code reformatting.
+ * validsw.ads: Add new flags Validity_Check_Non_Overlapping_Params
+ and Validity_Check_Valid_Scalars_On_Params along with comments
+ on usage.
+
+2012-10-01 Thomas Quinot <quinot@adacore.com>
+
+ * namet.ads, xsnamest.adb, prj-env.adb, sem_warn.adb,
+ errout.ads: Minor reformatting.
+ * prj-part.adb: Add comment.
+
+2012-10-01 Robert Dewar <dewar@adacore.com>
+
+ * sinfo.ads, exp_aggr.adb, sem_ch13.adb: Minor reformatting.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_aggr.adb (Resolve_Array_Aggregate): Handle properly
+ component associations given by subtypes that have static
+ predicates. Improve error message for overlapping ranges in
+ array aggregates.
+
+2012-10-01 Pascal Obry <obry@adacore.com>
+
+ * snames.ads-tmpl (Name_Link_Lib_Subdir): New constant.
+
+2012-10-01 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_ch9.adb (Analyze_Requeue): The target of a requeue
+ statement on a protected entry must be a variable. This is part
+ of AI05-0225.
+
2012-09-26 Ian Lance Taylor <iant@google.com>
* gcc-interface/Makefile.in (LIBBACKTRACE): New variable.
diff --git a/gcc/ada/Make-generated.in b/gcc/ada/Make-generated.in
index 833d47f25..00278df25 100644
--- a/gcc/ada/Make-generated.in
+++ b/gcc/ada/Make-generated.in
@@ -18,6 +18,7 @@ ifeq ($(origin MOVE_IF_CHANGE), undefined)
MOVE_IF_CHANGE=mv -f
endif
+.PHONY: ada_extra_files
ada_extra_files : $(ADA_GEN_SUBDIR)/treeprs.ads $(ADA_GEN_SUBDIR)/einfo.h $(ADA_GEN_SUBDIR)/sinfo.h $(ADA_GEN_SUBDIR)/nmake.adb \
$(ADA_GEN_SUBDIR)/nmake.ads $(ADA_GEN_SUBDIR)/snames.ads $(ADA_GEN_SUBDIR)/snames.adb $(ADA_GEN_SUBDIR)/snames.h
@@ -27,19 +28,22 @@ $(ADA_GEN_SUBDIR)/treeprs.ads : $(ADA_GEN_SUBDIR)/treeprs.adt $(ADA_GEN_SUBDIR)/
-$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/treeprs
$(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/treeprs/,$(notdir $^))
$(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/treeprs
- (cd $(ADA_GEN_SUBDIR)/bldtools/treeprs; gnatmake -q xtreeprs ; ./xtreeprs ../../treeprs.ads )
+ (cd $(ADA_GEN_SUBDIR)/bldtools/treeprs; gnatmake -q xtreeprs ; ./xtreeprs treeprs.ads )
+ $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/treeprs/treeprs.ads $(ADA_GEN_SUBDIR)/treeprs.ads
$(ADA_GEN_SUBDIR)/einfo.h : $(ADA_GEN_SUBDIR)/einfo.ads $(ADA_GEN_SUBDIR)/einfo.adb $(ADA_GEN_SUBDIR)/xeinfo.adb $(ADA_GEN_SUBDIR)/ceinfo.adb
-$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/einfo
$(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/einfo/,$(notdir $^))
$(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/einfo
- (cd $(ADA_GEN_SUBDIR)/bldtools/einfo; gnatmake -q xeinfo ; ./xeinfo ../../einfo.h )
+ (cd $(ADA_GEN_SUBDIR)/bldtools/einfo; gnatmake -q xeinfo ; ./xeinfo einfo.h )
+ $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/einfo/einfo.h $(ADA_GEN_SUBDIR)/einfo.h
$(ADA_GEN_SUBDIR)/sinfo.h : $(ADA_GEN_SUBDIR)/sinfo.ads $(ADA_GEN_SUBDIR)/sinfo.adb $(ADA_GEN_SUBDIR)/xsinfo.adb $(ADA_GEN_SUBDIR)/csinfo.adb
-$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/sinfo
$(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/sinfo/,$(notdir $^))
$(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/sinfo
- (cd $(ADA_GEN_SUBDIR)/bldtools/sinfo; gnatmake -q xsinfo ; ./xsinfo ../../sinfo.h )
+ (cd $(ADA_GEN_SUBDIR)/bldtools/sinfo; gnatmake -q xsinfo ; ./xsinfo sinfo.h )
+ $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/sinfo/sinfo.h $(ADA_GEN_SUBDIR)/sinfo.h
$(ADA_GEN_SUBDIR)/snames.h $(ADA_GEN_SUBDIR)/snames.ads $(ADA_GEN_SUBDIR)/snames.adb : $(ADA_GEN_SUBDIR)/stamp-snames ; @true
$(ADA_GEN_SUBDIR)/stamp-snames : $(ADA_GEN_SUBDIR)/snames.ads-tmpl $(ADA_GEN_SUBDIR)/snames.adb-tmpl $(ADA_GEN_SUBDIR)/snames.h-tmpl $(ADA_GEN_SUBDIR)/xsnamest.adb $(ADA_GEN_SUBDIR)/xutil.ads $(ADA_GEN_SUBDIR)/xutil.adb
@@ -52,17 +56,46 @@ $(ADA_GEN_SUBDIR)/stamp-snames : $(ADA_GEN_SUBDIR)/snames.ads-tmpl $(ADA_GEN_SUB
$(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/snamest/snames.nh $(ADA_GEN_SUBDIR)/snames.h
touch $(ADA_GEN_SUBDIR)/stamp-snames
-$(ADA_GEN_SUBDIR)/nmake.adb : $(ADA_GEN_SUBDIR)/sinfo.ads $(ADA_GEN_SUBDIR)/nmake.adt $(ADA_GEN_SUBDIR)/xnmake.adb $(ADA_GEN_SUBDIR)/xutil.ads $(ADA_GEN_SUBDIR)/xutil.adb
- -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/nmake_b
- $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/nmake_b/,$(notdir $^))
- $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/nmake_b
- (cd $(ADA_GEN_SUBDIR)/bldtools/nmake_b; gnatmake -q xnmake ; ./xnmake -b ../../nmake.adb )
-
-$(ADA_GEN_SUBDIR)/nmake.ads : $(ADA_GEN_SUBDIR)/sinfo.ads $(ADA_GEN_SUBDIR)/nmake.adt $(ADA_GEN_SUBDIR)/xnmake.adb $(ADA_GEN_SUBDIR)/nmake.adb $(ADA_GEN_SUBDIR)/xutil.ads $(ADA_GEN_SUBDIR)/xutil.adb
- -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/nmake_s
- $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/nmake_s/,$(notdir $^))
- $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/nmake_s
- (cd $(ADA_GEN_SUBDIR)/bldtools/nmake_s; gnatmake -q xnmake ; ./xnmake -s ../../nmake.ads )
+$(ADA_GEN_SUBDIR)/nmake.adb $(ADA_GEN_SUBDIR)/nmake.ads: $(ADA_GEN_SUBDIR)/stamp-nmake ; @true
+$(ADA_GEN_SUBDIR)/stamp-nmake: $(ADA_GEN_SUBDIR)/sinfo.ads $(ADA_GEN_SUBDIR)/nmake.adt $(ADA_GEN_SUBDIR)/xnmake.adb $(ADA_GEN_SUBDIR)/xutil.ads $(ADA_GEN_SUBDIR)/xutil.adb
+ -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/nmake
+ $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/nmake/,$(notdir $^))
+ $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/nmake
+ (cd $(ADA_GEN_SUBDIR)/bldtools/nmake; gnatmake -q xnmake ; ./xnmake -b nmake.adb ; ./xnmake -s nmake.ads)
+ $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/nmake/nmake.ads $(ADA_GEN_SUBDIR)/nmake.ads
+ $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/nmake/nmake.adb $(ADA_GEN_SUBDIR)/nmake.adb
+ touch $(ADA_GEN_SUBDIR)/stamp-nmake
+
+ifeq ($(strip $(filter-out alpha64 ia64 dec hp vms% openvms% alphavms%,$(subst -, ,$(host)))),)
+OSCONS_CPP=../../../$(DECC) -E /comment=as_is -DNATIVE \
+ -DTARGET='""$(target)""' s-oscons-tmplt.c
+
+OSCONS_EXTRACT=../../../$(DECC) -DNATIVE \
+ -DTARGET='""$(target)""' s-oscons-tmplt.c ; \
+ ld -o s-oscons-tmplt.exe s-oscons-tmplt.obj; \
+ ./s-oscons-tmplt.exe > s-oscons-tmplt.s
+
+else
+# GCC_FOR_TARGET has paths relative to the gcc directory, so we need to adjust
+# for running it from $(ADA_GEN_SUBDIR)/bldtools/oscons
+OSCONS_CC=`echo "$(GCC_FOR_TARGET)" \
+ | sed -e 's^\./xgcc^../../../xgcc^' -e 's^-B./^-B../../../^'`
+OSCONS_CPP=$(OSCONS_CC) $(GNATLIBCFLAGS) -E -C \
+ -DTARGET=\"$(target)\" s-oscons-tmplt.c > s-oscons-tmplt.i
+OSCONS_EXTRACT=$(OSCONS_CC) -S s-oscons-tmplt.i
+endif
+
+$(ADA_GEN_SUBDIR)/s-oscons.ads : $(ADA_GEN_SUBDIR)/s-oscons-tmplt.c $(ADA_GEN_SUBDIR)/gsocket.h $(ADA_GEN_SUBDIR)/xoscons.adb $(ADA_GEN_SUBDIR)/xutil.ads $(ADA_GEN_SUBDIR)/xutil.adb
+ -$(MKDIR) $(ADA_GEN_SUBDIR)/bldtools/oscons
+ $(RM) $(addprefix $(ADA_GEN_SUBDIR)/bldtools/oscons/,$(notdir $^))
+ $(CP) $^ $(ADA_GEN_SUBDIR)/bldtools/oscons
+ (cd $(ADA_GEN_SUBDIR)/bldtools/oscons ; gnatmake -q xoscons ; \
+ $(RM) s-oscons-tmplt.i s-oscons-tmplt.s ; \
+ $(OSCONS_CPP) ; \
+ $(OSCONS_EXTRACT) ; \
+ ./xoscons ) ; \
+ $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/oscons/s-oscons.ads $(ADA_GEN_SUBDIR)/s-oscons.ads ; \
+ $(MOVE_IF_CHANGE) $(ADA_GEN_SUBDIR)/bldtools/oscons/s-oscons.h $(ADA_GEN_SUBDIR)/s-oscons.h
$(ADA_GEN_SUBDIR)/sdefault.adb: $(ADA_GEN_SUBDIR)/stamp-sdefault ; @true
$(ADA_GEN_SUBDIR)/stamp-sdefault : $(srcdir)/version.c Makefile
diff --git a/gcc/ada/Makefile.rtl b/gcc/ada/Makefile.rtl
index 144e91469..8ef346915 100644
--- a/gcc/ada/Makefile.rtl
+++ b/gcc/ada/Makefile.rtl
@@ -481,6 +481,7 @@ GNATRTL_NONTASKING_OBJS= \
s-atocou$(objext) \
s-atopri$(objext) \
s-auxdec$(objext) \
+ s-bignum$(objext) \
s-bitops$(objext) \
s-boarop$(objext) \
s-bytswa$(objext) \
diff --git a/gcc/ada/a-calcon.adb b/gcc/ada/a-calcon.adb
index 7d58969cd..f24b971b2 100644
--- a/gcc/ada/a-calcon.adb
+++ b/gcc/ada/a-calcon.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2008-2009 Free Software Foundation, Inc. --
+-- Copyright (C) 2008-2012, 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- --
@@ -140,7 +140,7 @@ package body Ada.Calendar.Conversions is
function To_Unix_Time (Ada_Time : Time) return long is
Val : constant Long_Integer :=
- Conversion_Operations.To_Unix_Time (Ada_Time);
+ Conversion_Operations.To_Unix_Time (Ada_Time);
begin
return long (Val);
end To_Unix_Time;
diff --git a/gcc/ada/a-caldel-vms.adb b/gcc/ada/a-caldel-vms.adb
index 72cad3316..1cf6f00d9 100644
--- a/gcc/ada/a-caldel-vms.adb
+++ b/gcc/ada/a-caldel-vms.adb
@@ -7,7 +7,7 @@
-- B o d y --
-- --
-- Copyright (C) 1991-1994, Florida State University --
--- Copyright (C) 1995-2010, AdaCore --
+-- Copyright (C) 1995-2012, AdaCore --
-- --
-- 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- --
@@ -78,7 +78,7 @@ package body Ada.Calendar.Delays is
-- cause overflow.
Safe_T : constant Time :=
- (if T > Safe_Ada_High then Safe_Ada_High else T);
+ (if T > Safe_Ada_High then Safe_Ada_High else T);
begin
return OSP.To_Duration (OSP.OS_Time (Safe_T), OSP.Absolute_Calendar);
diff --git a/gcc/ada/a-calend-vms.adb b/gcc/ada/a-calend-vms.adb
index dc7c23e75..9d6913d04 100644
--- a/gcc/ada/a-calend-vms.adb
+++ b/gcc/ada/a-calend-vms.adb
@@ -141,7 +141,7 @@ package body Ada.Calendar is
-- UTC, it must be increased to include all leap seconds.
Ada_High_And_Leaps : constant OS_Time :=
- Ada_High + OS_Time (Leap_Seconds_Count) * Mili;
+ Ada_High + OS_Time (Leap_Seconds_Count) * Mili;
-- Two constants used in the calculations of elapsed leap seconds.
-- End_Of_Time is later than Ada_High in time zone -28. Start_Of_Time
@@ -221,9 +221,9 @@ package body Ada.Calendar is
-- The bound of type Duration expressed as time
Dur_High : constant OS_Time :=
- OS_Time (To_Relative_Time (Duration'Last));
+ OS_Time (To_Relative_Time (Duration'Last));
Dur_Low : constant OS_Time :=
- OS_Time (To_Relative_Time (Duration'First));
+ OS_Time (To_Relative_Time (Duration'First));
Res_M : OS_Time;
diff --git a/gcc/ada/a-calend.adb b/gcc/ada/a-calend.adb
index 3d70cf4f4..dbc95771e 100644
--- a/gcc/ada/a-calend.adb
+++ b/gcc/ada/a-calend.adb
@@ -177,29 +177,29 @@ package body Ada.Calendar is
-- UTC, it must be increased to include all leap seconds.
Ada_High_And_Leaps : constant Time_Rep :=
- Ada_High + Time_Rep (Leap_Seconds_Count) * Nano;
+ Ada_High + Time_Rep (Leap_Seconds_Count) * Nano;
-- Two constants used in the calculations of elapsed leap seconds.
-- End_Of_Time is later than Ada_High in time zone -28. Start_Of_Time
-- is earlier than Ada_Low in time zone +28.
End_Of_Time : constant Time_Rep :=
- Ada_High + Time_Rep (3) * Nanos_In_Day;
+ Ada_High + Time_Rep (3) * Nanos_In_Day;
Start_Of_Time : constant Time_Rep :=
- Ada_Low - Time_Rep (3) * Nanos_In_Day;
+ Ada_Low - Time_Rep (3) * Nanos_In_Day;
-- The Unix lower time bound expressed as nanoseconds since the start of
-- Ada time in UTC.
Unix_Min : constant Time_Rep :=
- Ada_Low + Time_Rep (17 * 366 + 52 * 365) * Nanos_In_Day;
+ Ada_Low + Time_Rep (17 * 366 + 52 * 365) * Nanos_In_Day;
-- The Unix upper time bound expressed as nanoseconds since the start of
-- Ada time in UTC.
Unix_Max : constant Time_Rep :=
- Ada_Low + Time_Rep (34 * 366 + 102 * 365) * Nanos_In_Day +
- Time_Rep (Leap_Seconds_Count) * Nano;
+ Ada_Low + Time_Rep (34 * 366 + 102 * 365) * Nanos_In_Day +
+ Time_Rep (Leap_Seconds_Count) * Nano;
Epoch_Offset : constant Time_Rep := (136 * 365 + 44 * 366) * Nanos_In_Day;
-- The difference between 2150-1-1 UTC and 1970-1-1 UTC expressed in
@@ -367,7 +367,7 @@ package body Ada.Calendar is
-- by adding the number of nanoseconds between the two origins.
Res_N : Time_Rep :=
- Duration_To_Time_Rep (System.OS_Primitives.Clock) + Unix_Min;
+ Duration_To_Time_Rep (System.OS_Primitives.Clock) + Unix_Min;
begin
-- If the target supports leap seconds, determine the number of leap
@@ -1283,7 +1283,7 @@ package body Ada.Calendar is
else
declare
Off : constant Long_Integer :=
- UTC_Time_Offset (Time (Date_N), Is_Historic);
+ UTC_Time_Offset (Time (Date_N), Is_Historic);
begin
Date_N := Date_N + Time_Rep (Off) * Nano;
@@ -1506,11 +1506,11 @@ package body Ada.Calendar is
else
declare
Cur_Off : constant Long_Integer :=
- UTC_Time_Offset (Time (Res_N), Is_Historic);
+ UTC_Time_Offset (Time (Res_N), Is_Historic);
Cur_Res_N : constant Time_Rep :=
- Res_N - Time_Rep (Cur_Off) * Nano;
+ Res_N - Time_Rep (Cur_Off) * Nano;
Off : constant Long_Integer :=
- UTC_Time_Offset (Time (Cur_Res_N), Is_Historic);
+ UTC_Time_Offset (Time (Cur_Res_N), Is_Historic);
begin
Res_N := Res_N - Time_Rep (Off) * Nano;
diff --git a/gcc/ada/a-calfor.adb b/gcc/ada/a-calfor.adb
index 1376f9367..6da6f1d40 100644
--- a/gcc/ada/a-calfor.adb
+++ b/gcc/ada/a-calfor.adb
@@ -213,7 +213,7 @@ package body Ada.Calendar.Formatting is
Result : String := "0000-00-00 00:00:00.00";
Last : constant Positive :=
- Result'Last - (if Include_Time_Fraction then 0 else 3);
+ Result'Last - (if Include_Time_Fraction then 0 else 3);
begin
Split (Date, Year, Month, Day,
diff --git a/gcc/ada/a-catizo.adb b/gcc/ada/a-catizo.adb
index a0eb02d0b..3c3c02f70 100644
--- a/gcc/ada/a-catizo.adb
+++ b/gcc/ada/a-catizo.adb
@@ -44,7 +44,7 @@ package body Ada.Calendar.Time_Zones is
function UTC_Time_Offset (Date : Time := Clock) return Time_Offset is
Offset_L : constant Long_Integer :=
- Time_Zones_Operations.UTC_Time_Offset (Date);
+ Time_Zones_Operations.UTC_Time_Offset (Date);
Offset : Time_Offset;
begin
diff --git a/gcc/ada/a-cbdlli.adb b/gcc/ada/a-cbdlli.adb
index df9bf2242..5db2d58f3 100644
--- a/gcc/ada/a-cbdlli.adb
+++ b/gcc/ada/a-cbdlli.adb
@@ -902,7 +902,7 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
procedure Sort (Front, Back : Count_Type) is
Pivot : constant Count_Type :=
- (if Front = 0 then Container.First else N (Front).Next);
+ (if Front = 0 then Container.First else N (Front).Next);
begin
if Pivot /= Back then
Partition (Pivot, Back);
@@ -1160,9 +1160,9 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => 0)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => 0)
do
B := B + 1;
end return;
@@ -1209,9 +1209,9 @@ package body Ada.Containers.Bounded_Doubly_Linked_Lists is
-- is a forward or reverse iteration.
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
diff --git a/gcc/ada/a-cbhama.adb b/gcc/ada/a-cbhama.adb
index 8eeaca2e2..314bed614 100644
--- a/gcc/ada/a-cbhama.adb
+++ b/gcc/ada/a-cbhama.adb
@@ -739,8 +739,8 @@ package body Ada.Containers.Bounded_Hashed_Maps is
begin
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access)
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access)
do
B := B + 1;
end return;
diff --git a/gcc/ada/a-cbhase.adb b/gcc/ada/a-cbhase.adb
index 7e294d3fb..cc60762ed 100644
--- a/gcc/ada/a-cbhase.adb
+++ b/gcc/ada/a-cbhase.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2012, 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- --
@@ -129,7 +129,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is
L_Node : Node_Type) return Boolean
is
R_Index : constant Hash_Type :=
- Element_Keys.Index (R_HT, L_Node.Element);
+ Element_Keys.Index (R_HT, L_Node.Element);
R_Node : Count_Type := R_HT.Buckets (R_Index);
@@ -480,7 +480,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is
L_Node : Node_Type) return Boolean
is
R_Index : constant Hash_Type :=
- Element_Keys.Index (R_HT, L_Node.Element);
+ Element_Keys.Index (R_HT, L_Node.Element);
R_Node : Count_Type := R_HT.Buckets (R_Index);
@@ -959,8 +959,8 @@ package body Ada.Containers.Bounded_Hashed_Sets is
begin
B := B + 1;
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access);
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access);
end Iterate;
------------
@@ -1180,8 +1180,7 @@ package body Ada.Containers.Bounded_Hashed_Sets is
(Container : in out Set;
New_Item : Element_Type)
is
- Node : constant Count_Type :=
- Element_Keys.Find (Container, New_Item);
+ Node : constant Count_Type := Element_Keys.Find (Container, New_Item);
begin
if Node = 0 then
diff --git a/gcc/ada/a-cbmutr.adb b/gcc/ada/a-cbmutr.adb
index e40c7bfc8..536f00afd 100644
--- a/gcc/ada/a-cbmutr.adb
+++ b/gcc/ada/a-cbmutr.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2011-2012, 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- --
@@ -1903,9 +1903,9 @@ package body Ada.Containers.Bounded_Multiway_Trees is
end if;
return It : constant Child_Iterator :=
- Child_Iterator'(Limited_Controlled with
- Container => C,
- Subtree => Parent.Node)
+ Child_Iterator'(Limited_Controlled with
+ Container => C,
+ Subtree => Parent.Node)
do
B := B + 1;
end return;
@@ -1931,9 +1931,9 @@ package body Ada.Containers.Bounded_Multiway_Trees is
B : Natural renames Position.Container.Busy;
begin
return It : constant Subtree_Iterator :=
- (Limited_Controlled with
- Container => Position.Container,
- Subtree => Position.Node)
+ (Limited_Controlled with
+ Container => Position.Container,
+ Subtree => Position.Node)
do
B := B + 1;
end return;
diff --git a/gcc/ada/a-cborma.adb b/gcc/ada/a-cborma.adb
index a782d39af..8fca6495d 100644
--- a/gcc/ada/a-cborma.adb
+++ b/gcc/ada/a-cborma.adb
@@ -980,9 +980,9 @@ package body Ada.Containers.Bounded_Ordered_Maps is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => 0)
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => 0)
do
B := B + 1;
end return;
@@ -1029,9 +1029,9 @@ package body Ada.Containers.Bounded_Ordered_Maps is
-- is a forward or reverse iteration.)
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
@@ -1174,7 +1174,7 @@ package body Ada.Containers.Bounded_Ordered_Maps is
M : Map renames Position.Container.all;
Node : constant Count_Type :=
- Tree_Operations.Next (M, Position.Node);
+ Tree_Operations.Next (M, Position.Node);
begin
if Node = 0 then
@@ -1233,7 +1233,7 @@ package body Ada.Containers.Bounded_Ordered_Maps is
M : Map renames Position.Container.all;
Node : constant Count_Type :=
- Tree_Operations.Previous (M, Position.Node);
+ Tree_Operations.Previous (M, Position.Node);
begin
if Node = 0 then
diff --git a/gcc/ada/a-cborse.adb b/gcc/ada/a-cborse.adb
index 62417f36b..3131de137 100644
--- a/gcc/ada/a-cborse.adb
+++ b/gcc/ada/a-cborse.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2012, 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- --
@@ -378,7 +378,7 @@ package body Ada.Containers.Bounded_Ordered_Sets is
function Ceiling (Container : Set; Item : Element_Type) return Cursor is
Node : constant Count_Type :=
- Element_Keys.Ceiling (Container, Item);
+ Element_Keys.Ceiling (Container, Item);
begin
return (if Node = 0 then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -720,7 +720,7 @@ package body Ada.Containers.Bounded_Ordered_Sets is
function Ceiling (Container : Set; Key : Key_Type) return Cursor is
Node : constant Count_Type :=
- Key_Keys.Ceiling (Container, Key);
+ Key_Keys.Ceiling (Container, Key);
begin
return (if Node = 0 then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -1334,9 +1334,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => 0)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => 0)
do
B := B + 1;
end return;
@@ -1382,9 +1382,9 @@ package body Ada.Containers.Bounded_Ordered_Sets is
-- is a forward or reverse iteration.)
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
@@ -1487,7 +1487,7 @@ package body Ada.Containers.Bounded_Ordered_Sets is
declare
Node : constant Count_Type :=
- Tree_Operations.Next (Position.Container.all, Position.Node);
+ Tree_Operations.Next (Position.Container.all, Position.Node);
begin
if Node = 0 then
@@ -1548,9 +1548,7 @@ package body Ada.Containers.Bounded_Ordered_Sets is
declare
Node : constant Count_Type :=
- Tree_Operations.Previous
- (Position.Container.all,
- Position.Node);
+ Tree_Operations.Previous (Position.Container.all, Position.Node);
begin
return (if Node = 0 then No_Element
else Cursor'(Position.Container, Node));
diff --git a/gcc/ada/a-cdlili.adb b/gcc/ada/a-cdlili.adb
index a04afb0bd..8234f327e 100644
--- a/gcc/ada/a-cdlili.adb
+++ b/gcc/ada/a-cdlili.adb
@@ -264,9 +264,8 @@ package body Ada.Containers.Doubly_Linked_Lists is
L : Natural renames C.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -750,7 +749,7 @@ package body Ada.Containers.Doubly_Linked_Lists is
procedure Sort (Front, Back : Node_Access) is
Pivot : constant Node_Access :=
- (if Front = null then Container.First else Front.Next);
+ (if Front = null then Container.First else Front.Next);
begin
if Pivot /= Back then
Partition (Pivot, Back);
@@ -997,9 +996,9 @@ package body Ada.Containers.Doubly_Linked_Lists is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => null)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
do
B := B + 1;
end return;
@@ -1044,9 +1043,9 @@ package body Ada.Containers.Doubly_Linked_Lists is
-- is a forward or reverse iteration.
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
@@ -1385,8 +1384,8 @@ package body Ada.Containers.Doubly_Linked_Lists is
L : Natural renames C.Lock;
begin
return R : constant Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
diff --git a/gcc/ada/a-cfdlli.adb b/gcc/ada/a-cfdlli.adb
index 404c66359..ee9484077 100644
--- a/gcc/ada/a-cfdlli.adb
+++ b/gcc/ada/a-cfdlli.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2010-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2010-2012, 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- --
@@ -989,9 +989,9 @@ package body Ada.Containers.Formal_Doubly_Linked_Lists is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- Iterator'(Ada.Finalization.Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => 0)
+ Iterator'(Ada.Finalization.Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => 0)
do
B := B + 1;
end return;
@@ -1029,9 +1029,9 @@ package body Ada.Containers.Formal_Doubly_Linked_Lists is
-- is a forward or reverse iteration.
return It : constant Iterator :=
- Iterator'(Ada.Finalization.Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ Iterator'(Ada.Finalization.Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
diff --git a/gcc/ada/a-cfhama.adb b/gcc/ada/a-cfhama.adb
index f2d670c75..c692cb666 100644
--- a/gcc/ada/a-cfhama.adb
+++ b/gcc/ada/a-cfhama.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2010-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2010-2012, 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- --
@@ -202,7 +202,7 @@ package body Ada.Containers.Formal_Hashed_Maps is
Capacity : Count_Type := 0) return Map
is
C : constant Count_Type :=
- Count_Type'Max (Capacity, Source.Capacity);
+ Count_Type'Max (Capacity, Source.Capacity);
H : Hash_Type;
N : Count_Type;
Target : Map (C, Source.Modulus);
@@ -407,8 +407,7 @@ package body Ada.Containers.Formal_Hashed_Maps is
----------
function Find (Container : Map; Key : Key_Type) return Cursor is
- Node : constant Count_Type :=
- Key_Ops.Find (Container, Key);
+ Node : constant Count_Type := Key_Ops.Find (Container, Key);
begin
if Node = 0 then
@@ -700,7 +699,7 @@ package body Ada.Containers.Formal_Hashed_Maps is
function Left (Container : Map; Position : Cursor) return Map is
Curs : Cursor;
C : Map (Container.Capacity, Container.Modulus) :=
- Copy (Container, Container.Capacity);
+ Copy (Container, Container.Capacity);
Node : Count_Type;
begin
@@ -1026,7 +1025,7 @@ package body Ada.Containers.Formal_Hashed_Maps is
function Right (Container : Map; Position : Cursor) return Map is
Curs : Cursor := First (Container);
C : Map (Container.Capacity, Container.Modulus) :=
- Copy (Container, Container.Capacity);
+ Copy (Container, Container.Capacity);
Node : Count_Type;
begin
diff --git a/gcc/ada/a-cfhase.adb b/gcc/ada/a-cfhase.adb
index fe6706bcd..d5d73e2a1 100644
--- a/gcc/ada/a-cfhase.adb
+++ b/gcc/ada/a-cfhase.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2010-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2010-2012, 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- --
@@ -226,7 +226,7 @@ package body Ada.Containers.Formal_Hashed_Sets is
Capacity : Count_Type := 0) return Set
is
C : constant Count_Type :=
- Count_Type'Max (Capacity, Source.Capacity);
+ Count_Type'Max (Capacity, Source.Capacity);
H : Hash_Type;
N : Count_Type;
Target : Set (C, Source.Modulus);
@@ -470,7 +470,7 @@ package body Ada.Containers.Formal_Hashed_Sets is
L_Node : Node_Type) return Boolean
is
R_Index : constant Hash_Type :=
- Element_Keys.Index (R_HT, L_Node.Element);
+ Element_Keys.Index (R_HT, L_Node.Element);
R_Node : Count_Type := R_HT.Buckets (R_Index);
RN : Nodes_Type renames R_HT.Nodes;
@@ -979,7 +979,7 @@ package body Ada.Containers.Formal_Hashed_Sets is
function Left (Container : Set; Position : Cursor) return Set is
Curs : Cursor := Position;
C : Set (Container.Capacity, Container.Modulus) :=
- Copy (Container, Container.Capacity);
+ Copy (Container, Container.Capacity);
Node : Count_Type;
begin
@@ -1280,7 +1280,7 @@ package body Ada.Containers.Formal_Hashed_Sets is
function Right (Container : Set; Position : Cursor) return Set is
Curs : Cursor := First (Container);
C : Set (Container.Capacity, Container.Modulus) :=
- Copy (Container, Container.Capacity);
+ Copy (Container, Container.Capacity);
Node : Count_Type;
begin
diff --git a/gcc/ada/a-cforma.adb b/gcc/ada/a-cforma.adb
index ce361a1a2..6b45ad603 100644
--- a/gcc/ada/a-cforma.adb
+++ b/gcc/ada/a-cforma.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2010-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2010-2012, 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- --
@@ -1003,7 +1003,7 @@ package body Ada.Containers.Formal_Ordered_Maps is
declare
Node : constant Count_Type :=
- Tree_Operations.Previous (Container, Position.Node);
+ Tree_Operations.Previous (Container, Position.Node);
begin
if Node = 0 then
diff --git a/gcc/ada/a-cforse.adb b/gcc/ada/a-cforse.adb
index 9872f2ce3..0707d74d0 100644
--- a/gcc/ada/a-cforse.adb
+++ b/gcc/ada/a-cforse.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2010-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2010-2012, 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- --
@@ -1336,7 +1336,7 @@ package body Ada.Containers.Formal_Ordered_Sets is
declare
Node : constant Count_Type :=
- Tree_Operations.Previous (Container, Position.Node);
+ Tree_Operations.Previous (Container, Position.Node);
begin
return (if Node = 0 then No_Element else (Node => Node));
end;
diff --git a/gcc/ada/a-cidlli.adb b/gcc/ada/a-cidlli.adb
index fafe67191..7d5e22ee8 100644
--- a/gcc/ada/a-cidlli.adb
+++ b/gcc/ada/a-cidlli.adb
@@ -291,8 +291,8 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
L : Natural renames C.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -801,7 +801,7 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
procedure Sort (Front, Back : Node_Access) is
Pivot : constant Node_Access :=
- (if Front = null then Container.First else Front.Next);
+ (if Front = null then Container.First else Front.Next);
begin
if Pivot /= Back then
Partition (Pivot, Back);
@@ -1041,9 +1041,9 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => null)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
do
B := B + 1;
end return;
@@ -1090,9 +1090,9 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
-- is a forward or reverse iteration.
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
@@ -1345,7 +1345,7 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
declare
Element : Element_Access :=
- new Element_Type'(Element_Type'Input (Stream));
+ new Element_Type'(Element_Type'Input (Stream));
begin
Dst := new Node_Type'(Element, null, null);
exception
@@ -1361,7 +1361,7 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
while Item.Length < N loop
declare
Element : Element_Access :=
- new Element_Type'(Element_Type'Input (Stream));
+ new Element_Type'(Element_Type'Input (Stream));
begin
Dst := new Node_Type'(Element, Next => null, Prev => Item.Last);
exception
@@ -1430,8 +1430,8 @@ package body Ada.Containers.Indefinite_Doubly_Linked_Lists is
L : Natural renames C.Lock;
begin
return R : constant Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
diff --git a/gcc/ada/a-cihama.adb b/gcc/ada/a-cihama.adb
index 2ea73b9f9..2d889cdfb 100644
--- a/gcc/ada/a-cihama.adb
+++ b/gcc/ada/a-cihama.adb
@@ -239,9 +239,8 @@ package body Ada.Containers.Indefinite_Hashed_Maps is
L : Natural renames HT.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -271,9 +270,8 @@ package body Ada.Containers.Indefinite_Hashed_Maps is
L : Natural renames HT.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -851,8 +849,7 @@ package body Ada.Containers.Indefinite_Hashed_Maps is
B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
begin
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access)
+ (Limited_Controlled with Container => Container'Unrestricted_Access)
do
B := B + 1;
end return;
@@ -1110,8 +1107,8 @@ package body Ada.Containers.Indefinite_Hashed_Maps is
L : Natural renames HT.Lock;
begin
return R : constant Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -1141,9 +1138,8 @@ package body Ada.Containers.Indefinite_Hashed_Maps is
L : Natural renames HT.Lock;
begin
return R : constant Reference_Type :=
- (Element => Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
diff --git a/gcc/ada/a-cihase.adb b/gcc/ada/a-cihase.adb
index 9d96b6c64..bae3ecc38 100644
--- a/gcc/ada/a-cihase.adb
+++ b/gcc/ada/a-cihase.adb
@@ -255,9 +255,8 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
L : Natural renames HT.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -683,7 +682,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
L_Node : Node_Access) return Boolean
is
R_Index : constant Hash_Type :=
- Element_Keys.Index (R_HT, L_Node.Element.all);
+ Element_Keys.Index (R_HT, L_Node.Element.all);
R_Node : Node_Access := R_HT.Buckets (R_Index);
@@ -710,7 +709,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
L_Node : Node_Access) return Boolean
is
R_Index : constant Hash_Type :=
- Element_Keys.Index (R_HT, L_Node.Element.all);
+ Element_Keys.Index (R_HT, L_Node.Element.all);
R_Node : Node_Access := R_HT.Buckets (R_Index);
@@ -1119,8 +1118,8 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
begin
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access)
do
B := B + 1;
end return;
@@ -1322,7 +1321,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
New_Item : Element_Type)
is
Node : constant Node_Access :=
- Element_Keys.Find (Container.HT, New_Item);
+ Element_Keys.Find (Container.HT, New_Item);
X : Element_Access;
pragma Warnings (Off, X);
@@ -1566,7 +1565,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
declare
Size : constant Hash_Type :=
- Prime_Numbers.To_Prime (Left.Length + Right.Length);
+ Prime_Numbers.To_Prime (Left.Length + Right.Length);
begin
Buckets := HT_Ops.New_Buckets (Length => Size);
end;
@@ -1768,7 +1767,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
declare
Size : constant Hash_Type :=
- Prime_Numbers.To_Prime (Left.Length + Right.Length);
+ Prime_Numbers.To_Prime (Left.Length + Right.Length);
begin
Buckets := HT_Ops.New_Buckets (Length => Size);
end;
@@ -1990,7 +1989,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
Key : Key_Type) return Constant_Reference_Type
is
Node : constant Node_Access :=
- Key_Keys.Find (Container.HT, Key);
+ Key_Keys.Find (Container.HT, Key);
begin
if Node = null then
@@ -2007,9 +2006,8 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
L : Natural renames HT.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -2176,7 +2174,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
Key : Key_Type) return Reference_Type
is
Node : constant Node_Access :=
- Key_Keys.Find (Container.HT, Key);
+ Key_Keys.Find (Container.HT, Key);
begin
if Node = null then
@@ -2204,7 +2202,7 @@ package body Ada.Containers.Indefinite_Hashed_Sets is
New_Item : Element_Type)
is
Node : constant Node_Access :=
- Key_Keys.Find (Container.HT, Key);
+ Key_Keys.Find (Container.HT, Key);
begin
if Node = null then
diff --git a/gcc/ada/a-cimutr.adb b/gcc/ada/a-cimutr.adb
index e249c6a68..15f1640e8 100644
--- a/gcc/ada/a-cimutr.adb
+++ b/gcc/ada/a-cimutr.adb
@@ -504,9 +504,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
L : Natural renames C.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -1049,7 +1048,7 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
Item : Element_Type) return Cursor
is
N : constant Tree_Node_Access :=
- Find_In_Children (Root_Node (Container), Item);
+ Find_In_Children (Root_Node (Container), Item);
begin
if N = null then
@@ -1534,9 +1533,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
end if;
return It : constant Child_Iterator :=
- Child_Iterator'(Limited_Controlled with
- Container => C,
- Subtree => Parent.Node)
+ Child_Iterator'(Limited_Controlled with
+ Container => C,
+ Subtree => Parent.Node)
do
B := B + 1;
end return;
@@ -1562,9 +1561,9 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
B : Natural renames Position.Container.Busy;
begin
return It : constant Subtree_Iterator :=
- (Limited_Controlled with
- Container => Position.Container,
- Subtree => Position.Node)
+ (Limited_Controlled with
+ Container => Position.Container,
+ Subtree => Position.Node)
do
B := B + 1;
end return;
@@ -2023,13 +2022,11 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
(Parent : Tree_Node_Access) return Tree_Node_Access
is
Element : constant Element_Access :=
- new Element_Type'(Element_Type'Input (Stream));
+ new Element_Type'(Element_Type'Input (Stream));
Subtree : constant Tree_Node_Access :=
- new Tree_Node_Type'
- (Parent => Parent,
- Element => Element,
- others => <>);
+ new Tree_Node_Type'
+ (Parent => Parent, Element => Element, others => <>);
begin
Read_Count := Read_Count + 1;
@@ -2126,8 +2123,8 @@ package body Ada.Containers.Indefinite_Multiway_Trees is
L : Natural renames C.Lock;
begin
return R : constant Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
diff --git a/gcc/ada/a-ciorma.adb b/gcc/ada/a-ciorma.adb
index 472c912d2..7f2b2491e 100644
--- a/gcc/ada/a-ciorma.adb
+++ b/gcc/ada/a-ciorma.adb
@@ -399,9 +399,8 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
L : Natural renames T.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -430,9 +429,8 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
L : Natural renames T.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -1014,9 +1012,9 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => null)
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
do
B := B + 1;
end return;
@@ -1064,9 +1062,9 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
-- is a forward or reverse iteration.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
@@ -1204,7 +1202,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
declare
Node : constant Node_Access :=
- Tree_Operations.Next (Position.Node);
+ Tree_Operations.Next (Position.Node);
begin
return (if Node = null then No_Element
else Cursor'(Position.Container, Node));
@@ -1260,7 +1258,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
declare
Node : constant Node_Access :=
- Tree_Operations.Previous (Position.Node);
+ Tree_Operations.Previous (Position.Node);
begin
return (if Node = null then No_Element
else Cursor'(Position.Container, Node));
@@ -1437,8 +1435,8 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
L : Natural renames T.Lock;
begin
return R : constant Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -1467,9 +1465,8 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
L : Natural renames T.Lock;
begin
return R : constant Reference_Type :=
- (Element => Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -1486,8 +1483,7 @@ package body Ada.Containers.Indefinite_Ordered_Maps is
Key : Key_Type;
New_Item : Element_Type)
is
- Node : constant Node_Access :=
- Key_Ops.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Ops.Find (Container.Tree, Key);
K : Key_Access;
E : Element_Access;
diff --git a/gcc/ada/a-ciormu.adb b/gcc/ada/a-ciormu.adb
index 7bd1aa1e5..4fce4754c 100644
--- a/gcc/ada/a-ciormu.adb
+++ b/gcc/ada/a-ciormu.adb
@@ -340,7 +340,7 @@ package body Ada.Containers.Indefinite_Ordered_Multisets is
function Ceiling (Container : Set; Item : Element_Type) return Cursor is
Node : constant Node_Access :=
- Element_Keys.Ceiling (Container.Tree, Item);
+ Element_Keys.Ceiling (Container.Tree, Item);
begin
if Node = null then
@@ -503,8 +503,7 @@ package body Ada.Containers.Indefinite_Ordered_Multisets is
end Difference;
function Difference (Left, Right : Set) return Set is
- Tree : constant Tree_Type :=
- Set_Ops.Difference (Left.Tree, Right.Tree);
+ Tree : constant Tree_Type := Set_Ops.Difference (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Difference;
@@ -601,8 +600,7 @@ package body Ada.Containers.Indefinite_Ordered_Multisets is
----------
function Find (Container : Set; Item : Element_Type) return Cursor is
- Node : constant Node_Access :=
- Element_Keys.Find (Container.Tree, Item);
+ Node : constant Node_Access := Element_Keys.Find (Container.Tree, Item);
begin
if Node = null then
@@ -677,8 +675,7 @@ package body Ada.Containers.Indefinite_Ordered_Multisets is
-----------
function Floor (Container : Set; Item : Element_Type) return Cursor is
- Node : constant Node_Access :=
- Element_Keys.Floor (Container.Tree, Item);
+ Node : constant Node_Access := Element_Keys.Floor (Container.Tree, Item);
begin
if Node = null then
@@ -753,8 +750,7 @@ package body Ada.Containers.Indefinite_Ordered_Multisets is
-------------
function Ceiling (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Node_Access :=
- Key_Keys.Ceiling (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Ceiling (Container.Tree, Key);
begin
if Node = null then
@@ -803,8 +799,7 @@ package body Ada.Containers.Indefinite_Ordered_Multisets is
-------------
function Element (Container : Set; Key : Key_Type) return Element_Type is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
@@ -1259,7 +1254,7 @@ package body Ada.Containers.Indefinite_Ordered_Multisets is
function Intersection (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Intersection (Left.Tree, Right.Tree);
+ Set_Ops.Intersection (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Intersection;
diff --git a/gcc/ada/a-ciorse.adb b/gcc/ada/a-ciorse.adb
index 885c6b656..a6538665a 100644
--- a/gcc/ada/a-ciorse.adb
+++ b/gcc/ada/a-ciorse.adb
@@ -359,7 +359,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
function Ceiling (Container : Set; Item : Element_Type) return Cursor is
Node : constant Node_Access :=
- Element_Keys.Ceiling (Container.Tree, Item);
+ Element_Keys.Ceiling (Container.Tree, Item);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -418,9 +418,8 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
L : Natural renames Tree.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -494,8 +493,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
end Delete;
procedure Delete (Container : in out Set; Item : Element_Type) is
- X : Node_Access :=
- Element_Keys.Find (Container.Tree, Item);
+ X : Node_Access := Element_Keys.Find (Container.Tree, Item);
begin
if X = null then
@@ -620,8 +618,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
-------------
procedure Exclude (Container : in out Set; Item : Element_Type) is
- X : Node_Access :=
- Element_Keys.Find (Container.Tree, Item);
+ X : Node_Access := Element_Keys.Find (Container.Tree, Item);
begin
if X /= null then
Tree_Operations.Delete_Node_Sans_Free (Container.Tree, X);
@@ -665,8 +662,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
----------
function Find (Container : Set; Item : Element_Type) return Cursor is
- Node : constant Node_Access :=
- Element_Keys.Find (Container.Tree, Item);
+ Node : constant Node_Access := Element_Keys.Find (Container.Tree, Item);
begin
if Node = null then
return No_Element;
@@ -726,8 +722,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
-----------
function Floor (Container : Set; Item : Element_Type) return Cursor is
- Node : constant Node_Access :=
- Element_Keys.Floor (Container.Tree, Item);
+ Node : constant Node_Access := Element_Keys.Floor (Container.Tree, Item);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -798,8 +793,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
-------------
function Ceiling (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Node_Access :=
- Key_Keys.Ceiling (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Ceiling (Container.Tree, Key);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -813,8 +807,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
(Container : aliased Set;
Key : Key_Type) return Constant_Reference_Type
is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
@@ -831,9 +824,8 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
L : Natural renames Tree.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Node.Element.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -871,8 +863,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
-------------
function Element (Container : Set; Key : Key_Type) return Element_Type is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
raise Constraint_Error with "key not in set";
@@ -912,8 +903,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
----------
function Find (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -924,8 +914,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
-----------
function Floor (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Node_Access :=
- Key_Keys.Floor (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Floor (Container.Tree, Key);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -1046,8 +1035,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
(Container : aliased in out Set;
Key : Key_Type) return Reference_Type
is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
@@ -1309,8 +1297,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
--------------
function New_Node return Node_Access is
- Element : Element_Access :=
- new Element_Type'(Src_Node.Element.all);
+ Element : Element_Access := new Element_Type'(Src_Node.Element.all);
Node : Node_Access;
begin
@@ -1348,7 +1335,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
function Intersection (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Intersection (Left.Tree, Right.Tree);
+ Set_Ops.Intersection (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Intersection;
@@ -1466,9 +1453,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => null)
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
do
B := B + 1;
end return;
@@ -1516,9 +1503,9 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
-- a forward or reverse iteration.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
@@ -1622,8 +1609,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
"bad cursor in Next");
declare
- Node : constant Node_Access :=
- Tree_Operations.Next (Position.Node);
+ Node : constant Node_Access := Tree_Operations.Next (Position.Node);
begin
return (if Node = null then No_Element
else Cursor'(Position.Container, Node));
@@ -1689,7 +1675,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
declare
Node : constant Node_Access :=
- Tree_Operations.Previous (Position.Node);
+ Tree_Operations.Previous (Position.Node);
begin
return (if Node = null then No_Element
else Cursor'(Position.Container, Node));
@@ -1819,7 +1805,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
procedure Replace (Container : in out Set; New_Item : Element_Type) is
Node : constant Node_Access :=
- Element_Keys.Find (Container.Tree, New_Item);
+ Element_Keys.Find (Container.Tree, New_Item);
X : Element_Access;
pragma Warnings (Off, X);
@@ -2097,7 +2083,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
function Symmetric_Difference (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
+ Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Symmetric_Difference;
@@ -2126,8 +2112,7 @@ package body Ada.Containers.Indefinite_Ordered_Sets is
end Union;
function Union (Left, Right : Set) return Set is
- Tree : constant Tree_Type :=
- Set_Ops.Union (Left.Tree, Right.Tree);
+ Tree : constant Tree_Type := Set_Ops.Union (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Union;
diff --git a/gcc/ada/a-clrefi.adb b/gcc/ada/a-clrefi.adb
index 938ea18fb..87090258f 100644
--- a/gcc/ada/a-clrefi.adb
+++ b/gcc/ada/a-clrefi.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2007-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2007-2012, 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- --
@@ -87,7 +87,7 @@ package body Ada.Command_Line.Response_File is
if Last_Arg = Arguments'Last then
declare
New_Arguments : constant Argument_List_Access :=
- new Argument_List (1 .. Arguments'Last * 2);
+ new Argument_List (1 .. Arguments'Last * 2);
begin
New_Arguments (Arguments'Range) := Arguments.all;
Arguments.all := (others => null);
@@ -421,10 +421,9 @@ package body Ada.Command_Line.Response_File is
declare
Inc_File_Name : constant String :=
- Arguments (Arg)
- (2 .. Arguments (Arg)'Last);
+ Arguments (Arg) (2 .. Arguments (Arg)'Last);
Current_Arguments : constant Argument_List :=
- Arguments (1 .. Last_Arg);
+ Arguments (1 .. Last_Arg);
begin
Recurse (Inc_File_Name);
@@ -433,10 +432,10 @@ package body Ada.Command_Line.Response_File is
declare
New_Arguments : constant Argument_List :=
- Arguments (1 .. Last_Arg);
+ Arguments (1 .. Last_Arg);
New_Last_Arg : constant Positive :=
- Current_Arguments'Length +
- New_Arguments'Length - 1;
+ Current_Arguments'Length +
+ New_Arguments'Length - 1;
begin
-- Grow Arguments if it is not large enough
diff --git a/gcc/ada/a-cobove.adb b/gcc/ada/a-cobove.adb
index af9ea25e0..8ca958f0b 100644
--- a/gcc/ada/a-cobove.adb
+++ b/gcc/ada/a-cobove.adb
@@ -1728,9 +1728,9 @@ package body Ada.Containers.Bounded_Vectors is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => V,
- Index => No_Index)
+ (Limited_Controlled with
+ Container => V,
+ Index => No_Index)
do
B := B + 1;
end return;
@@ -1781,9 +1781,9 @@ package body Ada.Containers.Bounded_Vectors is
-- a forward or reverse iteration.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => V,
- Index => Start.Index)
+ (Limited_Controlled with
+ Container => V,
+ Index => Start.Index)
do
B := B + 1;
end return;
@@ -2319,7 +2319,7 @@ package body Ada.Containers.Bounded_Vectors is
Index : Index_Type := Index_Type'Last) return Extended_Index
is
Last : constant Index_Type'Base :=
- Index_Type'Min (Container.Last, Index);
+ Index_Type'Min (Container.Last, Index);
begin
for Indx in reverse Index_Type'First .. Last loop
diff --git a/gcc/ada/a-cofove.adb b/gcc/ada/a-cofove.adb
index 8900e054c..548512d55 100644
--- a/gcc/ada/a-cofove.adb
+++ b/gcc/ada/a-cofove.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2010-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2010-2012, 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- --
@@ -53,7 +53,7 @@ package body Ada.Containers.Formal_Vectors is
declare
E : constant Elements_Array (1 .. Length (Right)) :=
- Right.Elements (1 .. RN);
+ Right.Elements (1 .. RN);
begin
return (Length (Right), E, Last => Right.Last, others => <>);
end;
@@ -62,7 +62,7 @@ package body Ada.Containers.Formal_Vectors is
if RN = 0 then
declare
E : constant Elements_Array (1 .. Length (Left)) :=
- Left.Elements (1 .. LN);
+ Left.Elements (1 .. LN);
begin
return (Length (Left), E, Last => Left.Last, others => <>);
end;
@@ -370,7 +370,7 @@ package body Ada.Containers.Formal_Vectors is
New_Last_As_Int : constant Int'Base := Old_Last_As_Int - N;
New_Last : constant Index_Type :=
- Index_Type (New_Last_As_Int);
+ Index_Type (New_Last_As_Int);
KK : constant Int := New_Last_As_Int - Int (No_Index);
K : constant Count_Type := Count_Type (KK);
@@ -867,7 +867,7 @@ package body Ada.Containers.Formal_Vectors is
declare
Dst_Last_As_Int : constant Int'Base :=
- Int (Before) + Int (N) - 1 - Int (No_Index);
+ Int (Before) + Int (N) - 1 - Int (No_Index);
Dst_Last : constant Count_Type := Count_Type (Dst_Last_As_Int);
@@ -902,7 +902,7 @@ package body Ada.Containers.Formal_Vectors is
Container.Elements (Dst_Last + 1 .. Length (Container));
Index_As_Int : constant Int'Base :=
- Dst_Last_As_Int - Src'Length + 1;
+ Dst_Last_As_Int - Src'Length + 1;
Index : constant Count_Type := Count_Type (Index_As_Int);
@@ -1775,7 +1775,7 @@ package body Ada.Containers.Formal_Vectors is
declare
Last_As_Int : constant Int'Base :=
- Int (Index_Type'First) + Int (Length) - 1;
+ Int (Index_Type'First) + Int (Length) - 1;
begin
Container.Last := Index_Type'Base (Last_As_Int);
end;
diff --git a/gcc/ada/a-cohama.adb b/gcc/ada/a-cohama.adb
index 00553d0ee..5eee4b302 100644
--- a/gcc/ada/a-cohama.adb
+++ b/gcc/ada/a-cohama.adb
@@ -231,8 +231,8 @@ package body Ada.Containers.Hashed_Maps is
L : Natural renames HT.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -257,9 +257,8 @@ package body Ada.Containers.Hashed_Maps is
L : Natural renames HT.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -312,9 +311,9 @@ package body Ada.Containers.Hashed_Maps is
(Source : Node_Access) return Node_Access
is
Target : constant Node_Access :=
- new Node_Type'(Key => Source.Key,
- Element => Source.Element,
- Next => null);
+ new Node_Type'(Key => Source.Key,
+ Element => Source.Element,
+ Next => null);
begin
return Target;
end Copy_Node;
@@ -774,8 +773,7 @@ package body Ada.Containers.Hashed_Maps is
B : Natural renames Container'Unrestricted_Access.all.HT.Busy;
begin
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access)
+ (Limited_Controlled with Container => Container'Unrestricted_Access)
do
B := B + 1;
end return;
@@ -981,8 +979,8 @@ package body Ada.Containers.Hashed_Maps is
L : Natural renames HT.Lock;
begin
return R : constant Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -1007,9 +1005,8 @@ package body Ada.Containers.Hashed_Maps is
L : Natural renames HT.Lock;
begin
return R : constant Reference_Type :=
- (Element => Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
diff --git a/gcc/ada/a-cohase.adb b/gcc/ada/a-cohase.adb
index 11940ee7a..6180168a1 100644
--- a/gcc/ada/a-cohase.adb
+++ b/gcc/ada/a-cohase.adb
@@ -238,9 +238,8 @@ package body Ada.Containers.Hashed_Sets is
L : Natural renames HT.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -442,7 +441,7 @@ package body Ada.Containers.Hashed_Sets is
if not Is_In (Right.HT, L_Node) then
declare
J : constant Hash_Type :=
- Hash (L_Node.Element) mod Buckets'Length;
+ Hash (L_Node.Element) mod Buckets'Length;
Bucket : Node_Access renames Buckets (J);
@@ -618,7 +617,7 @@ package body Ada.Containers.Hashed_Sets is
L_Node : Node_Access) return Boolean
is
R_Index : constant Hash_Type :=
- Element_Keys.Index (R_HT, L_Node.Element);
+ Element_Keys.Index (R_HT, L_Node.Element);
R_Node : Node_Access := R_HT.Buckets (R_Index);
@@ -645,7 +644,7 @@ package body Ada.Containers.Hashed_Sets is
L_Node : Node_Access) return Boolean
is
R_Index : constant Hash_Type :=
- Element_Keys.Index (R_HT, L_Node.Element);
+ Element_Keys.Index (R_HT, L_Node.Element);
R_Node : Node_Access := R_HT.Buckets (R_Index);
@@ -891,7 +890,7 @@ package body Ada.Containers.Hashed_Sets is
if Is_In (Right.HT, L_Node) then
declare
J : constant Hash_Type :=
- Hash (L_Node.Element) mod Buckets'Length;
+ Hash (L_Node.Element) mod Buckets'Length;
Bucket : Node_Access renames Buckets (J);
@@ -1201,7 +1200,7 @@ package body Ada.Containers.Hashed_Sets is
New_Item : Element_Type)
is
Node : constant Node_Access :=
- Element_Keys.Find (Container.HT, New_Item);
+ Element_Keys.Find (Container.HT, New_Item);
begin
if Node = null then
@@ -1396,7 +1395,7 @@ package body Ada.Containers.Hashed_Sets is
declare
Size : constant Hash_Type :=
- Prime_Numbers.To_Prime (Left.Length + Right.Length);
+ Prime_Numbers.To_Prime (Left.Length + Right.Length);
begin
Buckets := HT_Ops.New_Buckets (Length => Size);
end;
@@ -1520,7 +1519,7 @@ package body Ada.Containers.Hashed_Sets is
function New_Node (Next : Node_Access) return Node_Access is
Node : constant Node_Access :=
- new Node_Type'(Src_Node.Element, Next);
+ new Node_Type'(Src_Node.Element, Next);
begin
return Node;
end New_Node;
@@ -1577,7 +1576,7 @@ package body Ada.Containers.Hashed_Sets is
declare
Size : constant Hash_Type :=
- Prime_Numbers.To_Prime (Left.Length + Right.Length);
+ Prime_Numbers.To_Prime (Left.Length + Right.Length);
begin
Buckets := HT_Ops.New_Buckets (Length => Size);
end;
@@ -1594,7 +1593,7 @@ package body Ada.Containers.Hashed_Sets is
procedure Process (L_Node : Node_Access) is
J : constant Hash_Type :=
- Hash (L_Node.Element) mod Buckets'Length;
+ Hash (L_Node.Element) mod Buckets'Length;
begin
Buckets (J) := new Node_Type'(L_Node.Element, Buckets (J));
@@ -1624,7 +1623,7 @@ package body Ada.Containers.Hashed_Sets is
procedure Process (Src_Node : Node_Access) is
J : constant Hash_Type :=
- Hash (Src_Node.Element) mod Buckets'Length;
+ Hash (Src_Node.Element) mod Buckets'Length;
Tgt_Node : Node_Access := Buckets (J);
@@ -1781,8 +1780,7 @@ package body Ada.Containers.Hashed_Sets is
(Container : aliased Set;
Key : Key_Type) return Constant_Reference_Type
is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.HT, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.HT, Key);
begin
if Node = null then
@@ -1795,9 +1793,8 @@ package body Ada.Containers.Hashed_Sets is
L : Natural renames HT.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -1889,8 +1886,7 @@ package body Ada.Containers.Hashed_Sets is
(Container : Set;
Key : Key_Type) return Cursor
is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.HT, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.HT, Key);
begin
if Node = null then
@@ -1961,8 +1957,7 @@ package body Ada.Containers.Hashed_Sets is
(Container : aliased in out Set;
Key : Key_Type) return Reference_Type
is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.HT, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.HT, Key);
begin
if Node = null then
@@ -1985,8 +1980,7 @@ package body Ada.Containers.Hashed_Sets is
Key : Key_Type;
New_Item : Element_Type)
is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.HT, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.HT, Key);
begin
if Node = null then
diff --git a/gcc/ada/a-coinve.adb b/gcc/ada/a-coinve.adb
index e615ad17e..5b59c019d 100644
--- a/gcc/ada/a-coinve.adb
+++ b/gcc/ada/a-coinve.adb
@@ -90,8 +90,7 @@ package body Ada.Containers.Indefinite_Vectors is
RE : Elements_Array renames
Right.Elements.EA (Index_Type'First .. Right.Last);
- Elements : Elements_Access :=
- new Elements_Type (Right.Last);
+ Elements : Elements_Access := new Elements_Type (Right.Last);
begin
-- Elements of an indefinite vector are allocated, so we cannot
@@ -126,8 +125,7 @@ package body Ada.Containers.Indefinite_Vectors is
LE : Elements_Array renames
Left.Elements.EA (Index_Type'First .. Left.Last);
- Elements : Elements_Access :=
- new Elements_Type (Left.Last);
+ Elements : Elements_Access := new Elements_Type (Left.Last);
begin
-- Elements of an indefinite vector are allocated, so we cannot
@@ -348,8 +346,7 @@ package body Ada.Containers.Indefinite_Vectors is
LE : Elements_Array renames
Left.Elements.EA (Index_Type'First .. Left.Last);
- Elements : Elements_Access :=
- new Elements_Type (Last);
+ Elements : Elements_Access := new Elements_Type (Last);
begin
for I in LE'Range loop
@@ -433,8 +430,7 @@ package body Ada.Containers.Indefinite_Vectors is
RE : Elements_Array renames
Right.Elements.EA (Index_Type'First .. Right.Last);
- Elements : Elements_Access :=
- new Elements_Type (Last);
+ Elements : Elements_Access := new Elements_Type (Last);
I : Index_Type'Base := Index_Type'First;
@@ -717,9 +713,8 @@ package body Ada.Containers.Indefinite_Vectors is
L : Natural renames C.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => E.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => E.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -750,9 +745,8 @@ package body Ada.Containers.Indefinite_Vectors is
L : Natural renames C.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => E.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => E.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -1138,7 +1132,7 @@ package body Ada.Containers.Indefinite_Vectors is
declare
EA : constant Element_Access :=
- Position.Container.Elements.EA (Position.Index);
+ Position.Container.Elements.EA (Position.Index);
begin
if EA = null then
@@ -1287,7 +1281,7 @@ package body Ada.Containers.Indefinite_Vectors is
declare
EA : constant Element_Access :=
- Container.Elements.EA (Index_Type'First);
+ Container.Elements.EA (Index_Type'First);
begin
if EA = null then
@@ -2708,9 +2702,9 @@ package body Ada.Containers.Indefinite_Vectors is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => V,
- Index => No_Index)
+ (Limited_Controlled with
+ Container => V,
+ Index => No_Index)
do
B := B + 1;
end return;
@@ -2761,9 +2755,9 @@ package body Ada.Containers.Indefinite_Vectors is
-- is a forward or reverse iteration.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => V,
- Index => Start.Index)
+ (Limited_Controlled with
+ Container => V,
+ Index => Start.Index)
do
B := B + 1;
end return;
@@ -2816,7 +2810,7 @@ package body Ada.Containers.Indefinite_Vectors is
declare
EA : constant Element_Access :=
- Container.Elements.EA (Container.Last);
+ Container.Elements.EA (Container.Last);
begin
if EA = null then
@@ -3155,8 +3149,8 @@ package body Ada.Containers.Indefinite_Vectors is
L : Natural renames C.Lock;
begin
return R : constant Reference_Type :=
- (Element => E.all'Access,
- Control => (Controlled with Position.Container))
+ (Element => E.all'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -3187,9 +3181,8 @@ package body Ada.Containers.Indefinite_Vectors is
L : Natural renames C.Lock;
begin
return R : constant Reference_Type :=
- (Element => E.all'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => E.all'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -3652,7 +3645,7 @@ package body Ada.Containers.Indefinite_Vectors is
Index : Index_Type := Index_Type'Last) return Extended_Index
is
Last : constant Index_Type'Base :=
- (if Index > Container.Last then Container.Last else Index);
+ (if Index > Container.Last then Container.Last else Index);
begin
for Indx in reverse Index_Type'First .. Last loop
if Container.Elements.EA (Indx) /= null
diff --git a/gcc/ada/a-comutr.adb b/gcc/ada/a-comutr.adb
index 4933bcf54..426c6f067 100644
--- a/gcc/ada/a-comutr.adb
+++ b/gcc/ada/a-comutr.adb
@@ -484,9 +484,8 @@ package body Ada.Containers.Multiway_Trees is
L : Natural renames C.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -1009,7 +1008,7 @@ package body Ada.Containers.Multiway_Trees is
Item : Element_Type) return Cursor
is
N : constant Tree_Node_Access :=
- Find_In_Children (Root_Node (Container), Item);
+ Find_In_Children (Root_Node (Container), Item);
begin
if N = null then
return No_Element;
@@ -1537,9 +1536,9 @@ package body Ada.Containers.Multiway_Trees is
end if;
return It : constant Child_Iterator :=
- (Limited_Controlled with
- Container => C,
- Subtree => Parent.Node)
+ (Limited_Controlled with
+ Container => C,
+ Subtree => Parent.Node)
do
B := B + 1;
end return;
@@ -1565,9 +1564,9 @@ package body Ada.Containers.Multiway_Trees is
B : Natural renames Position.Container.Busy;
begin
return It : constant Subtree_Iterator :=
- (Limited_Controlled with
- Container => Position.Container,
- Subtree => Position.Node)
+ (Limited_Controlled with
+ Container => Position.Container,
+ Subtree => Position.Node)
do
B := B + 1;
end return;
@@ -2006,10 +2005,10 @@ package body Ada.Containers.Multiway_Trees is
(Parent : Tree_Node_Access) return Tree_Node_Access
is
Subtree : constant Tree_Node_Access :=
- new Tree_Node_Type'
- (Parent => Parent,
- Element => Element_Type'Input (Stream),
- others => <>);
+ new Tree_Node_Type'
+ (Parent => Parent,
+ Element => Element_Type'Input (Stream),
+ others => <>);
begin
Read_Count := Read_Count + 1;
@@ -2102,8 +2101,8 @@ package body Ada.Containers.Multiway_Trees is
L : Natural renames C.Lock;
begin
return R : constant Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
diff --git a/gcc/ada/a-convec.adb b/gcc/ada/a-convec.adb
index e2e5d93f2..6282301dd 100644
--- a/gcc/ada/a-convec.adb
+++ b/gcc/ada/a-convec.adb
@@ -85,10 +85,10 @@ package body Ada.Containers.Vectors is
declare
RE : Elements_Array renames
- Right.Elements.EA (Index_Type'First .. Right.Last);
+ Right.Elements.EA (Index_Type'First .. Right.Last);
Elements : constant Elements_Access :=
- new Elements_Type'(Right.Last, RE);
+ new Elements_Type'(Right.Last, RE);
begin
return (Controlled with Elements, Right.Last, 0, 0);
@@ -101,7 +101,7 @@ package body Ada.Containers.Vectors is
Left.Elements.EA (Index_Type'First .. Left.Last);
Elements : constant Elements_Access :=
- new Elements_Type'(Left.Last, LE);
+ new Elements_Type'(Left.Last, LE);
begin
return (Controlled with Elements, Left.Last, 0, 0);
@@ -198,13 +198,13 @@ package body Ada.Containers.Vectors is
declare
LE : Elements_Array renames
- Left.Elements.EA (Index_Type'First .. Left.Last);
+ Left.Elements.EA (Index_Type'First .. Left.Last);
RE : Elements_Array renames
- Right.Elements.EA (Index_Type'First .. Right.Last);
+ Right.Elements.EA (Index_Type'First .. Right.Last);
Elements : constant Elements_Access :=
- new Elements_Type'(Last, LE & RE);
+ new Elements_Type'(Last, LE & RE);
begin
return (Controlled with Elements, Last, 0, 0);
@@ -223,9 +223,9 @@ package body Ada.Containers.Vectors is
if Left.Is_Empty then
declare
Elements : constant Elements_Access :=
- new Elements_Type'
- (Last => Index_Type'First,
- EA => (others => Right));
+ new Elements_Type'
+ (Last => Index_Type'First,
+ EA => (others => Right));
begin
return (Controlled with Elements, Index_Type'First, 0, 0);
@@ -253,7 +253,7 @@ package body Ada.Containers.Vectors is
Left.Elements.EA (Index_Type'First .. Left.Last);
Elements : constant Elements_Access :=
- new Elements_Type'(Last => Last, EA => LE & Right);
+ new Elements_Type'(Last => Last, EA => LE & Right);
begin
return (Controlled with Elements, Last, 0, 0);
@@ -272,9 +272,9 @@ package body Ada.Containers.Vectors is
if Right.Is_Empty then
declare
Elements : constant Elements_Access :=
- new Elements_Type'
- (Last => Index_Type'First,
- EA => (others => Left));
+ new Elements_Type'
+ (Last => Index_Type'First,
+ EA => (others => Left));
begin
return (Controlled with Elements, Index_Type'First, 0, 0);
@@ -302,9 +302,9 @@ package body Ada.Containers.Vectors is
Right.Elements.EA (Index_Type'First .. Right.Last);
Elements : constant Elements_Access :=
- new Elements_Type'
- (Last => Last,
- EA => Left & RE);
+ new Elements_Type'
+ (Last => Last,
+ EA => Left & RE);
begin
return (Controlled with Elements, Last, 0, 0);
@@ -332,9 +332,9 @@ package body Ada.Containers.Vectors is
Last : constant Index_Type := Index_Type'First + 1;
Elements : constant Elements_Access :=
- new Elements_Type'
- (Last => Last,
- EA => (Left, Right));
+ new Elements_Type'
+ (Last => Last,
+ EA => (Left, Right));
begin
return (Controlled with Elements, Last, 0, 0);
@@ -519,10 +519,8 @@ package body Ada.Containers.Vectors is
L : Natural renames C.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element =>
- Container.Elements.EA (Position.Index)'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Container.Elements.EA (Position.Index)'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -544,9 +542,8 @@ package body Ada.Containers.Vectors is
L : Natural renames C.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Container.Elements.EA (Index)'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Container.Elements.EA (Index)'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -2253,9 +2250,9 @@ package body Ada.Containers.Vectors is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => V,
- Index => No_Index)
+ (Limited_Controlled with
+ Container => V,
+ Index => No_Index)
do
B := B + 1;
end return;
@@ -2306,9 +2303,9 @@ package body Ada.Containers.Vectors is
-- is a forward or reverse iteration.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => V,
- Index => Start.Index)
+ (Limited_Controlled with
+ Container => V,
+ Index => Start.Index)
do
B := B + 1;
end return;
@@ -2664,9 +2661,8 @@ package body Ada.Containers.Vectors is
L : Natural renames C.Lock;
begin
return R : constant Reference_Type :=
- (Element =>
- Container.Elements.EA (Position.Index)'Access,
- Control => (Controlled with Position.Container))
+ (Element => Container.Elements.EA (Position.Index)'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -2688,9 +2684,8 @@ package body Ada.Containers.Vectors is
L : Natural renames C.Lock;
begin
return R : constant Reference_Type :=
- (Element => Container.Elements.EA (Index)'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Container.Elements.EA (Index)'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -3150,7 +3145,7 @@ package body Ada.Containers.Vectors is
Index : Index_Type := Index_Type'Last) return Extended_Index
is
Last : constant Index_Type'Base :=
- Index_Type'Min (Container.Last, Index);
+ Index_Type'Min (Container.Last, Index);
begin
for Indx in reverse Index_Type'First .. Last loop
diff --git a/gcc/ada/a-coorma.adb b/gcc/ada/a-coorma.adb
index 5aef3636f..aa8fa91a8 100644
--- a/gcc/ada/a-coorma.adb
+++ b/gcc/ada/a-coorma.adb
@@ -360,8 +360,8 @@ package body Ada.Containers.Ordered_Maps is
L : Natural renames T.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -386,9 +386,8 @@ package body Ada.Containers.Ordered_Maps is
L : Natural renames T.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -422,12 +421,12 @@ package body Ada.Containers.Ordered_Maps is
function Copy_Node (Source : Node_Access) return Node_Access is
Target : constant Node_Access :=
- new Node_Type'(Color => Source.Color,
- Key => Source.Key,
- Element => Source.Element,
- Parent => null,
- Left => null,
- Right => null);
+ new Node_Type'(Color => Source.Color,
+ Key => Source.Key,
+ Element => Source.Element,
+ Parent => null,
+ Left => null,
+ Right => null);
begin
return Target;
end Copy_Node;
@@ -946,9 +945,9 @@ package body Ada.Containers.Ordered_Maps is
-- for a reverse iterator, Container.Last is the beginning.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => null)
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null)
do
B := B + 1;
end return;
@@ -994,9 +993,9 @@ package body Ada.Containers.Ordered_Maps is
-- is a forward or reverse iteration.
return It : constant Iterator :=
- (Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node)
+ (Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node)
do
B := B + 1;
end return;
@@ -1132,8 +1131,7 @@ package body Ada.Containers.Ordered_Maps is
"Position cursor of Next is bad");
declare
- Node : constant Node_Access :=
- Tree_Operations.Next (Position.Node);
+ Node : constant Node_Access := Tree_Operations.Next (Position.Node);
begin
if Node = null then
@@ -1190,7 +1188,7 @@ package body Ada.Containers.Ordered_Maps is
declare
Node : constant Node_Access :=
- Tree_Operations.Previous (Position.Node);
+ Tree_Operations.Previous (Position.Node);
begin
if Node = null then
@@ -1355,8 +1353,8 @@ package body Ada.Containers.Ordered_Maps is
L : Natural renames T.Lock;
begin
return R : constant Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control => (Controlled with Position.Container))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Position.Container))
do
B := B + 1;
L := L + 1;
@@ -1381,9 +1379,8 @@ package body Ada.Containers.Ordered_Maps is
L : Natural renames T.Lock;
begin
return R : constant Reference_Type :=
- (Element => Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
diff --git a/gcc/ada/a-coormu.adb b/gcc/ada/a-coormu.adb
index 2bfc682ef..2cc763197 100644
--- a/gcc/ada/a-coormu.adb
+++ b/gcc/ada/a-coormu.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2012, 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- --
@@ -308,7 +308,7 @@ package body Ada.Containers.Ordered_Multisets is
function Ceiling (Container : Set; Item : Element_Type) return Cursor is
Node : constant Node_Access :=
- Element_Keys.Ceiling (Container.Tree, Item);
+ Element_Keys.Ceiling (Container.Tree, Item);
begin
if Node = null then
@@ -365,11 +365,11 @@ package body Ada.Containers.Ordered_Multisets is
function Copy_Node (Source : Node_Access) return Node_Access is
Target : constant Node_Access :=
- new Node_Type'(Parent => null,
- Left => null,
- Right => null,
- Color => Source.Color,
- Element => Source.Element);
+ new Node_Type'(Parent => null,
+ Left => null,
+ Right => null,
+ Color => Source.Color,
+ Element => Source.Element);
begin
return Target;
end Copy_Node;
@@ -464,7 +464,7 @@ package body Ada.Containers.Ordered_Multisets is
function Difference (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Difference (Left.Tree, Right.Tree);
+ Set_Ops.Difference (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Difference;
@@ -568,7 +568,7 @@ package body Ada.Containers.Ordered_Multisets is
function Find (Container : Set; Item : Element_Type) return Cursor is
Node : constant Node_Access :=
- Element_Keys.Find (Container.Tree, Item);
+ Element_Keys.Find (Container.Tree, Item);
begin
if Node = null then
@@ -632,7 +632,7 @@ package body Ada.Containers.Ordered_Multisets is
function Floor (Container : Set; Item : Element_Type) return Cursor is
Node : constant Node_Access :=
- Element_Keys.Floor (Container.Tree, Item);
+ Element_Keys.Floor (Container.Tree, Item);
begin
if Node = null then
@@ -697,7 +697,7 @@ package body Ada.Containers.Ordered_Multisets is
function Ceiling (Container : Set; Key : Key_Type) return Cursor is
Node : constant Node_Access :=
- Key_Keys.Ceiling (Container.Tree, Key);
+ Key_Keys.Ceiling (Container.Tree, Key);
begin
if Node = null then
@@ -746,8 +746,7 @@ package body Ada.Containers.Ordered_Multisets is
-------------
function Element (Container : Set; Key : Key_Type) return Element_Type is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
raise Constraint_Error with "key not in set";
@@ -795,8 +794,7 @@ package body Ada.Containers.Ordered_Multisets is
----------
function Find (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
@@ -811,8 +809,7 @@ package body Ada.Containers.Ordered_Multisets is
-----------
function Floor (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Node_Access :=
- Key_Keys.Floor (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Floor (Container.Tree, Key);
begin
if Node = null then
@@ -1099,11 +1096,11 @@ package body Ada.Containers.Ordered_Multisets is
function New_Node return Node_Access is
Node : constant Node_Access :=
- new Node_Type'(Parent => null,
- Left => null,
- Right => null,
- Color => Red_Black_Trees.Red,
- Element => New_Item);
+ new Node_Type'(Parent => null,
+ Left => null,
+ Right => null,
+ Color => Red_Black_Trees.Red,
+ Element => New_Item);
begin
return Node;
end New_Node;
@@ -1144,11 +1141,11 @@ package body Ada.Containers.Ordered_Multisets is
function New_Node return Node_Access is
Node : constant Node_Access :=
- new Node_Type'(Parent => null,
- Left => null,
- Right => null,
- Color => Red,
- Element => Src_Node.Element);
+ new Node_Type'(Parent => null,
+ Left => null,
+ Right => null,
+ Color => Red,
+ Element => Src_Node.Element);
begin
return Node;
end New_Node;
@@ -1174,7 +1171,7 @@ package body Ada.Containers.Ordered_Multisets is
function Intersection (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Intersection (Left.Tree, Right.Tree);
+ Set_Ops.Intersection (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Intersection;
@@ -1385,7 +1382,7 @@ package body Ada.Containers.Ordered_Multisets is
-- a forward or reverse iteration.
return It : constant Iterator :=
- (Limited_Controlled with S, Start.Node)
+ (Limited_Controlled with S, Start.Node)
do
B := B + 1;
end return;
@@ -1489,8 +1486,7 @@ package body Ada.Containers.Ordered_Multisets is
"bad cursor in Next");
declare
- Node : constant Node_Access :=
- Tree_Operations.Next (Position.Node);
+ Node : constant Node_Access := Tree_Operations.Next (Position.Node);
begin
if Node = null then
return No_Element;
@@ -1553,7 +1549,7 @@ package body Ada.Containers.Ordered_Multisets is
declare
Node : constant Node_Access :=
- Tree_Operations.Previous (Position.Node);
+ Tree_Operations.Previous (Position.Node);
begin
return (if Node = null then No_Element
else Cursor'(Position.Container, Node));
@@ -1884,7 +1880,7 @@ package body Ada.Containers.Ordered_Multisets is
function Symmetric_Difference (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
+ Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Symmetric_Difference;
@@ -1912,8 +1908,7 @@ package body Ada.Containers.Ordered_Multisets is
end Union;
function Union (Left, Right : Set) return Set is
- Tree : constant Tree_Type :=
- Set_Ops.Union (Left.Tree, Right.Tree);
+ Tree : constant Tree_Type := Set_Ops.Union (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Union;
diff --git a/gcc/ada/a-coorse.adb b/gcc/ada/a-coorse.adb
index 600403b1e..f92760f57 100644
--- a/gcc/ada/a-coorse.adb
+++ b/gcc/ada/a-coorse.adb
@@ -319,7 +319,7 @@ package body Ada.Containers.Ordered_Sets is
function Ceiling (Container : Set; Item : Element_Type) return Cursor is
Node : constant Node_Access :=
- Element_Keys.Ceiling (Container.Tree, Item);
+ Element_Keys.Ceiling (Container.Tree, Item);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -373,9 +373,8 @@ package body Ada.Containers.Ordered_Sets is
L : Natural renames Tree.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Position.Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Position.Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -412,11 +411,11 @@ package body Ada.Containers.Ordered_Sets is
function Copy_Node (Source : Node_Access) return Node_Access is
Target : constant Node_Access :=
- new Node_Type'(Parent => null,
- Left => null,
- Right => null,
- Color => Source.Color,
- Element => Source.Element);
+ new Node_Type'(Parent => null,
+ Left => null,
+ Right => null,
+ Color => Source.Color,
+ Element => Source.Element);
begin
return Target;
end Copy_Node;
@@ -493,8 +492,7 @@ package body Ada.Containers.Ordered_Sets is
end Difference;
function Difference (Left, Right : Set) return Set is
- Tree : constant Tree_Type :=
- Set_Ops.Difference (Left.Tree, Right.Tree);
+ Tree : constant Tree_Type := Set_Ops.Difference (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Difference;
@@ -602,8 +600,7 @@ package body Ada.Containers.Ordered_Sets is
----------
function Find (Container : Set; Item : Element_Type) return Cursor is
- Node : constant Node_Access :=
- Element_Keys.Find (Container.Tree, Item);
+ Node : constant Node_Access := Element_Keys.Find (Container.Tree, Item);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -660,8 +657,7 @@ package body Ada.Containers.Ordered_Sets is
-----------
function Floor (Container : Set; Item : Element_Type) return Cursor is
- Node : constant Node_Access :=
- Element_Keys.Floor (Container.Tree, Item);
+ Node : constant Node_Access := Element_Keys.Floor (Container.Tree, Item);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -719,8 +715,7 @@ package body Ada.Containers.Ordered_Sets is
-------------
function Ceiling (Container : Set; Key : Key_Type) return Cursor is
- Node : constant Node_Access :=
- Key_Keys.Ceiling (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Ceiling (Container.Tree, Key);
begin
return (if Node = null then No_Element
else Cursor'(Container'Unrestricted_Access, Node));
@@ -734,8 +729,7 @@ package body Ada.Containers.Ordered_Sets is
(Container : aliased Set;
Key : Key_Type) return Constant_Reference_Type
is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
@@ -748,9 +742,8 @@ package body Ada.Containers.Ordered_Sets is
L : Natural renames Tree.Lock;
begin
return R : constant Constant_Reference_Type :=
- (Element => Node.Element'Access,
- Control =>
- (Controlled with Container'Unrestricted_Access))
+ (Element => Node.Element'Access,
+ Control => (Controlled with Container'Unrestricted_Access))
do
B := B + 1;
L := L + 1;
@@ -788,8 +781,7 @@ package body Ada.Containers.Ordered_Sets is
-------------
function Element (Container : Set; Key : Key_Type) return Element_Type is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
@@ -929,8 +921,7 @@ package body Ada.Containers.Ordered_Sets is
(Container : aliased in out Set;
Key : Key_Type) return Reference_Type
is
- Node : constant Node_Access :=
- Key_Keys.Find (Container.Tree, Key);
+ Node : constant Node_Access := Key_Keys.Find (Container.Tree, Key);
begin
if Node = null then
@@ -1215,7 +1206,7 @@ package body Ada.Containers.Ordered_Sets is
function Intersection (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Intersection (Left.Tree, Right.Tree);
+ Set_Ops.Intersection (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Intersection;
@@ -1343,9 +1334,9 @@ package body Ada.Containers.Ordered_Sets is
B := B + 1;
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => null);
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => null);
end Iterate;
function Iterate (Container : Set; Start : Cursor)
@@ -1390,9 +1381,9 @@ package body Ada.Containers.Ordered_Sets is
B := B + 1;
return It : constant Iterator :=
- Iterator'(Limited_Controlled with
- Container => Container'Unrestricted_Access,
- Node => Start.Node);
+ Iterator'(Limited_Controlled with
+ Container => Container'Unrestricted_Access,
+ Node => Start.Node);
end Iterate;
----------
@@ -1485,7 +1476,7 @@ package body Ada.Containers.Ordered_Sets is
declare
Node : constant Node_Access :=
- Tree_Operations.Next (Position.Node);
+ Tree_Operations.Next (Position.Node);
begin
return (if Node = null then No_Element
else Cursor'(Position.Container, Node));
@@ -1544,7 +1535,7 @@ package body Ada.Containers.Ordered_Sets is
declare
Node : constant Node_Access :=
- Tree_Operations.Previous (Position.Node);
+ Tree_Operations.Previous (Position.Node);
begin
return (if Node = null then No_Element
else Cursor'(Position.Container, Node));
@@ -1670,7 +1661,7 @@ package body Ada.Containers.Ordered_Sets is
procedure Replace (Container : in out Set; New_Item : Element_Type) is
Node : constant Node_Access :=
- Element_Keys.Find (Container.Tree, New_Item);
+ Element_Keys.Find (Container.Tree, New_Item);
begin
if Node = null then
@@ -1899,7 +1890,7 @@ package body Ada.Containers.Ordered_Sets is
function Symmetric_Difference (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
+ Set_Ops.Symmetric_Difference (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Symmetric_Difference;
@@ -1929,7 +1920,7 @@ package body Ada.Containers.Ordered_Sets is
function Union (Left, Right : Set) return Set is
Tree : constant Tree_Type :=
- Set_Ops.Union (Left.Tree, Right.Tree);
+ Set_Ops.Union (Left.Tree, Right.Tree);
begin
return Set'(Controlled with Tree);
end Union;
diff --git a/gcc/ada/a-crdlli.adb b/gcc/ada/a-crdlli.adb
index 137290b11..8d5fe9f5c 100644
--- a/gcc/ada/a-crdlli.adb
+++ b/gcc/ada/a-crdlli.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2004-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2012, 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- --
@@ -562,7 +562,7 @@ package body Ada.Containers.Restricted_Doubly_Linked_Lists is
procedure Sort (Front, Back : Count_Type) is
Pivot : constant Count_Type :=
- (if Front = 0 then Container.First else N (Front).Next);
+ (if Front = 0 then Container.First else N (Front).Next);
begin
if Pivot /= Back then
Partition (Pivot, Back);
diff --git a/gcc/ada/a-direct.adb b/gcc/ada/a-direct.adb
index e166c9f8f..fa95d3c9c 100644
--- a/gcc/ada/a-direct.adb
+++ b/gcc/ada/a-direct.adb
@@ -216,8 +216,7 @@ package body Ada.Directories is
Norm : constant String := Normalize_Pathname (Name);
Last_DS : constant Natural :=
- Strings.Fixed.Index
- (Name, Dir_Seps, Going => Strings.Backward);
+ Strings.Fixed.Index (Name, Dir_Seps, Going => Strings.Backward);
begin
if Last_DS = 0 then
@@ -755,7 +754,7 @@ package body Ada.Directories is
Target => Path_String_Access);
Path_Access : constant Path_String_Access :=
- Address_To_Access (Filename_Addr);
+ Address_To_Access (Filename_Addr);
begin
Last := Filename_Len;
@@ -767,9 +766,7 @@ package body Ada.Directories is
if Match (Name (1 .. Last), Search.Value.Pattern) then
declare
Full_Name : constant String :=
- Compose
- (To_String
- (Search.Value.Name), Name (1 .. Last));
+ Compose (To_String (Search.Value.Name), Name (1 .. Last));
Found : Boolean := False;
begin
@@ -1159,8 +1156,7 @@ package body Ada.Directories is
function Simple_Name_Internal (Path : String) return String is
Cut_Start : Natural :=
- Strings.Fixed.Index
- (Path, Dir_Seps, Going => Strings.Backward);
+ Strings.Fixed.Index (Path, Dir_Seps, Going => Strings.Backward);
Cut_End : Natural;
begin
@@ -1176,7 +1172,7 @@ package body Ada.Directories is
BN : constant String := Path (Cut_Start .. Cut_End);
Has_Drive_Letter : constant Boolean :=
- OS_Lib.Path_Separator /= ':';
+ OS_Lib.Path_Separator /= ':';
-- If Path separator is not ':' then we are on a DOS based OS
-- where this character is used as a drive letter separator.
diff --git a/gcc/ada/a-direio.adb b/gcc/ada/a-direio.adb
index 7a5e5c8e5..b9330b044 100644
--- a/gcc/ada/a-direio.adb
+++ b/gcc/ada/a-direio.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -48,7 +48,7 @@ use type System.Direct_IO.Count;
package body Ada.Direct_IO is
Zeroes : constant System.Storage_Elements.Storage_Array :=
- (1 .. System.Storage_Elements.Storage_Offset (Bytes) => 0);
+ (1 .. System.Storage_Elements.Storage_Offset (Bytes) => 0);
-- Buffer used to fill out partial records
package FCB renames System.File_Control_Block;
diff --git a/gcc/ada/a-dirval-mingw.adb b/gcc/ada/a-dirval-mingw.adb
index d73f56840..205f128cd 100644
--- a/gcc/ada/a-dirval-mingw.adb
+++ b/gcc/ada/a-dirval-mingw.adb
@@ -7,7 +7,7 @@
-- B o d y --
-- (Windows Version) --
-- --
--- Copyright (C) 2004-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2012, 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- --
@@ -37,11 +37,11 @@ with Ada.Characters.Latin_1; use Ada.Characters.Latin_1;
package body Ada.Directories.Validity is
Invalid_Character : constant array (Character) of Boolean :=
- (NUL .. US | '\' => True,
- '/' | ':' | '*' | '?' => True,
- '"' | '<' | '>' | '|' => True,
- DEL .. NBSP => True,
- others => False);
+ (NUL .. US | '\' => True,
+ '/' | ':' | '*' | '?' => True,
+ '"' | '<' | '>' | '|' => True,
+ DEL .. NBSP => True,
+ others => False);
---------------------------------
-- Is_Path_Name_Case_Sensitive --
diff --git a/gcc/ada/a-dirval-vms.adb b/gcc/ada/a-dirval-vms.adb
index 34032b233..c9a08310d 100644
--- a/gcc/ada/a-dirval-vms.adb
+++ b/gcc/ada/a-dirval-vms.adb
@@ -7,7 +7,7 @@
-- B o d y --
-- (VMS Version) --
-- --
--- Copyright (C) 2004-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 2004-2012, 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- --
@@ -38,11 +38,11 @@ package body Ada.Directories.Validity is
Max_Path_Length : constant := 1_024;
Invalid_Character : constant array (Character) of Boolean :=
- ('a' .. 'z' => False,
- 'A' .. 'Z' => False,
- '0' .. '9' => False,
- '_' | '$' | '-' | '.' => False,
- others => True);
+ ('a' .. 'z' => False,
+ 'A' .. 'Z' => False,
+ '0' .. '9' => False,
+ '_' | '$' | '-' | '.' => False,
+ others => True);
---------------------------------
-- Is_Path_Name_Case_Sensitive --
diff --git a/gcc/ada/a-dynpri.adb b/gcc/ada/a-dynpri.adb
index 9116a5739..4e67934b7 100644
--- a/gcc/ada/a-dynpri.adb
+++ b/gcc/ada/a-dynpri.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, Free Software Foundation, Inc. --
-- --
-- GNARL 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- --
@@ -82,7 +82,7 @@ package body Ada.Dynamic_Priorities is
procedure Set_Priority
(Priority : System.Any_Priority;
T : Ada.Task_Identification.Task_Id :=
- Ada.Task_Identification.Current_Task)
+ Ada.Task_Identification.Current_Task)
is
Target : constant Task_Id := Convert_Ids (T);
Error_Message : constant String := "Trying to set the priority of a ";
diff --git a/gcc/ada/a-except-2005.adb b/gcc/ada/a-except-2005.adb
index 4c5f66629..fd3f04b11 100644
--- a/gcc/ada/a-except-2005.adb
+++ b/gcc/ada/a-except-2005.adb
@@ -1009,10 +1009,10 @@ package body Ada.Exceptions is
Prefix : constant String := "adjust/finalize raised ";
Orig_Msg : constant String := Exception_Message (X);
Orig_Prefix_Length : constant Natural :=
- Integer'Min (Prefix'Length, Orig_Msg'Length);
+ Integer'Min (Prefix'Length, Orig_Msg'Length);
Orig_Prefix : String renames Orig_Msg
- (Orig_Msg'First ..
- Orig_Msg'First + Orig_Prefix_Length - 1);
+ (Orig_Msg'First ..
+ Orig_Msg'First + Orig_Prefix_Length - 1);
begin
-- Message already has the proper prefix, just re-raise
@@ -1446,9 +1446,9 @@ package body Ada.Exceptions is
(File : System.Address; Line, Column, Index, First, Last : Integer)
is
Msg : constant String :=
- Rmsg_05 (Rmsg_05'First .. Rmsg_05'Last - 1) & ASCII.LF &
- "index " & Image (Index) & " not in " & Image (First) &
- ".." & Image (Last) & ASCII.NUL;
+ Rmsg_05 (Rmsg_05'First .. Rmsg_05'Last - 1) & ASCII.LF &
+ "index " & Image (Index) & " not in " & Image (First) &
+ ".." & Image (Last) & ASCII.NUL;
begin
Raise_Constraint_Error_Msg (File, Line, Column, Msg'Address);
end Rcheck_CE_Index_Check_Ext;
@@ -1457,9 +1457,9 @@ package body Ada.Exceptions is
(File : System.Address; Line, Column, Index, First, Last : Integer)
is
Msg : constant String :=
- Rmsg_06 (Rmsg_06'First .. Rmsg_06'Last - 1) & ASCII.LF &
- "value " & Image (Index) & " not in " & Image (First) &
- ".." & Image (Last) & ASCII.NUL;
+ Rmsg_06 (Rmsg_06'First .. Rmsg_06'Last - 1) & ASCII.LF &
+ "value " & Image (Index) & " not in " & Image (First) &
+ ".." & Image (Last) & ASCII.NUL;
begin
Raise_Constraint_Error_Msg (File, Line, Column, Msg'Address);
end Rcheck_CE_Invalid_Data_Ext;
@@ -1468,9 +1468,9 @@ package body Ada.Exceptions is
(File : System.Address; Line, Column, Index, First, Last : Integer)
is
Msg : constant String :=
- Rmsg_12 (Rmsg_12'First .. Rmsg_12'Last - 1) & ASCII.LF &
- "value " & Image (Index) & " not in " & Image (First) &
- ".." & Image (Last) & ASCII.NUL;
+ Rmsg_12 (Rmsg_12'First .. Rmsg_12'Last - 1) & ASCII.LF &
+ "value " & Image (Index) & " not in " & Image (First) &
+ ".." & Image (Last) & ASCII.NUL;
begin
Raise_Constraint_Error_Msg (File, Line, Column, Msg'Address);
end Rcheck_CE_Range_Check_Ext;
diff --git a/gcc/ada/a-except.adb b/gcc/ada/a-except.adb
index 3d3ba615c..3dae9c4dd 100644
--- a/gcc/ada/a-except.adb
+++ b/gcc/ada/a-except.adb
@@ -1026,10 +1026,9 @@ package body Ada.Exceptions is
Prefix : constant String := "adjust/finalize raised ";
Orig_Msg : constant String := Exception_Message (X);
Orig_Prefix_Length : constant Natural :=
- Integer'Min (Prefix'Length, Orig_Msg'Length);
+ Integer'Min (Prefix'Length, Orig_Msg'Length);
Orig_Prefix : String renames Orig_Msg
- (Orig_Msg'First ..
- Orig_Msg'First + Orig_Prefix_Length - 1);
+ (Orig_Msg'First .. Orig_Msg'First + Orig_Prefix_Length - 1);
begin
-- Message already has proper prefix, just re-reraise
diff --git a/gcc/ada/a-exetim-mingw.adb b/gcc/ada/a-exetim-mingw.adb
index c80d11286..b6919f268 100644
--- a/gcc/ada/a-exetim-mingw.adb
+++ b/gcc/ada/a-exetim-mingw.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2007-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2007-2012, 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- --
@@ -91,7 +91,7 @@ package body Ada.Execution_Time is
function Clock
(T : Ada.Task_Identification.Task_Id :=
- Ada.Task_Identification.Current_Task) return CPU_Time
+ Ada.Task_Identification.Current_Task) return CPU_Time
is
Hundreds_Nano_In_Sec : constant Long_Long_Float := 1.0E7;
diff --git a/gcc/ada/a-exetim-posix.adb b/gcc/ada/a-exetim-posix.adb
index 094f2aab5..9dc709ac6 100644
--- a/gcc/ada/a-exetim-posix.adb
+++ b/gcc/ada/a-exetim-posix.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2007-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2007-2012, 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- --
@@ -95,8 +95,7 @@ package body Ada.Execution_Time is
function Clock
(T : Ada.Task_Identification.Task_Id :=
- Ada.Task_Identification.Current_Task)
- return CPU_Time
+ Ada.Task_Identification.Current_Task) return CPU_Time
is
TS : aliased timespec;
Result : Interfaces.C.int;
diff --git a/gcc/ada/a-exexda.adb b/gcc/ada/a-exexda.adb
index aa91cdcfe..85b519a5e 100644
--- a/gcc/ada/a-exexda.adb
+++ b/gcc/ada/a-exexda.adb
@@ -220,7 +220,7 @@ package body Exception_Data is
N : Integer_Address;
H : constant array (Integer range 0 .. 15) of Character :=
- "0123456789abcdef";
+ "0123456789abcdef";
begin
P := S'Last;
N := To_Integer (A);
@@ -659,7 +659,7 @@ package body Exception_Data is
Message : String)
is
Len : constant Natural :=
- Natural'Min (Message'Length, Exception_Msg_Max_Length);
+ Natural'Min (Message'Length, Exception_Msg_Max_Length);
First : constant Integer := Message'First;
begin
Excep.Exception_Raised := False;
@@ -689,7 +689,7 @@ package body Exception_Data is
-- call become inoffensive.
Wrapper : constant Traceback_Decorator_Wrapper_Call :=
- Traceback_Decorator_Wrapper;
+ Traceback_Decorator_Wrapper;
begin
if Wrapper = null then
diff --git a/gcc/ada/a-exexpr-gcc.adb b/gcc/ada/a-exexpr-gcc.adb
index e62ffd2ef..178b7e375 100644
--- a/gcc/ada/a-exexpr-gcc.adb
+++ b/gcc/ada/a-exexpr-gcc.adb
@@ -356,7 +356,7 @@ package body Exception_Propagation is
declare
GNAT_Occurrence : constant GNAT_GCC_Exception_Access :=
- To_GNAT_GCC_Exception (GCC_Exception);
+ To_GNAT_GCC_Exception (GCC_Exception);
begin
Excep.all := GNAT_Occurrence.Occurrence;
diff --git a/gcc/ada/a-ngcoar.adb b/gcc/ada/a-ngcoar.adb
index 3be88491d..ca0c58c36 100644
--- a/gcc/ada/a-ngcoar.adb
+++ b/gcc/ada/a-ngcoar.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2006-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2006-2012, 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- --
@@ -1073,7 +1073,7 @@ package body Ada.Numerics.Generic_Complex_Arrays is
for K in 1 .. N loop
declare
C : constant Complex :=
- (A (A'First (1) + (J - 1), A'First (2) + (K - 1)));
+ (A (A'First (1) + (J - 1), A'First (2) + (K - 1)));
begin
M (J, K) := Re (C);
M (J + N, K + N) := Re (C);
@@ -1120,7 +1120,7 @@ package body Ada.Numerics.Generic_Complex_Arrays is
for K in 1 .. N loop
declare
C : constant Complex :=
- (A (A'First (1) + (J - 1), A'First (2) + (K - 1)));
+ (A (A'First (1) + (J - 1), A'First (2) + (K - 1)));
begin
M (J, K) := Re (C);
M (J + N, K + N) := Re (C);
diff --git a/gcc/ada/a-ngelfu.adb b/gcc/ada/a-ngelfu.adb
index cd426ca75..796f57415 100644
--- a/gcc/ada/a-ngelfu.adb
+++ b/gcc/ada/a-ngelfu.adb
@@ -971,7 +971,7 @@ package body Ada.Numerics.Generic_Elementary_Functions is
G : constant Float_Type'Base := Y * Y;
Float_Type_Digits_15_Or_More : constant Boolean :=
- Float_Type'Digits > 14;
+ Float_Type'Digits > 14;
begin
if X < Half_Log_Epsilon then
diff --git a/gcc/ada/a-sequio.adb b/gcc/ada/a-sequio.adb
index f0a51417a..397a778f3 100644
--- a/gcc/ada/a-sequio.adb
+++ b/gcc/ada/a-sequio.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -182,7 +182,7 @@ package body Ada.Sequential_IO is
then
declare
RsizS : constant SSE.Storage_Offset :=
- SSE.Storage_Offset (Rsiz - 1);
+ SSE.Storage_Offset (Rsiz - 1);
type SA is new SSE.Storage_Array (0 .. RsizS);
diff --git a/gcc/ada/a-strfix.adb b/gcc/ada/a-strfix.adb
index 0f3395899..69c0650df 100644
--- a/gcc/ada/a-strfix.adb
+++ b/gcc/ada/a-strfix.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -434,9 +434,9 @@ package body Ada.Strings.Fixed is
declare
Result_Length : constant Natural :=
- Integer'Max
- (Source'Length,
- Position - Source'First + New_Item'Length);
+ Integer'Max
+ (Source'Length,
+ Position - Source'First + New_Item'Length);
Result : String (1 .. Result_Length);
Front : constant Integer := Position - Source'First;
@@ -482,15 +482,15 @@ package body Ada.Strings.Fixed is
if High >= Low then
declare
Front_Len : constant Integer :=
- Integer'Max (0, Low - Source'First);
+ Integer'Max (0, Low - Source'First);
-- Length of prefix of Source copied to result
Back_Len : constant Integer :=
- Integer'Max (0, Source'Last - High);
+ Integer'Max (0, Source'Last - High);
-- Length of suffix of Source copied to result
Result_Length : constant Integer :=
- Front_Len + By'Length + Back_Len;
+ Front_Len + By'Length + Back_Len;
-- Length of result
Result : String (1 .. Result_Length);
diff --git a/gcc/ada/a-strunb-shared.adb b/gcc/ada/a-strunb-shared.adb
index 0ba9bd142..dac8d235d 100644
--- a/gcc/ada/a-strunb-shared.adb
+++ b/gcc/ada/a-strunb-shared.adb
@@ -486,7 +486,7 @@ package body Ada.Strings.Unbounded is
function Aligned_Max_Length (Max_Length : Natural) return Natural is
Static_Size : constant Natural :=
- Empty_Shared_String'Size / Standard'Storage_Unit;
+ Empty_Shared_String'Size / Standard'Storage_Unit;
-- Total size of all static components
begin
diff --git a/gcc/ada/a-strunb.adb b/gcc/ada/a-strunb.adb
index eae34bee8..b4c3cddf9 100644
--- a/gcc/ada/a-strunb.adb
+++ b/gcc/ada/a-strunb.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -785,14 +785,13 @@ package body Ada.Strings.Unbounded is
if Chunk_Size > S_Length - Source.Last then
declare
New_Size : constant Positive :=
- S_Length + Chunk_Size + (S_Length / Growth_Factor);
+ S_Length + Chunk_Size + (S_Length / Growth_Factor);
New_Rounded_Up_Size : constant Positive :=
- ((New_Size - 1) / Min_Mul_Alloc + 1) *
- Min_Mul_Alloc;
+ ((New_Size - 1) / Min_Mul_Alloc + 1) * Min_Mul_Alloc;
Tmp : constant String_Access :=
- new String (1 .. New_Rounded_Up_Size);
+ new String (1 .. New_Rounded_Up_Size);
begin
Tmp (1 .. Source.Last) := Source.Reference (1 .. Source.Last);
diff --git a/gcc/ada/a-stwifi.adb b/gcc/ada/a-stwifi.adb
index afb443de3..dfe961995 100644
--- a/gcc/ada/a-stwifi.adb
+++ b/gcc/ada/a-stwifi.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -411,9 +411,9 @@ package body Ada.Strings.Wide_Fixed is
else
declare
Result_Length : constant Natural :=
- Natural'Max
- (Source'Length,
- Position - Source'First + New_Item'Length);
+ Natural'Max
+ (Source'Length,
+ Position - Source'First + New_Item'Length);
Result : Wide_String (1 .. Result_Length);
@@ -455,15 +455,14 @@ package body Ada.Strings.Wide_Fixed is
if High >= Low then
declare
Front_Len : constant Integer :=
- Integer'Max (0, Low - Source'First);
+ Integer'Max (0, Low - Source'First);
-- Length of prefix of Source copied to result
- Back_Len : constant Integer :=
- Integer'Max (0, Source'Last - High);
+ Back_Len : constant Integer := Integer'Max (0, Source'Last - High);
-- Length of suffix of Source copied to result
Result_Length : constant Integer :=
- Front_Len + By'Length + Back_Len;
+ Front_Len + By'Length + Back_Len;
-- Length of result
Result : Wide_String (1 .. Result_Length);
@@ -622,7 +621,7 @@ package body Ada.Strings.Wide_Fixed is
else
declare
Result : constant Wide_String (1 .. High - Low + 1) :=
- Source (Low .. High);
+ Source (Low .. High);
begin
return Result;
diff --git a/gcc/ada/a-stwiun-shared.adb b/gcc/ada/a-stwiun-shared.adb
index 731be43bf..6c3be5408 100644
--- a/gcc/ada/a-stwiun-shared.adb
+++ b/gcc/ada/a-stwiun-shared.adb
@@ -486,11 +486,11 @@ package body Ada.Strings.Wide_Unbounded is
function Aligned_Max_Length (Max_Length : Natural) return Natural is
Static_Size : constant Natural :=
- Empty_Shared_Wide_String'Size / Standard'Storage_Unit;
+ Empty_Shared_Wide_String'Size / Standard'Storage_Unit;
-- Total size of all static components
Element_Size : constant Natural :=
- Wide_Character'Size / Standard'Storage_Unit;
+ Wide_Character'Size / Standard'Storage_Unit;
begin
return
diff --git a/gcc/ada/a-stwiun.adb b/gcc/ada/a-stwiun.adb
index 77e427f92..06f9d3691 100644
--- a/gcc/ada/a-stwiun.adb
+++ b/gcc/ada/a-stwiun.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -802,14 +802,13 @@ package body Ada.Strings.Wide_Unbounded is
if Chunk_Size > S_Length - Source.Last then
declare
New_Size : constant Positive :=
- S_Length + Chunk_Size + (S_Length / Growth_Factor);
+ S_Length + Chunk_Size + (S_Length / Growth_Factor);
New_Rounded_Up_Size : constant Positive :=
- ((New_Size - 1) / Min_Mul_Alloc + 1) *
- Min_Mul_Alloc;
+ ((New_Size - 1) / Min_Mul_Alloc + 1) * Min_Mul_Alloc;
Tmp : constant Wide_String_Access :=
- new Wide_String (1 .. New_Rounded_Up_Size);
+ new Wide_String (1 .. New_Rounded_Up_Size);
begin
Tmp (1 .. Source.Last) := Source.Reference (1 .. Source.Last);
diff --git a/gcc/ada/a-stzfix.adb b/gcc/ada/a-stzfix.adb
index 67c2fe56c..9176d400e 100644
--- a/gcc/ada/a-stzfix.adb
+++ b/gcc/ada/a-stzfix.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -43,7 +43,7 @@ package body Ada.Strings.Wide_Wide_Fixed is
Pattern : Wide_Wide_String;
Going : Direction := Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
+ Wide_Wide_Maps.Identity)
return Natural
renames Ada.Strings.Wide_Wide_Search.Index;
@@ -68,7 +68,7 @@ package body Ada.Strings.Wide_Wide_Fixed is
From : Positive;
Going : Direction := Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
+ Wide_Wide_Maps.Identity)
return Natural
renames Ada.Strings.Wide_Wide_Search.Index;
@@ -104,7 +104,7 @@ package body Ada.Strings.Wide_Wide_Fixed is
(Source : Wide_Wide_String;
Pattern : Wide_Wide_String;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
+ Wide_Wide_Maps.Identity)
return Natural
renames Ada.Strings.Wide_Wide_Search.Count;
@@ -413,9 +413,9 @@ package body Ada.Strings.Wide_Wide_Fixed is
else
declare
Result_Length : constant Natural :=
- Natural'Max
- (Source'Length,
- Position - Source'First + New_Item'Length);
+ Natural'Max
+ (Source'Length,
+ Position - Source'First + New_Item'Length);
Result : Wide_Wide_String (1 .. Result_Length);
@@ -457,15 +457,15 @@ package body Ada.Strings.Wide_Wide_Fixed is
if High >= Low then
declare
Front_Len : constant Integer :=
- Integer'Max (0, Low - Source'First);
+ Integer'Max (0, Low - Source'First);
-- Length of prefix of Source copied to result
Back_Len : constant Integer :=
- Integer'Max (0, Source'Last - High);
+ Integer'Max (0, Source'Last - High);
-- Length of suffix of Source copied to result
Result_Length : constant Integer :=
- Front_Len + By'Length + Back_Len;
+ Front_Len + By'Length + Back_Len;
-- Length of result
Result : Wide_Wide_String (1 .. Result_Length);
@@ -626,7 +626,7 @@ package body Ada.Strings.Wide_Wide_Fixed is
else
declare
Result : constant Wide_Wide_String (1 .. High - Low + 1) :=
- Source (Low .. High);
+ Source (Low .. High);
begin
return Result;
diff --git a/gcc/ada/a-stzsea.adb b/gcc/ada/a-stzsea.adb
index e745091f6..31285fb26 100644
--- a/gcc/ada/a-stzsea.adb
+++ b/gcc/ada/a-stzsea.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -71,8 +71,7 @@ package body Ada.Strings.Wide_Wide_Search is
(Source : Wide_Wide_String;
Pattern : Wide_Wide_String;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
PL1 : constant Integer := Pattern'Length - 1;
Num : Natural;
@@ -267,8 +266,7 @@ package body Ada.Strings.Wide_Wide_Search is
Pattern : Wide_Wide_String;
Going : Direction := Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
PL1 : constant Integer := Pattern'Length - 1;
Cur : Natural;
@@ -479,8 +477,7 @@ package body Ada.Strings.Wide_Wide_Search is
From : Positive;
Going : Direction := Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
begin
if Going = Forward then
diff --git a/gcc/ada/a-stzsup.adb b/gcc/ada/a-stzsup.adb
index a79dfa0cc..d197a8fb7 100644
--- a/gcc/ada/a-stzsup.adb
+++ b/gcc/ada/a-stzsup.adb
@@ -698,8 +698,7 @@ package body Ada.Strings.Wide_Wide_Superbounded is
(Source : Super_String;
Pattern : Wide_Wide_String;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
begin
return
@@ -939,8 +938,7 @@ package body Ada.Strings.Wide_Wide_Superbounded is
Pattern : Wide_Wide_String;
Going : Strings.Direction := Strings.Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
begin
return Wide_Wide_Search.Index
@@ -976,8 +974,7 @@ package body Ada.Strings.Wide_Wide_Superbounded is
From : Positive;
Going : Direction := Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
begin
return Wide_Wide_Search.Index
diff --git a/gcc/ada/a-stzunb-shared.adb b/gcc/ada/a-stzunb-shared.adb
index 9ec5d4764..37ab29536 100644
--- a/gcc/ada/a-stzunb-shared.adb
+++ b/gcc/ada/a-stzunb-shared.adb
@@ -486,12 +486,11 @@ package body Ada.Strings.Wide_Wide_Unbounded is
function Aligned_Max_Length (Max_Length : Natural) return Natural is
Static_Size : constant Natural :=
- Empty_Shared_Wide_Wide_String'Size
- / Standard'Storage_Unit;
+ Empty_Shared_Wide_Wide_String'Size / Standard'Storage_Unit;
-- Total size of all static components
Element_Size : constant Natural :=
- Wide_Wide_Character'Size / Standard'Storage_Unit;
+ Wide_Wide_Character'Size / Standard'Storage_Unit;
begin
return
@@ -645,8 +644,7 @@ package body Ada.Strings.Wide_Wide_Unbounded is
(Source : Unbounded_Wide_Wide_String;
Pattern : Wide_Wide_String;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
SR : constant Shared_Wide_Wide_String_Access := Source.Reference;
begin
@@ -975,8 +973,7 @@ package body Ada.Strings.Wide_Wide_Unbounded is
Pattern : Wide_Wide_String;
Going : Strings.Direction := Strings.Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
SR : constant Shared_Wide_Wide_String_Access := Source.Reference;
begin
@@ -1014,8 +1011,7 @@ package body Ada.Strings.Wide_Wide_Unbounded is
From : Positive;
Going : Direction := Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
SR : constant Shared_Wide_Wide_String_Access := Source.Reference;
begin
diff --git a/gcc/ada/a-stzunb.adb b/gcc/ada/a-stzunb.adb
index 82dae6f88..267df9e69 100644
--- a/gcc/ada/a-stzunb.adb
+++ b/gcc/ada/a-stzunb.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -404,8 +404,7 @@ package body Ada.Strings.Wide_Wide_Unbounded is
(Source : Unbounded_Wide_Wide_String;
Pattern : Wide_Wide_String;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
begin
return
@@ -596,8 +595,7 @@ package body Ada.Strings.Wide_Wide_Unbounded is
Pattern : Wide_Wide_String;
Going : Strings.Direction := Strings.Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
begin
return
@@ -635,8 +633,7 @@ package body Ada.Strings.Wide_Wide_Unbounded is
From : Positive;
Going : Direction := Forward;
Mapping : Wide_Wide_Maps.Wide_Wide_Character_Mapping :=
- Wide_Wide_Maps.Identity)
- return Natural
+ Wide_Wide_Maps.Identity) return Natural
is
begin
return
@@ -813,14 +810,13 @@ package body Ada.Strings.Wide_Wide_Unbounded is
if Chunk_Size > S_Length - Source.Last then
declare
New_Size : constant Positive :=
- S_Length + Chunk_Size + (S_Length / Growth_Factor);
+ S_Length + Chunk_Size + (S_Length / Growth_Factor);
New_Rounded_Up_Size : constant Positive :=
- ((New_Size - 1) / Min_Mul_Alloc + 1) *
- Min_Mul_Alloc;
+ ((New_Size - 1) / Min_Mul_Alloc + 1) * Min_Mul_Alloc;
Tmp : constant Wide_Wide_String_Access :=
- new Wide_Wide_String (1 .. New_Rounded_Up_Size);
+ new Wide_Wide_String (1 .. New_Rounded_Up_Size);
begin
Tmp (1 .. Source.Last) := Source.Reference (1 .. Source.Last);
diff --git a/gcc/ada/a-tags.adb b/gcc/ada/a-tags.adb
index 4731bb909..d45c37861 100644
--- a/gcc/ada/a-tags.adb
+++ b/gcc/ada/a-tags.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -139,13 +139,13 @@ package body Ada.Tags is
function CW_Membership (Obj_Tag : Tag; Typ_Tag : Tag) return Boolean is
Obj_TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (Obj_Tag) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (Obj_Tag) - DT_Typeinfo_Ptr_Size);
Typ_TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (Typ_Tag) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (Typ_Tag) - DT_Typeinfo_Ptr_Size);
Obj_TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (Obj_TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (Obj_TSD_Ptr.all);
Typ_TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (Typ_TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (Typ_TSD_Ptr.all);
Pos : constant Integer := Obj_TSD.Idepth - Typ_TSD.Idepth;
begin
return Pos >= 0 and then Obj_TSD.Tags_Table (Pos) = Typ_Tag;
@@ -157,9 +157,9 @@ package body Ada.Tags is
function Get_External_Tag (T : Tag) return System.Address is
TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (TSD_Ptr.all);
begin
return To_Address (TSD.External_Tag);
end Get_External_Tag;
@@ -179,7 +179,7 @@ package body Ada.Tags is
function OSD (T : Tag) return Object_Specific_Data_Ptr is
OSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
begin
return To_Object_Specific_Data_Ptr (OSD_Ptr.all);
end OSD;
@@ -190,9 +190,9 @@ package body Ada.Tags is
function SSD (T : Tag) return Select_Specific_Data_Ptr is
TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (TSD_Ptr.all);
begin
return TSD.SSD;
end SSD;
@@ -260,9 +260,9 @@ package body Ada.Tags is
function Get_HT_Link (T : Tag) return Tag is
TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (TSD_Ptr.all);
begin
return TSD.HT_Link.all;
end Get_HT_Link;
@@ -285,9 +285,9 @@ package body Ada.Tags is
procedure Set_HT_Link (T : Tag; Next : Tag) is
TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (TSD_Ptr.all);
begin
TSD.HT_Link.all := Next;
end Set_HT_Link;
@@ -419,7 +419,7 @@ package body Ada.Tags is
function DT (T : Tag) return Dispatch_Table_Ptr is
Offset : constant SSE.Storage_Offset :=
- To_Dispatch_Table_Ptr (T).Prims_Ptr'Position;
+ To_Dispatch_Table_Ptr (T).Prims_Ptr'Position;
begin
return To_Dispatch_Table_Ptr (To_Address (T) - Offset);
end DT;
@@ -562,9 +562,9 @@ 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);
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (TSD_Ptr.all);
Iface_Table : constant Interface_Data_Ptr := TSD.Interfaces_Table;
begin
@@ -612,7 +612,7 @@ package body Ada.Tags is
then
declare
Addr_First : constant Natural :=
- External'First + Internal_Tag_Header'Length;
+ External'First + Internal_Tag_Header'Length;
Addr_Last : Natural;
Addr : Integer_Address;
@@ -718,14 +718,13 @@ package body Ada.Tags is
Ancestor : Tag) return Boolean
is
D_TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (Descendant)
- - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (Descendant) - DT_Typeinfo_Ptr_Size);
A_TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (Ancestor) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (Ancestor) - DT_Typeinfo_Ptr_Size);
D_TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (D_TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (D_TSD_Ptr.all);
A_TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (A_TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (A_TSD_Ptr.all);
begin
return CW_Membership (Descendant, Ancestor)
@@ -782,9 +781,9 @@ package body Ada.Tags is
function Needs_Finalization (T : Tag) return Boolean is
TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (TSD_Ptr.all);
begin
return TSD.Needs_Finalization;
end Needs_Finalization;
@@ -802,17 +801,16 @@ package body Ada.Tags is
-- ancestor tags.
TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (T) - DT_Typeinfo_Ptr_Size);
TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (TSD_Ptr.all);
-- Pointer to the TSD
Parent_Tag : constant Tag := TSD.Tags_Table (Parent_Slot);
Parent_TSD_Ptr : constant Addr_Ptr :=
- To_Addr_Ptr (To_Address (Parent_Tag)
- - DT_Typeinfo_Ptr_Size);
+ To_Addr_Ptr (To_Address (Parent_Tag) - DT_Typeinfo_Ptr_Size);
Parent_TSD : constant Type_Specific_Data_Ptr :=
- To_Type_Specific_Data_Ptr (Parent_TSD_Ptr.all);
+ To_Type_Specific_Data_Ptr (Parent_TSD_Ptr.all);
begin
-- Here we compute the size of the _parent field of the object
diff --git a/gcc/ada/a-teioed.adb b/gcc/ada/a-teioed.adb
index cfe64c3b6..2bb1435a8 100644
--- a/gcc/ada/a-teioed.adb
+++ b/gcc/ada/a-teioed.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -932,7 +932,7 @@ package body Ada.Text_IO.Editing is
function Pic_String (Pic : Picture) return String is
Temp : String (1 .. Pic.Contents.Picture.Length) :=
- Pic.Contents.Picture.Expanded;
+ Pic.Contents.Picture.Expanded;
begin
for J in Temp'Range loop
if Temp (J) = 'b' then
diff --git a/gcc/ada/a-textio.adb b/gcc/ada/a-textio.adb
index 28e5541ab..2f2fe27c6 100644
--- a/gcc/ada/a-textio.adb
+++ b/gcc/ada/a-textio.adb
@@ -2118,8 +2118,7 @@ package body Ada.Text_IO is
end Has_Translated_Characters;
Needs_Binary_Write : constant Boolean :=
- text_translation_required
- and then Has_Translated_Characters;
+ text_translation_required and then Has_Translated_Characters;
-- Start of processing for Write
diff --git a/gcc/ada/a-tifiio.adb b/gcc/ada/a-tifiio.adb
index 82aeb8a83..ff4bb2c4e 100644
--- a/gcc/ada/a-tifiio.adb
+++ b/gcc/ada/a-tifiio.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -290,10 +290,9 @@ package body Ada.Text_IO.Fixed_IO is
and then Num'Small * 10.0**Scale < 10.0);
Exact : constant Boolean :=
- Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
- or else Float'Floor (1.0 / Num'Small) =
- Float'Ceiling (1.0 / Num'Small)
- or else Num'Small >= 10.0**Max_Digits;
+ Float'Floor (Num'Small) = Float'Ceiling (Num'Small)
+ or else Float'Floor (1.0 / Num'Small) = Float'Ceiling (1.0 / Num'Small)
+ or else Num'Small >= 10.0**Max_Digits;
-- True iff a numerator and denominator can be calculated such that
-- their ratio exactly represents the small of Num.
@@ -387,11 +386,11 @@ package body Ada.Text_IO.Fixed_IO is
Exp : Field := Default_Exp)
is
Fore : constant Integer :=
- To'Length
- - 1 -- Decimal point
- - Field'Max (1, Aft) -- Decimal part
- - Boolean'Pos (Exp /= 0) -- Exponent indicator
- - Exp; -- Exponent
+ To'Length
+ - 1 -- Decimal point
+ - Field'Max (1, Aft) -- Decimal part
+ - Boolean'Pos (Exp /= 0) -- Exponent indicator
+ - Exp; -- Exponent
Last : Natural;
diff --git a/gcc/ada/a-wtedit.adb b/gcc/ada/a-wtedit.adb
index cc41dc1cd..921c0afc1 100644
--- a/gcc/ada/a-wtedit.adb
+++ b/gcc/ada/a-wtedit.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -1090,7 +1090,7 @@ package body Ada.Wide_Text_IO.Editing is
function Pic_String (Pic : Picture) return String is
Temp : String (1 .. Pic.Contents.Picture.Length) :=
- Pic.Contents.Picture.Expanded;
+ Pic.Contents.Picture.Expanded;
begin
for J in Temp'Range loop
if Temp (J) = 'b' then
diff --git a/gcc/ada/a-wtenau.adb b/gcc/ada/a-wtenau.adb
index 44658bc74..d09306bb7 100644
--- a/gcc/ada/a-wtenau.adb
+++ b/gcc/ada/a-wtenau.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -152,7 +152,7 @@ package body Ada.Wide_Text_IO.Enumeration_Aux is
Set : Type_Set)
is
Actual_Width : constant Integer :=
- Integer'Max (Integer (Width), Item'Length);
+ Integer'Max (Integer (Width), Item'Length);
begin
Check_On_One_Line (TFT (File), Actual_Width);
diff --git a/gcc/ada/a-ztedit.adb b/gcc/ada/a-ztedit.adb
index 9b5036a4d..6d97f61ff 100644
--- a/gcc/ada/a-ztedit.adb
+++ b/gcc/ada/a-ztedit.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -1091,7 +1091,7 @@ package body Ada.Wide_Wide_Text_IO.Editing is
function Pic_String (Pic : Picture) return String is
Temp : String (1 .. Pic.Contents.Picture.Length) :=
- Pic.Contents.Picture.Expanded;
+ Pic.Contents.Picture.Expanded;
begin
for J in Temp'Range loop
if Temp (J) = 'b' then
diff --git a/gcc/ada/a-ztenau.adb b/gcc/ada/a-ztenau.adb
index c5776366b..8df795e68 100644
--- a/gcc/ada/a-ztenau.adb
+++ b/gcc/ada/a-ztenau.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -153,7 +153,7 @@ package body Ada.Wide_Wide_Text_IO.Enumeration_Aux is
Set : Type_Set)
is
Actual_Width : constant Integer :=
- Integer'Max (Integer (Width), Item'Length);
+ Integer'Max (Integer (Width), Item'Length);
begin
Check_On_One_Line (TFT (File), Actual_Width);
diff --git a/gcc/ada/aspects.ads b/gcc/ada/aspects.ads
index ebe71aec0..3b4ebcedf 100644
--- a/gcc/ada/aspects.ads
+++ b/gcc/ada/aspects.ads
@@ -95,7 +95,7 @@ package Aspects is
Aspect_Implicit_Dereference,
Aspect_Input,
Aspect_Interrupt_Priority,
- Aspect_Invariant,
+ Aspect_Invariant, -- GNAT
Aspect_Iterator_Element,
Aspect_Link_Name,
Aspect_Machine_Radix,
@@ -191,11 +191,12 @@ package Aspects is
-- The following array indicates aspects that accept 'Class
Class_Aspect_OK : constant array (Aspect_Id) of Boolean :=
- (Aspect_Invariant => True,
- Aspect_Pre => True,
- Aspect_Predicate => True,
- Aspect_Post => True,
- others => False);
+ (Aspect_Invariant => True,
+ Aspect_Pre => True,
+ Aspect_Predicate => True,
+ Aspect_Post => True,
+ Aspect_Type_Invariant => True,
+ others => False);
-- The following array indicates aspects that a subtype inherits from
-- its base type. True means that the subtype inherits the aspect from
diff --git a/gcc/ada/back_end.adb b/gcc/ada/back_end.adb
index fa7c54d2f..aa398ff31 100644
--- a/gcc/ada/back_end.adb
+++ b/gcc/ada/back_end.adb
@@ -76,6 +76,7 @@ package body Back_End is
type File_Info_Type is record
File_Name : File_Name_Type;
+ Instance : Instance_Id;
Num_Source_Lines : Nat;
end record;
@@ -119,6 +120,7 @@ package body Back_End is
for J in 1 .. Last_Source_File loop
File_Info_Array (J).File_Name := Full_Debug_Name (J);
+ File_Info_Array (J).Instance := Instance (J);
File_Info_Array (J).Num_Source_Lines :=
Nat (Physical_To_Logical (Last_Source_Line (J), J));
end loop;
@@ -243,6 +245,12 @@ package body Back_End is
elsif Switch_Chars (First .. Last) = "fdump-scos" then
Opt.Generate_SCO := True;
+ -- Back end switch -fdebug-instances also enables instance table
+ -- SCO generation.
+
+ elsif Switch_Chars (First .. Last) = "fdebug-instances" then
+ Opt.Generate_SCO_Instance_Table := True;
+
end if;
end if;
end Scan_Back_End_Switches;
@@ -266,7 +274,7 @@ package body Back_End is
Argv_Ptr : constant Big_String_Ptr := save_argv (Arg);
Argv_Len : constant Nat := Len_Arg (Arg);
Argv : constant String :=
- Argv_Ptr (1 .. Natural (Argv_Len));
+ Argv_Ptr (1 .. Natural (Argv_Len));
begin
Args (Positive (Arg)) := new String'(Argv);
end;
diff --git a/gcc/ada/bcheck.adb b/gcc/ada/bcheck.adb
index 796627e0d..2efe6da9d 100644
--- a/gcc/ada/bcheck.adb
+++ b/gcc/ada/bcheck.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -280,7 +280,7 @@ package body Bcheck is
Check_Policy : declare
Policy : constant Character :=
- ALIs.Table (A1).Task_Dispatching_Policy;
+ ALIs.Table (A1).Task_Dispatching_Policy;
begin
for A2 in A1 + 1 .. ALIs.Last loop
@@ -337,10 +337,10 @@ package body Bcheck is
end record;
PSD_Table : array (0 .. Max_Prio) of Specific_Dispatching_Entry :=
- (others => Specific_Dispatching_Entry'
- (Dispatching_Policy => ' ',
- Afile => No_ALI_Id,
- Loc => 0));
+ (others => Specific_Dispatching_Entry'
+ (Dispatching_Policy => ' ',
+ Afile => No_ALI_Id,
+ Loc => 0));
-- Array containing an entry per priority containing the location
-- where there is a Priority_Specific_Dispatching pragma that
-- applies to the priority.
@@ -943,9 +943,7 @@ package body Bcheck is
for ND in No_Deps.First .. No_Deps.Last loop
declare
- ND_Unit : constant Name_Id :=
- No_Deps.Table (ND).No_Dep_Unit;
-
+ ND_Unit : constant Name_Id := No_Deps.Table (ND).No_Dep_Unit;
begin
for J in ALIs.First .. ALIs.Last loop
declare
@@ -1019,7 +1017,7 @@ package body Bcheck is
if AFN /= No_File then
declare
WAI : constant ALI_Id :=
- ALI_Id (Get_Name_Table_Info (AFN));
+ ALI_Id (Get_Name_Table_Info (AFN));
WTE : ALIs_Record renames ALIs.Table (WAI);
begin
diff --git a/gcc/ada/binde.adb b/gcc/ada/binde.adb
index 46dc6d2a5..ed51554b6 100644
--- a/gcc/ada/binde.adb
+++ b/gcc/ada/binde.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -427,8 +427,8 @@ package body Binde is
elsif Is_Waiting_Body (U1) and then Is_Waiting_Body (U2) then
declare
Result : constant Boolean :=
- UNR.Table (Corresponding_Spec (U1)).Elab_Position >
- UNR.Table (Corresponding_Spec (U2)).Elab_Position;
+ UNR.Table (Corresponding_Spec (U1)).Elab_Position >
+ UNR.Table (Corresponding_Spec (U2)).Elab_Position;
begin
if Debug_Flag_B then
if Result then
@@ -483,8 +483,8 @@ package body Binde is
then
declare
Result : constant Boolean :=
- UNR.Table (Corresponding_Body (U1)).Num_Pred <
- UNR.Table (Corresponding_Body (U2)).Num_Pred;
+ UNR.Table (Corresponding_Body (U1)).Num_Pred <
+ UNR.Table (Corresponding_Body (U2)).Num_Pred;
begin
if Debug_Flag_B then
if Result then
@@ -902,8 +902,7 @@ package body Binde is
then
declare
Info : constant Int :=
- Get_Name_Table_Info
- (Withs.Table (W).Uname);
+ Get_Name_Table_Info (Withs.Table (W).Uname);
begin
-- If the unit is unknown, for some unknown reason, fail
@@ -913,11 +912,10 @@ package body Binde is
if Info = 0 or else Unit_Id (Info) = No_Unit_Id then
declare
Withed : String :=
- Get_Name_String (Withs.Table (W).Uname);
+ Get_Name_String (Withs.Table (W).Uname);
Last_Withed : Natural := Withed'Last;
Withing : String :=
- Get_Name_String
- (Units.Table (Before).Uname);
+ Get_Name_String (Units.Table (Before).Uname);
Last_Withing : Natural := Withing'Last;
Spec_Body : String := " (Spec)";
@@ -1520,8 +1518,8 @@ package body Binde is
elsif Is_Waiting_Body (U1) and then Is_Waiting_Body (U2) then
declare
Result : constant Boolean :=
- UNR.Table (Corresponding_Spec (U1)).Elab_Position <
- UNR.Table (Corresponding_Spec (U2)).Elab_Position;
+ UNR.Table (Corresponding_Spec (U1)).Elab_Position <
+ UNR.Table (Corresponding_Spec (U2)).Elab_Position;
begin
if Debug_Flag_B then
if Result then
@@ -1580,8 +1578,8 @@ package body Binde is
then
declare
Result : constant Boolean :=
- UNR.Table (Corresponding_Body (U1)).Num_Pred >=
- UNR.Table (Corresponding_Body (U2)).Num_Pred;
+ UNR.Table (Corresponding_Body (U1)).Num_Pred >=
+ UNR.Table (Corresponding_Body (U2)).Num_Pred;
begin
if Debug_Flag_B then
if Result then
diff --git a/gcc/ada/bindgen.adb b/gcc/ada/bindgen.adb
index 686082d61..bb5a0aac9 100644
--- a/gcc/ada/bindgen.adb
+++ b/gcc/ada/bindgen.adb
@@ -137,7 +137,6 @@ package body Bindgen is
-- Num_Interrupt_States : Integer;
-- Unreserve_All_Interrupts : Integer;
-- Exception_Tracebacks : Integer;
- -- Zero_Cost_Exceptions : Integer;
-- Detect_Blocking : Integer;
-- Default_Stack_Size : Integer;
-- Leap_Seconds_Support : Integer;
@@ -216,9 +215,6 @@ package body Bindgen is
-- tracebacks are provided by default, so a value of zero for this
-- parameter does not necessarily mean no trace backs are available.
- -- Zero_Cost_Exceptions is set to one if zero cost exceptions are used for
- -- this partition, and to zero if longjmp/setjmp exceptions are used.
-
-- Detect_Blocking indicates whether pragma Detect_Blocking is active or
-- not. A value of zero indicates that the pragma is not present, while a
-- value of 1 signals its presence in the partition.
@@ -607,9 +603,6 @@ package body Bindgen is
"""__gl_exception_tracebacks"");");
end if;
- WBI (" Zero_Cost_Exceptions : Integer;");
- WBI (" pragma Import (C, Zero_Cost_Exceptions, " &
- """__gl_zero_cost_exceptions"");");
WBI (" Detect_Blocking : Integer;");
WBI (" pragma Import (C, Detect_Blocking, " &
"""__gl_detect_blocking"");");
@@ -803,17 +796,6 @@ package body Bindgen is
WBI (" Exception_Tracebacks := 1;");
end if;
- Set_String (" Zero_Cost_Exceptions := ");
-
- if Zero_Cost_Exceptions_Specified then
- Set_String ("1");
- else
- Set_String ("0");
- end if;
-
- Set_String (";");
- Write_Statement_Buffer;
-
Set_String (" Detect_Blocking := ");
if Detect_Blocking then
@@ -2135,8 +2117,7 @@ package body Bindgen is
-- function Get_Ada_Main_Name for details on the form of the name.
Needs_Library_Finalization : constant Boolean :=
- not Configurable_Run_Time_On_Target
- and then Has_Finalizer;
+ not Configurable_Run_Time_On_Target and then Has_Finalizer;
-- For restricted run-time libraries (ZFP and Ravenscar) tasks are
-- non-terminating, so we do not want finalization.
@@ -2658,7 +2639,7 @@ package body Bindgen is
function Get_Ada_Main_Name return String is
Suffix : constant String := "_00";
Name : String (1 .. Opt.Ada_Main_Name.all'Length + Suffix'Length) :=
- Opt.Ada_Main_Name.all & Suffix;
+ Opt.Ada_Main_Name.all & Suffix;
Nlen : Natural;
begin
@@ -2945,9 +2926,9 @@ package body Bindgen is
loop
declare
Inum : constant Int :=
- Interrupt_States.Table (K).Interrupt_Id;
+ Interrupt_States.Table (K).Interrupt_Id;
Stat : constant Character :=
- Interrupt_States.Table (K).Interrupt_State;
+ Interrupt_States.Table (K).Interrupt_State;
begin
while IS_Pragma_Settings.Last < Inum loop
diff --git a/gcc/ada/butil.adb b/gcc/ada/butil.adb
index 4d0f4420d..703d24395 100644
--- a/gcc/ada/butil.adb
+++ b/gcc/ada/butil.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2007, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -119,7 +119,7 @@ package body Butil is
declare
U1_Name : constant String (1 .. Name_Len) :=
- Name_Buffer (1 .. Name_Len);
+ Name_Buffer (1 .. Name_Len);
Min_Length : Natural;
begin
diff --git a/gcc/ada/ceinfo.adb b/gcc/ada/ceinfo.adb
index 44e7c67db..3f073b357 100644
--- a/gcc/ada/ceinfo.adb
+++ b/gcc/ada/ceinfo.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1998-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1998-2012, 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- --
@@ -61,11 +61,11 @@ procedure CEinfo is
Fnam : constant Pattern := (UC & Break (' ')) * Fieldnm;
Field_Def : constant Pattern :=
- "-- " & Fnam & " (" & Break (')') * Accessfunc;
+ "-- " & Fnam & " (" & Break (')') * Accessfunc;
Field_Ref : constant Pattern :=
- " -- " & Fnam & Break ('(') & Len (1) &
- Break (')') * Accessfunc;
+ " -- " & Fnam & Break ('(') & Len (1) &
+ Break (')') * Accessfunc;
Field_Com : constant Pattern := " -- " & Fnam & Span (' ') &
(Break (' ') or Rest) * Accessfunc;
diff --git a/gcc/ada/checks.adb b/gcc/ada/checks.adb
index b086c7548..061f9796f 100644
--- a/gcc/ada/checks.adb
+++ b/gcc/ada/checks.adb
@@ -34,6 +34,7 @@ with Exp_Pakd; use Exp_Pakd;
with Exp_Tss; use Exp_Tss;
with Exp_Util; use Exp_Util;
with Elists; use Elists;
+with Expander; use Expander;
with Eval_Fat; use Eval_Fat;
with Freeze; use Freeze;
with Lib; use Lib;
@@ -193,6 +194,29 @@ package body Checks is
-- Local Subprograms --
-----------------------
+ procedure Apply_Arithmetic_Overflow_Checked_Suppressed (N : Node_Id);
+ -- Used to apply arithmetic overflow checks for all cases except operators
+ -- on signed arithmetic types in MINIMIZED/ELIMINATED case (for which we
+ -- call Apply_Arithmetic_Overflow_Minimized_Eliminated below). N is always
+ -- a signed integer arithmetic operator (if and case expressions are not
+ -- included for this case).
+
+ procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id);
+ -- Used to apply arithmetic overflow checks for the case where the overflow
+ -- checking mode is MINIMIZED or ELIMINATED (and the Do_Overflow_Check flag
+ -- is known to be set) and we have a signed integer arithmetic op (which
+ -- includes the case of if and case expressions).
+
+ procedure Apply_Division_Check
+ (N : Node_Id;
+ Rlo : Uint;
+ Rhi : Uint;
+ ROK : Boolean);
+ -- N is an N_Op_Div, N_Op_Rem, or N_Op_Mod node. This routine applies
+ -- division checks as required if the Do_Division_Check flag is set.
+ -- Rlo and Rhi give the possible range of the right operand, these values
+ -- can be referenced and trusted only if ROK is set True.
+
procedure Apply_Float_Conversion_Check
(Ck_Node : Node_Id;
Target_Typ : Entity_Id);
@@ -289,6 +313,13 @@ package body Checks is
-- Called by Apply_{Length,Range}_Checks to rewrite the tree with the
-- Constraint_Error node.
+ function Is_Signed_Integer_Arithmetic_Op (N : Node_Id) return Boolean;
+ -- Returns True if node N is for an arithmetic operation with signed
+ -- integer operands. This includes unary and binary operators, and also
+ -- if and case expression nodes where the dependent expressions are of
+ -- a signed integer type. These are the kinds of nodes for which special
+ -- handling applies in MINIMIZED or ELIMINATED overflow checking mode.
+
function Range_Or_Validity_Checks_Suppressed
(Expr : Node_Id) return Boolean;
-- Returns True if either range or validity checks or both are suppressed
@@ -397,9 +428,8 @@ package body Checks is
Internal_Static_Sloc : constant Source_Ptr := Static_Sloc;
Checks_On : constant Boolean :=
- (not Index_Checks_Suppressed (Suppress_Typ))
- or else
- (not Range_Checks_Suppressed (Suppress_Typ));
+ (not Index_Checks_Suppressed (Suppress_Typ))
+ or else (not Range_Checks_Suppressed (Suppress_Typ));
begin
-- For now we just return if Checks_On is false, however this should
@@ -732,6 +762,32 @@ package body Checks is
-- Apply_Arithmetic_Overflow_Check --
-------------------------------------
+ procedure Apply_Arithmetic_Overflow_Check (N : Node_Id) is
+ begin
+ -- Use old routine in almost all cases (the only case we are treating
+ -- specially is the case of a signed integer arithmetic op with the
+ -- Do_Overflow_Check flag set on the node, and the overflow checking
+ -- mode is MINIMIZED or ELIMINATED).
+
+ if Overflow_Check_Mode (Etype (N)) not in Minimized_Or_Eliminated
+ or else not Do_Overflow_Check (N)
+ or else not Is_Signed_Integer_Arithmetic_Op (N)
+ then
+ Apply_Arithmetic_Overflow_Checked_Suppressed (N);
+
+ -- Otherwise use the new routine for the case of a signed integer
+ -- arithmetic op, with Do_Overflow_Check set to True, and the checking
+ -- mode is MINIMIZED or ELIMINATED.
+
+ else
+ Apply_Arithmetic_Overflow_Minimized_Eliminated (N);
+ end if;
+ end Apply_Arithmetic_Overflow_Check;
+
+ --------------------------------------------------
+ -- Apply_Arithmetic_Overflow_Checked_Suppressed --
+ --------------------------------------------------
+
-- This routine is called only if the type is an integer type, and a
-- software arithmetic overflow check may be needed for op (add, subtract,
-- or multiply). This check is performed only if Software_Overflow_Checking
@@ -739,10 +795,19 @@ package body Checks is
-- operation into a more complex sequence of tests that ensures that
-- overflow is properly caught.
- procedure Apply_Arithmetic_Overflow_Check (N : Node_Id) is
- Loc : constant Source_Ptr := Sloc (N);
- Typ : constant Entity_Id := Etype (N);
- Rtyp : constant Entity_Id := Root_Type (Typ);
+ -- This is used in SUPPRESSED/CHECKED modes. It is identical to the
+ -- code for these cases before the big overflow earthquake, thus ensuring
+ -- that in these modes we have compatible behavior (and reliability) to
+ -- what was there before. It is also called for types other than signed
+ -- integers, and if the Do_Overflow_Check flag is off.
+
+ -- Note: we also call this routine if we decide in the MINIMIZED case
+ -- to give up and just generate an overflow check without any fuss.
+
+ procedure Apply_Arithmetic_Overflow_Checked_Suppressed (N : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (N);
+ Typ : constant Entity_Id := Etype (N);
+ Rtyp : constant Entity_Id := Root_Type (Typ);
begin
-- An interesting special case. If the arithmetic operation appears as
@@ -790,9 +855,9 @@ package body Checks is
if Is_Signed_Integer_Type (Typ)
and then Nkind (Parent (N)) = N_Type_Conversion
then
- declare
+ Conversion_Optimization : declare
Target_Type : constant Entity_Id :=
- Base_Type (Entity (Subtype_Mark (Parent (N))));
+ Base_Type (Entity (Subtype_Mark (Parent (N))));
Llo, Lhi : Uint;
Rlo, Rhi : Uint;
@@ -854,7 +919,7 @@ package body Checks is
end if;
end if;
end if;
- end;
+ end Conversion_Optimization;
end if;
-- Now see if an overflow check is required
@@ -1002,7 +1067,165 @@ package body Checks is
when RE_Not_Available =>
return;
end;
- end Apply_Arithmetic_Overflow_Check;
+ end Apply_Arithmetic_Overflow_Checked_Suppressed;
+
+ ----------------------------------------------------
+ -- Apply_Arithmetic_Overflow_Minimized_Eliminated --
+ ----------------------------------------------------
+
+ procedure Apply_Arithmetic_Overflow_Minimized_Eliminated (Op : Node_Id) is
+ pragma Assert (Is_Signed_Integer_Arithmetic_Op (Op));
+ pragma Assert (Do_Overflow_Check (Op));
+
+ Loc : constant Source_Ptr := Sloc (Op);
+ P : constant Node_Id := Parent (Op);
+
+ LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
+ -- Operands and results are of this type when we convert
+
+ Result_Type : constant Entity_Id := Etype (Op);
+ -- Original result type
+
+ Check_Mode : constant Overflow_Check_Type :=
+ Overflow_Check_Mode (Etype (Op));
+ pragma Assert (Check_Mode in Minimized_Or_Eliminated);
+
+ Lo, Hi : Uint;
+ -- Ranges of values for result
+
+ begin
+ -- Nothing to do if our parent is one of the following:
+
+ -- Another signed integer arithmetic op
+ -- A membership operation
+ -- A comparison operation
+
+ -- In all these cases, we will process at the higher level (and then
+ -- this node will be processed during the downwards recursion that
+ -- is part of the processing in Minimize_Eliminate_Overflow_Checks).
+
+ if Is_Signed_Integer_Arithmetic_Op (P)
+ or else Nkind (P) in N_Membership_Test
+ or else Nkind (P) in N_Op_Compare
+
+ -- We may also be a range operand in a membership test
+
+ or else (Nkind (P) = N_Range
+ and then Nkind (Parent (P)) in N_Membership_Test)
+ then
+ return;
+ end if;
+
+ -- Otherwise, we have a top level arithmetic operation node, and this
+ -- is where we commence the special processing for MINIMIZED/ELIMINATED
+ -- modes. This is the case where we tell the machinery not to move into
+ -- Bignum mode at this top level (of course the top level operation
+ -- will still be in Bignum mode if either of its operands are of type
+ -- Bignum).
+
+ Minimize_Eliminate_Overflow_Checks (Op, Lo, Hi, Top_Level => True);
+
+ -- That call may but does not necessarily change the result type of Op.
+ -- It is the job of this routine to undo such changes, so that at the
+ -- top level, we have the proper type. This "undoing" is a point at
+ -- which a final overflow check may be applied.
+
+ -- If the result type was not fiddled we are all set. We go to base
+ -- types here because things may have been rewritten to generate the
+ -- base type of the operand types.
+
+ if Base_Type (Etype (Op)) = Base_Type (Result_Type) then
+ return;
+
+ -- Bignum case
+
+ elsif Is_RTE (Etype (Op), RE_Bignum) then
+
+ -- We need a sequence that looks like:
+
+ -- Rnn : Result_Type;
+
+ -- declare
+ -- M : Mark_Id := SS_Mark;
+ -- begin
+ -- Rnn := Long_Long_Integer'Base (From_Bignum (Op));
+ -- SS_Release (M);
+ -- end;
+
+ -- This block is inserted (using Insert_Actions), and then the node
+ -- is replaced with a reference to Rnn.
+
+ -- A special case arises if our parent is a conversion node. In this
+ -- case no point in generating a conversion to Result_Type, we will
+ -- let the parent handle this. Note that this special case is not
+ -- just about optimization. Consider
+
+ -- A,B,C : Integer;
+ -- ...
+ -- X := Long_Long_Integer'Base (A * (B ** C));
+
+ -- Now the product may fit in Long_Long_Integer but not in Integer.
+ -- In MINIMIZED/ELIMINATED mode, we don't want to introduce an
+ -- overflow exception for this intermediate value.
+
+ declare
+ Blk : constant Node_Id := Make_Bignum_Block (Loc);
+ Rnn : constant Entity_Id := Make_Temporary (Loc, 'R', Op);
+ RHS : Node_Id;
+
+ Rtype : Entity_Id;
+
+ begin
+ RHS := Convert_From_Bignum (Op);
+
+ if Nkind (P) /= N_Type_Conversion then
+ Convert_To_And_Rewrite (Result_Type, RHS);
+ Rtype := Result_Type;
+
+ -- Interesting question, do we need a check on that conversion
+ -- operation. Answer, not if we know the result is in range.
+ -- At the moment we are not taking advantage of this. To be
+ -- looked at later ???
+
+ else
+ Rtype := LLIB;
+ end if;
+
+ Insert_Before
+ (First (Statements (Handled_Statement_Sequence (Blk))),
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Rnn, Loc),
+ Expression => RHS));
+
+ Insert_Actions (Op, New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Rnn,
+ Object_Definition => New_Occurrence_Of (Rtype, Loc)),
+ Blk));
+
+ Rewrite (Op, New_Occurrence_Of (Rnn, Loc));
+ Analyze_And_Resolve (Op);
+ end;
+
+ -- Here we know the result is Long_Long_Integer'Base, of that it has
+ -- been rewritten because the parent operation is a conversion. See
+ -- Apply_Arithmetic_Overflow_Checked_Suppressed.Conversion_Optimization.
+
+ else
+ pragma Assert
+ (Etype (Op) = LLIB or else Nkind (Parent (Op)) = N_Type_Conversion);
+
+ -- All we need to do here is to convert the result to the proper
+ -- result type. As explained above for the Bignum case, we can
+ -- omit this if our parent is a type conversion.
+
+ if Nkind (P) /= N_Type_Conversion then
+ Convert_To_And_Rewrite (Result_Type, Op);
+ end if;
+
+ Analyze_And_Resolve (Op);
+ end if;
+ end Apply_Arithmetic_Overflow_Minimized_Eliminated;
----------------------------
-- Apply_Constraint_Check --
@@ -1051,8 +1274,7 @@ package body Checks is
Apply_Range_Check (N, Typ);
end if;
- elsif (Is_Record_Type (Typ)
- or else Is_Private_Type (Typ))
+ elsif (Is_Record_Type (Typ) or else Is_Private_Type (Typ))
and then Has_Discriminants (Base_Type (Typ))
and then Is_Constrained (Typ)
then
@@ -1279,7 +1501,7 @@ package body Checks is
then
declare
Alloc_Typ : constant Entity_Id :=
- Entity (Expression (Original_Node (N)));
+ Entity (Expression (Original_Node (N)));
begin
if Alloc_Typ = T_Typ
@@ -1341,8 +1563,7 @@ package body Checks is
then
declare
Type_Def : constant Node_Id :=
- Type_Definition
- (Original_Node (Parent (T_Typ)));
+ Type_Definition (Original_Node (Parent (T_Typ)));
begin
if Nkind (Type_Def) = N_Derived_Type_Definition
and then Is_Entity_Name (Subtype_Indication (Type_Def))
@@ -1420,8 +1641,8 @@ package body Checks is
Cond := Build_Discriminant_Checks (N, T_Typ);
- -- If Lhs is set and is a parameter, then the condition is
- -- guarded by: lhs'constrained and then (condition built above)
+ -- If Lhs is set and is a parameter, then the condition is guarded by:
+ -- lhs'constrained and then (condition built above)
if Present (Param_Entity (Lhs)) then
Cond :=
@@ -1443,52 +1664,69 @@ package body Checks is
Reason => CE_Discriminant_Check_Failed));
end Apply_Discriminant_Check;
- ------------------------
- -- Apply_Divide_Check --
- ------------------------
+ -------------------------
+ -- Apply_Divide_Checks --
+ -------------------------
- procedure Apply_Divide_Check (N : Node_Id) is
+ procedure Apply_Divide_Checks (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
Left : constant Node_Id := Left_Opnd (N);
Right : constant Node_Id := Right_Opnd (N);
+ Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Typ);
+ -- Current overflow checking mode
+
LLB : Uint;
Llo : Uint;
Lhi : Uint;
LOK : Boolean;
Rlo : Uint;
Rhi : Uint;
- ROK : Boolean;
+ ROK : Boolean;
pragma Warnings (Off, Lhi);
-- Don't actually use this value
begin
+ -- If we are operating in MINIMIZED or ELIMINATED mode, and the
+ -- Do_Overflow_Check flag is set and we are operating on signed
+ -- integer types, then the only thing this routine does is to call
+ -- Apply_Arithmetic_Overflow_Minimized_Eliminated. That procedure will
+ -- (possibly later on during recursive downward calls), make sure that
+ -- any needed overflow and division checks are properly applied.
+
+ if Mode in Minimized_Or_Eliminated
+ and then Do_Overflow_Check (N)
+ and then Is_Signed_Integer_Type (Typ)
+ then
+ Apply_Arithmetic_Overflow_Minimized_Eliminated (N);
+ return;
+ end if;
+
+ -- Proceed here in SUPPRESSED or CHECKED modes
+
if Full_Expander_Active
and then not Backend_Divide_Checks_On_Target
and then Check_Needed (Right, Division_Check)
then
Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
- -- See if division by zero possible, and if so generate test. This
- -- part of the test is not controlled by the -gnato switch.
+ -- Deal with division check
- if Do_Division_Check (N) then
- if (not ROK) or else (Rlo <= 0 and then 0 <= Rhi) then
- Insert_Action (N,
- Make_Raise_Constraint_Error (Loc,
- Condition =>
- Make_Op_Eq (Loc,
- Left_Opnd => Duplicate_Subexpr_Move_Checks (Right),
- Right_Opnd => Make_Integer_Literal (Loc, 0)),
- Reason => CE_Divide_By_Zero));
- end if;
+ if Do_Division_Check (N)
+ and then not Division_Checks_Suppressed (Typ)
+ then
+ Apply_Division_Check (N, Rlo, Rhi, ROK);
end if;
- -- Test for extremely annoying case of xxx'First divided by -1
+ -- Deal with overflow check
+
+ if Do_Overflow_Check (N) and then Mode /= Suppressed then
+
+ -- Test for extremely annoying case of xxx'First divided by -1
+ -- for division of signed integer types (only overflow case).
- if Do_Overflow_Check (N) then
if Nkind (N) = N_Op_Divide
and then Is_Signed_Integer_Type (Typ)
then
@@ -1496,30 +1734,68 @@ package body Checks is
LLB := Expr_Value (Type_Low_Bound (Base_Type (Typ)));
if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
- and then
- ((not LOK) or else (Llo = LLB))
+ and then
+ ((not LOK) or else (Llo = LLB))
then
Insert_Action (N,
Make_Raise_Constraint_Error (Loc,
Condition =>
Make_And_Then (Loc,
+ Left_Opnd =>
+ Make_Op_Eq (Loc,
+ Left_Opnd =>
+ Duplicate_Subexpr_Move_Checks (Left),
+ Right_Opnd => Make_Integer_Literal (Loc, LLB)),
- Make_Op_Eq (Loc,
- Left_Opnd =>
- Duplicate_Subexpr_Move_Checks (Left),
- Right_Opnd => Make_Integer_Literal (Loc, LLB)),
+ Right_Opnd =>
+ Make_Op_Eq (Loc,
+ Left_Opnd => Duplicate_Subexpr (Right),
+ Right_Opnd => Make_Integer_Literal (Loc, -1))),
- Make_Op_Eq (Loc,
- Left_Opnd =>
- Duplicate_Subexpr (Right),
- Right_Opnd =>
- Make_Integer_Literal (Loc, -1))),
Reason => CE_Overflow_Check_Failed));
end if;
end if;
end if;
end if;
- end Apply_Divide_Check;
+ end Apply_Divide_Checks;
+
+ --------------------------
+ -- Apply_Division_Check --
+ --------------------------
+
+ procedure Apply_Division_Check
+ (N : Node_Id;
+ Rlo : Uint;
+ Rhi : Uint;
+ ROK : Boolean)
+ is
+ pragma Assert (Do_Division_Check (N));
+
+ Loc : constant Source_Ptr := Sloc (N);
+ Right : constant Node_Id := Right_Opnd (N);
+
+ begin
+ if Full_Expander_Active
+ and then not Backend_Divide_Checks_On_Target
+ and then Check_Needed (Right, Division_Check)
+ then
+ -- See if division by zero possible, and if so generate test. This
+ -- part of the test is not controlled by the -gnato switch, since
+ -- it is a Division_Check and not an Overflow_Check.
+
+ if Do_Division_Check (N) then
+ if (not ROK) or else (Rlo <= 0 and then 0 <= Rhi) then
+ Insert_Action (N,
+ Make_Raise_Constraint_Error (Loc,
+ Condition =>
+ Make_Op_Eq (Loc,
+ Left_Opnd => Duplicate_Subexpr_Move_Checks (Right),
+ Right_Opnd => Make_Integer_Literal (Loc, 0)),
+ Reason => CE_Divide_By_Zero));
+ end if;
+ end if;
+ end if;
+ end Apply_Division_Check;
----------------------------------
-- Apply_Float_Conversion_Check --
@@ -1576,7 +1852,7 @@ package body Checks is
Loc : constant Source_Ptr := Sloc (Ck_Node);
Expr_Type : constant Entity_Id := Base_Type (Etype (Ck_Node));
Target_Base : constant Entity_Id :=
- Implementation_Base_Type (Target_Typ);
+ Implementation_Base_Type (Target_Typ);
Par : constant Node_Id := Parent (Ck_Node);
pragma Assert (Nkind (Par) = N_Type_Conversion);
@@ -1584,9 +1860,9 @@ package body Checks is
Truncate : constant Boolean := Float_Truncate (Par);
Max_Bound : constant Uint :=
- UI_Expon
- (Machine_Radix_Value (Expr_Type),
- Machine_Mantissa_Value (Expr_Type) - 1) - 1;
+ UI_Expon
+ (Machine_Radix_Value (Expr_Type),
+ Machine_Mantissa_Value (Expr_Type) - 1) - 1;
-- Largest bound, so bound plus or minus half is a machine number of F
@@ -1774,12 +2050,391 @@ package body Checks is
(Ck_Node, Target_Typ, Source_Typ, Do_Static => False);
end Apply_Length_Check;
+ -------------------------------------
+ -- Apply_Parameter_Aliasing_Checks --
+ -------------------------------------
+
+ procedure Apply_Parameter_Aliasing_Checks
+ (Call : Node_Id;
+ Subp : Entity_Id)
+ is
+ function May_Cause_Aliasing
+ (Formal_1 : Entity_Id;
+ Formal_2 : Entity_Id) return Boolean;
+ -- Determine whether two formal parameters can alias each other
+ -- depending on their modes.
+
+ function Original_Actual (N : Node_Id) return Node_Id;
+ -- The expander may replace an actual with a temporary for the sake of
+ -- side effect removal. The temporary may hide a potential aliasing as
+ -- it does not share the address of the actual. This routine attempts
+ -- to retrieve the original actual.
+
+ ------------------------
+ -- May_Cause_Aliasing --
+ ------------------------
+
+ function May_Cause_Aliasing
+ (Formal_1 : Entity_Id;
+ Formal_2 : Entity_Id) return Boolean
+ is
+ begin
+ -- The following combination cannot lead to aliasing
+
+ -- Formal 1 Formal 2
+ -- IN IN
+
+ if Ekind (Formal_1) = E_In_Parameter
+ and then
+ Ekind (Formal_2) = E_In_Parameter
+ then
+ return False;
+
+ -- The following combinations may lead to aliasing
+
+ -- Formal 1 Formal 2
+ -- IN OUT
+ -- IN IN OUT
+ -- OUT IN
+ -- OUT IN OUT
+ -- OUT OUT
+
+ else
+ return True;
+ end if;
+ end May_Cause_Aliasing;
+
+ ---------------------
+ -- Original_Actual --
+ ---------------------
+
+ function Original_Actual (N : Node_Id) return Node_Id is
+ begin
+ if Nkind (N) = N_Type_Conversion then
+ return Expression (N);
+
+ -- The expander created a temporary to capture the result of a type
+ -- conversion where the expression is the real actual.
+
+ elsif Nkind (N) = N_Identifier
+ and then Present (Original_Node (N))
+ and then Nkind (Original_Node (N)) = N_Type_Conversion
+ then
+ return Expression (Original_Node (N));
+ end if;
+
+ return N;
+ end Original_Actual;
+
+ -- Local variables
+
+ Loc : constant Source_Ptr := Sloc (Call);
+ Actual_1 : Node_Id;
+ Actual_2 : Node_Id;
+ Check : Node_Id;
+ Cond : Node_Id;
+ Formal_1 : Entity_Id;
+ Formal_2 : Entity_Id;
+
+ -- Start of processing for Apply_Parameter_Aliasing_Checks
+
+ begin
+ Cond := Empty;
+
+ Actual_1 := First_Actual (Call);
+ Formal_1 := First_Formal (Subp);
+ while Present (Actual_1) and then Present (Formal_1) loop
+
+ -- Ensure that the actual is an object that is not passed by value.
+ -- Elementary types are always passed by value, therefore actuals of
+ -- such types cannot lead to aliasing.
+
+ if Is_Object_Reference (Original_Actual (Actual_1))
+ and then not Is_Elementary_Type (Etype (Original_Actual (Actual_1)))
+ then
+ Actual_2 := Next_Actual (Actual_1);
+ Formal_2 := Next_Formal (Formal_1);
+ while Present (Actual_2) and then Present (Formal_2) loop
+
+ -- The other actual we are testing against must also denote
+ -- a non pass-by-value object. Generate the check only when
+ -- the mode of the two formals may lead to aliasing.
+
+ if Is_Object_Reference (Original_Actual (Actual_2))
+ and then not
+ Is_Elementary_Type (Etype (Original_Actual (Actual_2)))
+ and then May_Cause_Aliasing (Formal_1, Formal_2)
+ then
+ -- Generate:
+ -- Actual_1'Overlaps_Storage (Actual_2)
+
+ Check :=
+ Make_Attribute_Reference (Loc,
+ Prefix =>
+ New_Copy_Tree (Original_Actual (Actual_1)),
+ Attribute_Name => Name_Overlaps_Storage,
+ Expressions =>
+ New_List (New_Copy_Tree (Original_Actual (Actual_2))));
+
+ if No (Cond) then
+ Cond := Check;
+ else
+ Cond :=
+ Make_And_Then (Loc,
+ Left_Opnd => Cond,
+ Right_Opnd => Check);
+ end if;
+ end if;
+
+ Next_Actual (Actual_2);
+ Next_Formal (Formal_2);
+ end loop;
+ end if;
+
+ Next_Actual (Actual_1);
+ Next_Formal (Formal_1);
+ end loop;
+
+ -- Place the check right before the call
+
+ if Present (Cond) then
+ Insert_Action (Call,
+ Make_Raise_Program_Error (Loc,
+ Condition => Cond,
+ Reason => PE_Explicit_Raise));
+ end if;
+ end Apply_Parameter_Aliasing_Checks;
+
+ -------------------------------------
+ -- Apply_Parameter_Validity_Checks --
+ -------------------------------------
+
+ procedure Apply_Parameter_Validity_Checks (Subp : Entity_Id) is
+ Subp_Decl : Node_Id;
+
+ procedure Add_Validity_Check
+ (Context : Entity_Id;
+ PPC_Nam : Name_Id;
+ For_Result : Boolean := False);
+ -- Add a single 'Valid[_Scalar] check which verifies the initialization
+ -- of Context. PPC_Nam denotes the pre or post condition pragma name.
+ -- Set flag For_Result when to verify the result of a function.
+
+ procedure Build_PPC_Pragma (PPC_Nam : Name_Id; Check : Node_Id);
+ -- Create a pre or post condition pragma with name PPC_Nam which
+ -- tests expression Check.
+
+ ------------------------
+ -- Add_Validity_Check --
+ ------------------------
+
+ procedure Add_Validity_Check
+ (Context : Entity_Id;
+ PPC_Nam : Name_Id;
+ For_Result : Boolean := False)
+ is
+ Loc : constant Source_Ptr := Sloc (Subp);
+ Typ : constant Entity_Id := Etype (Context);
+ Check : Node_Id;
+ Nam : Name_Id;
+
+ begin
+ -- Pick the proper version of 'Valid depending on the type of the
+ -- context. If the context is not eligible for such a check, return.
+
+ if Is_Scalar_Type (Typ) then
+ Nam := Name_Valid;
+ elsif not No_Scalar_Parts (Typ) then
+ Nam := Name_Valid_Scalars;
+ else
+ return;
+ end if;
+
+ -- Step 1: Create the expression to verify the validity of the
+ -- context.
+
+ Check := New_Reference_To (Context, Loc);
+
+ -- When processing a function result, use 'Result. Generate
+ -- Context'Result
+
+ if For_Result then
+ Check :=
+ Make_Attribute_Reference (Loc,
+ Prefix => Check,
+ Attribute_Name => Name_Result);
+ end if;
+
+ -- Generate:
+ -- Context['Result]'Valid[_Scalars]
+
+ Check :=
+ Make_Attribute_Reference (Loc,
+ Prefix => Check,
+ Attribute_Name => Nam);
+
+ -- Step 2: Create a pre or post condition pragma
+
+ Build_PPC_Pragma (PPC_Nam, Check);
+ end Add_Validity_Check;
+
+ ----------------------
+ -- Build_PPC_Pragma --
+ ----------------------
+
+ procedure Build_PPC_Pragma (PPC_Nam : Name_Id; Check : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (Subp);
+ Decls : List_Id;
+ Prag : Node_Id;
+
+ begin
+ Prag :=
+ Make_Pragma (Loc,
+ Pragma_Identifier => Make_Identifier (Loc, PPC_Nam),
+ Pragma_Argument_Associations => New_List (
+ Make_Pragma_Argument_Association (Loc,
+ Chars => Name_Check,
+ Expression => Check)));
+
+ -- Add a message unless exception messages are suppressed
+
+ if not Exception_Locations_Suppressed then
+ Append_To (Pragma_Argument_Associations (Prag),
+ Make_Pragma_Argument_Association (Loc,
+ Chars => Name_Message,
+ Expression =>
+ Make_String_Literal (Loc,
+ Strval => "failed " & Get_Name_String (PPC_Nam) &
+ " from " & Build_Location_String (Loc))));
+ end if;
+
+ -- Insert the pragma in the tree
+
+ if Nkind (Parent (Subp_Decl)) = N_Compilation_Unit then
+ Add_Global_Declaration (Prag);
+ Analyze (Prag);
+
+ -- PPC pragmas associated with subprogram bodies must be inserted in
+ -- the declarative part of the body.
+
+ elsif Nkind (Subp_Decl) = N_Subprogram_Body then
+ Decls := Declarations (Subp_Decl);
+
+ if No (Decls) then
+ Decls := New_List;
+ Set_Declarations (Subp_Decl, Decls);
+ end if;
+
+ Prepend_To (Decls, Prag);
+
+ -- Ensure the proper visibility of the subprogram body and its
+ -- parameters.
+
+ Push_Scope (Subp);
+ Analyze (Prag);
+ Pop_Scope;
+
+ -- For subprogram declarations insert the PPC pragma right after the
+ -- declarative node.
+
+ else
+ Insert_After_And_Analyze (Subp_Decl, Prag);
+ end if;
+ end Build_PPC_Pragma;
+
+ -- Local variables
+
+ Formal : Entity_Id;
+ Subp_Spec : Node_Id;
+
+ -- Start of processing for Apply_Parameter_Validity_Checks
+
+ begin
+ -- Extract the subprogram specification and declaration nodes
+
+ Subp_Spec := Parent (Subp);
+
+ if Nkind (Subp_Spec) = N_Defining_Program_Unit_Name then
+ Subp_Spec := Parent (Subp_Spec);
+ end if;
+
+ Subp_Decl := Parent (Subp_Spec);
+
+ if not Comes_From_Source (Subp)
+
+ -- Do not process formal subprograms because the corresponding actual
+ -- will receive the proper checks when the instance is analyzed.
+
+ or else Is_Formal_Subprogram (Subp)
+
+ -- Do not process imported subprograms since pre and post conditions
+ -- are never verified on routines coming from a different language.
+
+ or else Is_Imported (Subp)
+ or else Is_Intrinsic_Subprogram (Subp)
+
+ -- The PPC pragmas generated by this routine do not correspond to
+ -- source aspects, therefore they cannot be applied to abstract
+ -- subprograms.
+
+ or else Nkind (Subp_Decl) = N_Abstract_Subprogram_Declaration
+
+ -- Do not consider subprogram renaminds because the renamed entity
+ -- already has the proper PPC pragmas.
+
+ or else Nkind (Subp_Decl) = N_Subprogram_Renaming_Declaration
+
+ -- Do not process null procedures because there is no benefit of
+ -- adding the checks to a no action routine.
+
+ or else (Nkind (Subp_Spec) = N_Procedure_Specification
+ and then Null_Present (Subp_Spec))
+ then
+ return;
+ end if;
+
+ -- Inspect all the formals applying aliasing and scalar initialization
+ -- checks where applicable.
+
+ Formal := First_Formal (Subp);
+ while Present (Formal) loop
+
+ -- Generate the following scalar initialization checks for each
+ -- formal parameter:
+
+ -- mode IN - Pre => Formal'Valid[_Scalars]
+ -- mode IN OUT - Pre, Post => Formal'Valid[_Scalars]
+ -- mode OUT - Post => Formal'Valid[_Scalars]
+
+ if Check_Validity_Of_Parameters then
+ if Ekind_In (Formal, E_In_Parameter, E_In_Out_Parameter) then
+ Add_Validity_Check (Formal, Name_Precondition, False);
+ end if;
+
+ if Ekind_In (Formal, E_In_Out_Parameter, E_Out_Parameter) then
+ Add_Validity_Check (Formal, Name_Postcondition, False);
+ end if;
+ end if;
+
+ Next_Formal (Formal);
+ end loop;
+
+ -- Generate following scalar initialization check for function result:
+
+ -- Post => Subp'Result'Valid[_Scalars]
+
+ if Check_Validity_Of_Parameters and then Ekind (Subp) = E_Function then
+ Add_Validity_Check (Subp, Name_Postcondition, True);
+ end if;
+ end Apply_Parameter_Validity_Checks;
+
---------------------------
-- Apply_Predicate_Check --
---------------------------
procedure Apply_Predicate_Check (N : Node_Id; Typ : Entity_Id) is
S : Entity_Id;
+
begin
if Present (Predicate_Function (Typ)) then
@@ -1787,18 +2442,51 @@ package body Checks is
-- subprograms, such as TSS functions.
S := Current_Scope;
- while Present (S)
- and then not Is_Subprogram (S)
- loop
+ while Present (S) and then not Is_Subprogram (S) loop
S := Scope (S);
end loop;
- if Present (S)
- and then Get_TSS_Name (S) /= TSS_Null
- then
+ if Present (S) and then Get_TSS_Name (S) /= TSS_Null then
return;
+ -- If the check appears within the predicate function itself, it
+ -- means that the user specified a check whose formal is the
+ -- predicated subtype itself, rather than some covering type. This
+ -- is likely to be a common error, and thus deserves a warning.
+
+ elsif S = Predicate_Function (Typ) then
+ Error_Msg_N
+ ("predicate check includes a function call that "
+ & "requires a predicate check?", Parent (N));
+ Error_Msg_N
+ ("\this will result in infinite recursion?", Parent (N));
+ Insert_Action (N,
+ Make_Raise_Storage_Error (Sloc (N),
+ Reason => SE_Infinite_Recursion));
+
+ -- Here for normal case of predicate active.
+
else
+ -- If the predicate is a static predicate and the operand is
+ -- static, the predicate must be evaluated statically. If the
+ -- evaluation fails this is a static constraint error. This check
+ -- is disabled in -gnatc mode, because the compiler is incapable
+ -- of evaluating static expressions in that case.
+
+ if Is_OK_Static_Expression (N) then
+ if Present (Static_Predicate (Typ)) then
+ if Operating_Mode < Generate_Code
+ or else Eval_Static_Predicate_Check (N, Typ)
+ then
+ return;
+ else
+ Error_Msg_NE
+ ("static expression fails static predicate check on&",
+ N, Typ);
+ end if;
+ end if;
+ end if;
+
Insert_Action (N,
Make_Predicate_Check (Typ, Duplicate_Subexpr (N)));
end if;
@@ -2135,9 +2823,8 @@ package body Checks is
Loc : constant Source_Ptr := Sloc (Ck_Node);
Checks_On : constant Boolean :=
- (not Index_Checks_Suppressed (Target_Typ))
- or else
- (not Length_Checks_Suppressed (Target_Typ));
+ (not Index_Checks_Suppressed (Target_Typ))
+ or else (not Length_Checks_Suppressed (Target_Typ));
begin
if not Full_Expander_Active then
@@ -2243,9 +2930,8 @@ package body Checks is
Loc : constant Source_Ptr := Sloc (Ck_Node);
Checks_On : constant Boolean :=
- (not Index_Checks_Suppressed (Target_Typ))
- or else
- (not Range_Checks_Suppressed (Target_Typ));
+ (not Index_Checks_Suppressed (Target_Typ))
+ or else (not Range_Checks_Suppressed (Target_Typ));
begin
if not Full_Expander_Active or else not Checks_On then
@@ -2398,8 +3084,8 @@ package body Checks is
-- fixed point values must be read as integral values.
Float_To_Int : constant Boolean :=
- Is_Floating_Point_Type (Expr_Type)
- and then Is_Integer_Type (Target_Type);
+ Is_Floating_Point_Type (Expr_Type)
+ and then Is_Integer_Type (Target_Type);
begin
if not Overflow_Checks_Suppressed (Target_Base)
@@ -2455,7 +3141,7 @@ package body Checks is
New_Constraints : constant Elist_Id := New_Elmt_List;
Old_Constraints : constant Elist_Id :=
- Discriminant_Constraint (Expr_Type);
+ Discriminant_Constraint (Expr_Type);
begin
Constraint := First_Elmt (Stored_Constraint (Target_Type));
@@ -3096,6 +3782,52 @@ package body Checks is
Saved_Checks_TOS := Saved_Checks_TOS - 1;
end Conditional_Statements_End;
+ -------------------------
+ -- Convert_From_Bignum --
+ -------------------------
+
+ function Convert_From_Bignum (N : Node_Id) return Node_Id is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ begin
+ pragma Assert (Is_RTE (Etype (N), RE_Bignum));
+
+ -- Construct call From Bignum
+
+ return
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_From_Bignum), Loc),
+ Parameter_Associations => New_List (Relocate_Node (N)));
+ end Convert_From_Bignum;
+
+ -----------------------
+ -- Convert_To_Bignum --
+ -----------------------
+
+ function Convert_To_Bignum (N : Node_Id) return Node_Id is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ begin
+ -- Nothing to do if Bignum already except call Relocate_Node
+
+ if Is_RTE (Etype (N), RE_Bignum) then
+ return Relocate_Node (N);
+
+ -- Otherwise construct call to To_Bignum, converting the operand to the
+ -- required Long_Long_Integer form.
+
+ else
+ pragma Assert (Is_Signed_Integer_Type (Etype (N)));
+ return
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_To_Bignum), Loc),
+ Parameter_Associations => New_List (
+ Convert_To (Standard_Long_Long_Integer, Relocate_Node (N))));
+ end if;
+ end Convert_To_Bignum;
+
---------------------
-- Determine_Range --
---------------------
@@ -3559,19 +4291,6 @@ package body Checks is
-- the computed expression is in the range Lor .. Hir. We can use this
-- to restrict the possible range of results.
- -- If one of the computed bounds is outside the range of the base type,
- -- the expression may raise an exception and we had better indicate that
- -- the evaluation has failed, at least if checks are enabled.
-
- if OK1
- and then Enable_Overflow_Checks
- and then not Is_Entity_Name (N)
- and then (Lor < Lo or else Hir > Hi)
- then
- OK := False;
- return;
- end if;
-
if OK1 then
-- If the refined value of the low bound is greater than the type
@@ -3696,13 +4415,14 @@ package body Checks is
---------------------------
procedure Enable_Overflow_Check (N : Node_Id) is
- Typ : constant Entity_Id := Base_Type (Etype (N));
- Chk : Nat;
- OK : Boolean;
- Ent : Entity_Id;
- Ofs : Uint;
- Lo : Uint;
- Hi : Uint;
+ Typ : constant Entity_Id := Base_Type (Etype (N));
+ Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Etype (N));
+ Chk : Nat;
+ OK : Boolean;
+ Ent : Entity_Id;
+ Ofs : Uint;
+ Lo : Uint;
+ Hi : Uint;
begin
if Debug_Flag_CC then
@@ -3714,22 +4434,49 @@ package body Checks is
-- No check if overflow checks suppressed for type of node
- if Present (Etype (N))
- and then Overflow_Checks_Suppressed (Etype (N))
- then
+ if Mode = Suppressed then
return;
-- Nothing to do for unsigned integer types, which do not overflow
elsif Is_Modular_Integer_Type (Typ) then
return;
+ end if;
+
+ -- This is the point at which processing for CHECKED mode diverges
+ -- from processing for MINIMIZED/ELIMINATED modes. This divergence is
+ -- probably more extreme that it needs to be, but what is going on here
+ -- is that when we introduced MINIMIZED/ELIMINATED modes, we wanted
+ -- to leave the processing for CHECKED mode untouched. There were
+ -- two reasons for this. First it avoided any incompatible change of
+ -- behavior. Second, it guaranteed that CHECKED mode continued to be
+ -- legacy reliable.
+
+ -- The big difference is that in CHECKED mode there is a fair amount of
+ -- circuitry to try to avoid setting the Do_Overflow_Check flag if we
+ -- know that no check is needed. We skip all that in the two new modes,
+ -- since really overflow checking happens over a whole subtree, and we
+ -- do the corresponding optimizations later on when applying the checks.
+
+ if Mode in Minimized_Or_Eliminated then
+ Activate_Overflow_Check (N);
+
+ if Debug_Flag_CC then
+ w ("Minimized/Eliminated mode");
+ end if;
+
+ return;
+ end if;
+
+ -- Remainder of processing is for Checked case, and is unchanged from
+ -- earlier versions preceding the addition of MINIMIZED/ELIMINATED.
-- Nothing to do if the range of the result is known OK. We skip this
-- for conversions, since the caller already did the check, and in any
-- case the condition for deleting the check for a type conversion is
-- different.
- elsif Nkind (N) /= N_Type_Conversion then
+ if Nkind (N) /= N_Type_Conversion then
Determine_Range (N, OK, Lo, Hi, Assume_Valid => True);
-- Note in the test below that we assume that the range is not OK
@@ -4353,6 +5100,13 @@ package body Checks is
then
return True;
+ -- Real literals are assumed to be valid in VM targets
+
+ elsif VM_Target /= No_VM
+ and then Nkind (Expr) = N_Real_Literal
+ then
+ return True;
+
-- If we have a type conversion or a qualification of a known valid
-- value, then the result will always be valid.
@@ -4546,11 +5300,11 @@ package body Checks is
Sel : constant Node_Id := Selector_Name (N);
Orig_Comp : constant Entity_Id :=
- Original_Record_Component (Entity (Sel));
+ Original_Record_Component (Entity (Sel));
-- The original component to be checked
Discr_Fct : constant Entity_Id :=
- Discriminant_Checking_Func (Orig_Comp);
+ Discriminant_Checking_Func (Orig_Comp);
-- The discriminant checking function
Discr : Entity_Id;
@@ -5343,9 +6097,8 @@ package body Checks is
Check_Node : Node_Id;
Checks_On : constant Boolean :=
- (not Index_Checks_Suppressed (Suppress_Typ))
- or else
- (not Range_Checks_Suppressed (Suppress_Typ));
+ (not Index_Checks_Suppressed (Suppress_Typ))
+ or else (not Range_Checks_Suppressed (Suppress_Typ));
begin
-- For now we just return if Checks_On is false, however this should be
@@ -5500,6 +6253,29 @@ package body Checks is
end;
end Insert_Valid_Check;
+ -------------------------------------
+ -- Is_Signed_Integer_Arithmetic_Op --
+ -------------------------------------
+
+ function Is_Signed_Integer_Arithmetic_Op (N : Node_Id) return Boolean is
+ begin
+ case Nkind (N) is
+ when N_Op_Abs | N_Op_Add | N_Op_Divide | N_Op_Expon |
+ N_Op_Minus | N_Op_Mod | N_Op_Multiply | N_Op_Plus |
+ N_Op_Rem | N_Op_Subtract =>
+ return Is_Signed_Integer_Type (Etype (N));
+
+ when N_If_Expression | N_Case_Expression =>
+ return Is_Signed_Integer_Type (Etype (N));
+
+ when N_Case_Expression_Alternative =>
+ return Is_Signed_Integer_Type (Etype (Parent (N)));
+
+ when others =>
+ return False;
+ end case;
+ end Is_Signed_Integer_Arithmetic_Op;
+
----------------------------------
-- Install_Null_Excluding_Check --
----------------------------------
@@ -5568,11 +6344,11 @@ package body Checks is
return False;
end if;
- -- Similarly, if we are in a conditional expression and not
- -- part of the condition, then we return False, since neither
- -- the THEN or ELSE expressions will always be elaborated.
+ -- 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_Conditional_Expression
+ if Nkind (P) = N_If_Expression
and then N /= First (Expressions (P))
then
return False;
@@ -5580,7 +6356,7 @@ package body Checks is
-- If we are in a case expression, and not part of the
-- expression, then we return False, since a particular
- -- branch may not always be elaborated
+ -- dependent expression may not always be elaborated
if Nkind (P) = N_Case_Expression
and then N /= Expression (P)
@@ -5767,6 +6543,61 @@ package body Checks is
Possible_Local_Raise (R_Cno, Standard_Constraint_Error);
end Install_Static_Check;
+ -------------------------
+ -- Is_Check_Suppressed --
+ -------------------------
+
+ function Is_Check_Suppressed (E : Entity_Id; C : Check_Id) return Boolean is
+ Ptr : Suppress_Stack_Entry_Ptr;
+
+ begin
+ -- First search the local entity suppress stack. We search this from the
+ -- top of the stack down so that we get the innermost entry that applies
+ -- to this case if there are nested entries.
+
+ Ptr := Local_Suppress_Stack_Top;
+ while Ptr /= null loop
+ if (Ptr.Entity = Empty or else Ptr.Entity = E)
+ and then (Ptr.Check = All_Checks or else Ptr.Check = C)
+ then
+ return Ptr.Suppress;
+ end if;
+
+ Ptr := Ptr.Prev;
+ end loop;
+
+ -- Now search the global entity suppress table for a matching entry.
+ -- We also search this from the top down so that if there are multiple
+ -- pragmas for the same entity, the last one applies (not clear what
+ -- or whether the RM specifies this handling, but it seems reasonable).
+
+ Ptr := Global_Suppress_Stack_Top;
+ while Ptr /= null loop
+ if (Ptr.Entity = Empty or else Ptr.Entity = E)
+ and then (Ptr.Check = All_Checks or else Ptr.Check = C)
+ then
+ return Ptr.Suppress;
+ end if;
+
+ Ptr := Ptr.Prev;
+ end loop;
+
+ -- If we did not find a matching entry, then use the normal scope
+ -- suppress value after all (actually this will be the global setting
+ -- since it clearly was not overridden at any point). For a predefined
+ -- check, we test the specific flag. For a user defined check, we check
+ -- the All_Checks flag. The Overflow flag requires special handling to
+ -- deal with the General vs Assertion case
+
+ if C = Overflow_Check then
+ return Overflow_Checks_Suppressed (Empty);
+ elsif C in Predefined_Check_Id then
+ return Scope_Suppress.Suppress (C);
+ else
+ return Scope_Suppress.Suppress (All_Checks);
+ end if;
+ end Is_Check_Suppressed;
+
---------------------
-- Kill_All_Checks --
---------------------
@@ -5825,17 +6656,962 @@ package body Checks is
end if;
end Length_Checks_Suppressed;
+ -----------------------
+ -- Make_Bignum_Block --
+ -----------------------
+
+ function Make_Bignum_Block (Loc : Source_Ptr) return Node_Id is
+ M : constant Entity_Id := Make_Defining_Identifier (Loc, Name_uM);
+
+ begin
+ return
+ Make_Block_Statement (Loc,
+ Declarations => New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => M,
+ Object_Definition =>
+ New_Occurrence_Of (RTE (RE_Mark_Id), Loc),
+ Expression =>
+ Make_Function_Call (Loc,
+ Name => New_Reference_To (RTE (RE_SS_Mark), Loc)))),
+
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => New_List (
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (RTE (RE_SS_Release), Loc),
+ Parameter_Associations => New_List (
+ New_Reference_To (M, Loc))))));
+ end Make_Bignum_Block;
+
+ ----------------------------------------
+ -- Minimize_Eliminate_Overflow_Checks --
+ ----------------------------------------
+
+ -- This is a recursive routine that is called at the top of an expression
+ -- tree to properly process overflow checking for a whole subtree by making
+ -- recursive calls to process operands. This processing may involve the use
+ -- of bignum or long long integer arithmetic, which will change the types
+ -- of operands and results. That's why we can't do this bottom up (since
+ -- it would interfere with semantic analysis).
+
+ -- What happens is that if MINIMIZED/ELIMINATED mode is in effect then
+ -- the operator expansion routines, as well as the expansion routines
+ -- for if/case expression test the Do_Overflow_Check flag and if it is
+ -- set they (for the moment) do nothing except call the routine to apply
+ -- the overflow check (Apply_Arithmetic_Overflow_Check). That routine
+ -- does nothing for non top-level nodes, so at the point where the call
+ -- is made for the top level node, the entire expression subtree has not
+ -- been expanded, or processed for overflow. All that has to happen as a
+ -- result of the top level call to this routine.
+
+ -- As noted above, the overflow processing works by making recursive calls
+ -- for the operands, and figuring out what to do, based on the processing
+ -- of these operands (e.g. if a bignum operand appears, the parent op has
+ -- to be done in bignum mode), and the determined ranges of the operands.
+
+ -- After possible rewriting of a constituent subexpression node, a call is
+ -- made to either reexpand the node (if nothing has changed) or reanalyze
+ -- the node (if it has been modified by the overflow check processing). The
+ -- Analyzed_Flag is set to False before the reexpand/reanalyze. To avoid
+ -- a recursive call into the whole overflow apparatus, an important rule
+ -- for this call is that either Do_Overflow_Check must be False, or if
+ -- it is set, then the overflow checking mode must be temporarily set
+ -- to CHECKED/SUPPRESSED. Either step will avoid the unwanted recursion.
+
+ procedure Minimize_Eliminate_Overflow_Checks
+ (N : Node_Id;
+ Lo : out Uint;
+ Hi : out Uint;
+ Top_Level : Boolean)
+ is
+ Rtyp : constant Entity_Id := Etype (N);
+ pragma Assert (Is_Signed_Integer_Type (Rtyp));
+ -- Result type, must be a signed integer type
+
+ Check_Mode : constant Overflow_Check_Type := Overflow_Check_Mode (Empty);
+ pragma Assert (Check_Mode in Minimized_Or_Eliminated);
+
+ Loc : constant Source_Ptr := Sloc (N);
+
+ Rlo, Rhi : Uint;
+ -- Ranges of values for right operand (operator case)
+
+ Llo, Lhi : Uint;
+ -- Ranges of values for left operand (operator case)
+
+ LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
+ -- Operands and results are of this type when we convert
+
+ LLLo : constant Uint := Intval (Type_Low_Bound (LLIB));
+ LLHi : constant Uint := Intval (Type_High_Bound (LLIB));
+ -- Bounds of Long_Long_Integer
+
+ Binary : constant Boolean := Nkind (N) in N_Binary_Op;
+ -- Indicates binary operator case
+
+ OK : Boolean;
+ -- Used in call to Determine_Range
+
+ Bignum_Operands : Boolean;
+ -- Set True if one or more operands is already of type Bignum, meaning
+ -- that for sure (regardless of Top_Level setting) we are committed to
+ -- doing the operation in Bignum mode (or in the case of a case or if
+ -- expression, converting all the dependent expressions to Bignum).
+
+ Long_Long_Integer_Operands : Boolean;
+ -- Set True if one or more operands is already of type Long_Long_Integer
+ -- which means that if the result is known to be in the result type
+ -- range, then we must convert such operands back to the result type.
+ -- This switch is properly set only when Bignum_Operands is False.
+
+ procedure Reexpand (C : Suppressed_Or_Checked);
+ -- This is called when we have not modified the node, so we do not need
+ -- to reanalyze it. But we do want to reexpand it in either SUPPRESSED
+ -- or CHECKED mode (as indicated by the argument C) to get proper
+ -- expansion. It is important that we reset the mode to SUPPRESSED or
+ -- CHECKED, since if we leave it in MINIMIZED or ELIMINATED mode we
+ -- would reenter this routine recursively which would not be good!
+ -- Note that this is not just an optimization, testing has showed up
+ -- several complex cases in which reanalyzing an already analyzed node
+ -- causes incorrect behavior.
+
+ function In_Result_Range return Boolean;
+ -- Returns True iff Lo .. Hi are within range of the result type
+
+ procedure Max (A : in out Uint; B : Uint);
+ -- If A is No_Uint, sets A to B, else to UI_Max (A, B)
+
+ procedure Min (A : in out Uint; B : Uint);
+ -- If A is No_Uint, sets A to B, else to UI_Min (A, B)
+
+ ---------------------
+ -- In_Result_Range --
+ ---------------------
+
+ function In_Result_Range return Boolean is
+ begin
+ if Lo = No_Uint or else Hi = No_Uint then
+ return False;
+
+ elsif Is_Static_Subtype (Etype (N)) then
+ return Lo >= Expr_Value (Type_Low_Bound (Rtyp))
+ and then
+ Hi <= Expr_Value (Type_High_Bound (Rtyp));
+
+ else
+ return Lo >= Expr_Value (Type_Low_Bound (Base_Type (Rtyp)))
+ and then
+ Hi <= Expr_Value (Type_High_Bound (Base_Type (Rtyp)));
+ end if;
+ end In_Result_Range;
+
+ ---------
+ -- Max --
+ ---------
+
+ procedure Max (A : in out Uint; B : Uint) is
+ begin
+ if A = No_Uint or else B > A then
+ A := B;
+ end if;
+ end Max;
+
+ ---------
+ -- Min --
+ ---------
+
+ procedure Min (A : in out Uint; B : Uint) is
+ begin
+ if A = No_Uint or else B < A then
+ A := B;
+ end if;
+ end Min;
+
+ --------------
+ -- Reexpand --
+ --------------
+
+ procedure Reexpand (C : Suppressed_Or_Checked) is
+ Svg : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ Sva : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
+ begin
+ Scope_Suppress.Overflow_Checks_General := C;
+ Scope_Suppress.Overflow_Checks_Assertions := C;
+ Set_Analyzed (N, False);
+ Expand (N);
+ Scope_Suppress.Overflow_Checks_General := Svg;
+ Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ end Reexpand;
+
+ -- Start of processing for Minimize_Eliminate_Overflow_Checks
+
+ begin
+ -- Case where we do not have a signed integer arithmetic operation
+
+ if not Is_Signed_Integer_Arithmetic_Op (N) then
+
+ -- Use the normal Determine_Range routine to get the range. We
+ -- don't require operands to be valid, invalid values may result in
+ -- rubbish results where the result has not been properly checked for
+ -- overflow, that's fine!
+
+ Determine_Range (N, OK, Lo, Hi, Assume_Valid => False);
+
+ -- If Determine_Range did not work (can this in fact happen? Not
+ -- clear but might as well protect), use type bounds.
+
+ if not OK then
+ Lo := Intval (Type_Low_Bound (Base_Type (Etype (N))));
+ Hi := Intval (Type_High_Bound (Base_Type (Etype (N))));
+ end if;
+
+ -- If we don't have a binary operator, all we have to do is to set
+ -- the Hi/Lo range, so we are done
+
+ return;
+
+ -- Processing for if expression
+
+ elsif Nkind (N) = N_If_Expression then
+ declare
+ Then_DE : constant Node_Id := Next (First (Expressions (N)));
+ Else_DE : constant Node_Id := Next (Then_DE);
+
+ begin
+ Bignum_Operands := False;
+
+ Minimize_Eliminate_Overflow_Checks
+ (Then_DE, Lo, Hi, Top_Level => False);
+
+ if Lo = No_Uint then
+ Bignum_Operands := True;
+ end if;
+
+ Minimize_Eliminate_Overflow_Checks
+ (Else_DE, Rlo, Rhi, Top_Level => False);
+
+ if Rlo = No_Uint then
+ Bignum_Operands := True;
+ else
+ Long_Long_Integer_Operands :=
+ Etype (Then_DE) = LLIB or else Etype (Else_DE) = LLIB;
+
+ Min (Lo, Rlo);
+ Max (Hi, Rhi);
+ end if;
+
+ -- If at least one of our operands is now Bignum, we must rebuild
+ -- the if expression to use Bignum operands. We will analyze the
+ -- rebuilt if expression with overflow checks off, since once we
+ -- are in bignum mode, we are all done with overflow checks!
+
+ if Bignum_Operands then
+ Rewrite (N,
+ Make_If_Expression (Loc,
+ Expressions => New_List (
+ Remove_Head (Expressions (N)),
+ Convert_To_Bignum (Then_DE),
+ Convert_To_Bignum (Else_DE)),
+ Is_Elsif => Is_Elsif (N)));
+
+ Analyze_And_Resolve
+ (N, RTE (RE_Bignum), Suppress => Overflow_Check);
+
+ -- If we have no Long_Long_Integer operands, then we are in result
+ -- range, since it means that none of our operands felt the need
+ -- to worry about overflow (otherwise it would have already been
+ -- converted to long long integer or bignum). We reexpand to
+ -- complete the expansion of the if expression (but we do not
+ -- need to reanalyze).
+
+ elsif not Long_Long_Integer_Operands then
+ Set_Do_Overflow_Check (N, False);
+ Reexpand (Suppressed);
+
+ -- Otherwise convert us to long long integer mode. Note that we
+ -- don't need any further overflow checking at this level.
+
+ else
+ Convert_To_And_Rewrite (LLIB, Then_DE);
+ Convert_To_And_Rewrite (LLIB, Else_DE);
+ Set_Etype (N, LLIB);
+
+ -- Now reanalyze with overflow checks off
+
+ Set_Do_Overflow_Check (N, False);
+ Set_Analyzed (N, False);
+ Analyze_And_Resolve (N, LLIB, Suppress => Overflow_Check);
+ end if;
+ end;
+
+ return;
+
+ -- Here for case expression
+
+ elsif Nkind (N) = N_Case_Expression then
+ Bignum_Operands := False;
+ Long_Long_Integer_Operands := False;
+
+ declare
+ Alt : Node_Id;
+
+ begin
+ -- Loop through expressions applying recursive call
+
+ Alt := First (Alternatives (N));
+ while Present (Alt) loop
+ declare
+ Aexp : constant Node_Id := Expression (Alt);
+
+ begin
+ Minimize_Eliminate_Overflow_Checks
+ (Aexp, Lo, Hi, Top_Level => False);
+
+ if Lo = No_Uint then
+ Bignum_Operands := True;
+ elsif Etype (Aexp) = LLIB then
+ Long_Long_Integer_Operands := True;
+ end if;
+ end;
+
+ Next (Alt);
+ end loop;
+
+ -- If we have no bignum or long long integer operands, it means
+ -- that none of our dependent expressions could raise overflow.
+ -- In this case, we simply return with no changes except for
+ -- resetting the overflow flag, since we are done with overflow
+ -- checks for this node. We will reexpand to get the needed
+ -- expansion for the case expression, but we do not need to
+ -- reanalyze, since nothing has changed.
+
+ if not (Bignum_Operands or Long_Long_Integer_Operands) then
+ Set_Do_Overflow_Check (N, False);
+ Reexpand (Suppressed);
+
+ -- Otherwise we are going to rebuild the case expression using
+ -- either bignum or long long integer operands throughout.
+
+ else
+ declare
+ Rtype : Entity_Id;
+ New_Alts : List_Id;
+ New_Exp : Node_Id;
+
+ begin
+ New_Alts := New_List;
+ Alt := First (Alternatives (N));
+ while Present (Alt) loop
+ if Bignum_Operands then
+ New_Exp := Convert_To_Bignum (Expression (Alt));
+ Rtype := RTE (RE_Bignum);
+ else
+ New_Exp := Convert_To (LLIB, Expression (Alt));
+ Rtype := LLIB;
+ end if;
+
+ Append_To (New_Alts,
+ Make_Case_Expression_Alternative (Sloc (Alt),
+ Actions => No_List,
+ Discrete_Choices => Discrete_Choices (Alt),
+ Expression => New_Exp));
+
+ Next (Alt);
+ end loop;
+
+ Rewrite (N,
+ Make_Case_Expression (Loc,
+ Expression => Expression (N),
+ Alternatives => New_Alts));
+
+ Analyze_And_Resolve (N, Rtype, Suppress => Overflow_Check);
+ end;
+ end if;
+ end;
+
+ return;
+ end if;
+
+ -- If we have an arithmetic operator we make recursive calls on the
+ -- operands to get the ranges (and to properly process the subtree
+ -- that lies below us!)
+
+ Minimize_Eliminate_Overflow_Checks
+ (Right_Opnd (N), Rlo, Rhi, Top_Level => False);
+
+ if Binary then
+ Minimize_Eliminate_Overflow_Checks
+ (Left_Opnd (N), Llo, Lhi, Top_Level => False);
+ end if;
+
+ -- Record if we have Long_Long_Integer operands
+
+ Long_Long_Integer_Operands :=
+ Etype (Right_Opnd (N)) = LLIB
+ or else (Binary and then Etype (Left_Opnd (N)) = LLIB);
+
+ -- If either operand is a bignum, then result will be a bignum and we
+ -- don't need to do any range analysis. As previously discussed we could
+ -- do range analysis in such cases, but it could mean working with giant
+ -- numbers at compile time for very little gain (the number of cases
+ -- in which we could slip back from bignum mode is small).
+
+ if Rlo = No_Uint or else (Binary and then Llo = No_Uint) then
+ Lo := No_Uint;
+ Hi := No_Uint;
+ Bignum_Operands := True;
+
+ -- Otherwise compute result range
+
+ else
+ Bignum_Operands := False;
+
+ case Nkind (N) is
+
+ -- Absolute value
+
+ when N_Op_Abs =>
+ Lo := Uint_0;
+ Hi := UI_Max (abs Rlo, abs Rhi);
+
+ -- Addition
+
+ when N_Op_Add =>
+ Lo := Llo + Rlo;
+ Hi := Lhi + Rhi;
+
+ -- Division
+
+ when N_Op_Divide =>
+
+ -- If the right operand can only be zero, set 0..0
+
+ if Rlo = 0 and then Rhi = 0 then
+ Lo := Uint_0;
+ Hi := Uint_0;
+
+ -- Possible bounds of division must come from dividing end
+ -- values of the input ranges (four possibilities), provided
+ -- zero is not included in the possible values of the right
+ -- operand.
+
+ -- Otherwise, we just consider two intervals of values for
+ -- the right operand: the interval of negative values (up to
+ -- -1) and the interval of positive values (starting at 1).
+ -- Since division by 1 is the identity, and division by -1
+ -- is negation, we get all possible bounds of division in that
+ -- case by considering:
+ -- - all values from the division of end values of input
+ -- ranges;
+ -- - the end values of the left operand;
+ -- - the negation of the end values of the left operand.
+
+ else
+ declare
+ Mrk : constant Uintp.Save_Mark := Mark;
+ -- Mark so we can release the RR and Ev values
+
+ Ev1 : Uint;
+ Ev2 : Uint;
+ Ev3 : Uint;
+ Ev4 : Uint;
+
+ begin
+ -- Discard extreme values of zero for the divisor, since
+ -- they will simply result in an exception in any case.
+
+ if Rlo = 0 then
+ Rlo := Uint_1;
+ elsif Rhi = 0 then
+ Rhi := -Uint_1;
+ end if;
+
+ -- Compute possible bounds coming from dividing end
+ -- values of the input ranges.
+
+ Ev1 := Llo / Rlo;
+ Ev2 := Llo / Rhi;
+ Ev3 := Lhi / Rlo;
+ Ev4 := Lhi / Rhi;
+
+ Lo := UI_Min (UI_Min (Ev1, Ev2), UI_Min (Ev3, Ev4));
+ Hi := UI_Max (UI_Max (Ev1, Ev2), UI_Max (Ev3, Ev4));
+
+ -- If the right operand can be both negative or positive,
+ -- include the end values of the left operand in the
+ -- extreme values, as well as their negation.
+
+ if Rlo < 0 and then Rhi > 0 then
+ Ev1 := Llo;
+ Ev2 := -Llo;
+ Ev3 := Lhi;
+ Ev4 := -Lhi;
+
+ Min (Lo,
+ UI_Min (UI_Min (Ev1, Ev2), UI_Min (Ev3, Ev4)));
+ Max (Hi,
+ UI_Max (UI_Max (Ev1, Ev2), UI_Max (Ev3, Ev4)));
+ end if;
+
+ -- Release the RR and Ev values
+
+ Release_And_Save (Mrk, Lo, Hi);
+ end;
+ end if;
+
+ -- Exponentiation
+
+ when N_Op_Expon =>
+
+ -- Discard negative values for the exponent, since they will
+ -- simply result in an exception in any case.
+
+ if Rhi < 0 then
+ Rhi := Uint_0;
+ elsif Rlo < 0 then
+ Rlo := Uint_0;
+ end if;
+
+ -- Estimate number of bits in result before we go computing
+ -- giant useless bounds. Basically the number of bits in the
+ -- result is the number of bits in the base multiplied by the
+ -- value of the exponent. If this is big enough that the result
+ -- definitely won't fit in Long_Long_Integer, switch to bignum
+ -- mode immediately, and avoid computing giant bounds.
+
+ -- The comparison here is approximate, but conservative, it
+ -- only clicks on cases that are sure to exceed the bounds.
+
+ if Num_Bits (UI_Max (abs Llo, abs Lhi)) * Rhi + 1 > 100 then
+ Lo := No_Uint;
+ Hi := No_Uint;
+
+ -- If right operand is zero then result is 1
+
+ elsif Rhi = 0 then
+ Lo := Uint_1;
+ Hi := Uint_1;
+
+ else
+ -- High bound comes either from exponentiation of largest
+ -- positive value to largest exponent value, or from
+ -- the exponentiation of most negative value to an
+ -- even exponent.
+
+ declare
+ Hi1, Hi2 : Uint;
+
+ begin
+ if Lhi > 0 then
+ Hi1 := Lhi ** Rhi;
+ else
+ Hi1 := Uint_0;
+ end if;
+
+ if Llo < 0 then
+ if Rhi mod 2 = 0 then
+ Hi2 := Llo ** Rhi;
+ else
+ Hi2 := Llo ** (Rhi - 1);
+ end if;
+ else
+ Hi2 := Uint_0;
+ end if;
+
+ Hi := UI_Max (Hi1, Hi2);
+ end;
+
+ -- Result can only be negative if base can be negative
+
+ if Llo < 0 then
+ if Rhi mod 2 = 0 then
+ Lo := Llo ** (Rhi - 1);
+ else
+ Lo := Llo ** Rhi;
+ end if;
+
+ -- Otherwise low bound is minimum ** minimum
+
+ else
+ Lo := Llo ** Rlo;
+ end if;
+ end if;
+
+ -- Negation
+
+ when N_Op_Minus =>
+ Lo := -Rhi;
+ Hi := -Rlo;
+
+ -- Mod
+
+ when N_Op_Mod =>
+ declare
+ Maxabs : constant Uint := UI_Max (abs Rlo, abs Rhi) - 1;
+ -- This is the maximum absolute value of the result
+
+ begin
+ Lo := Uint_0;
+ Hi := Uint_0;
+
+ -- The result depends only on the sign and magnitude of
+ -- the right operand, it does not depend on the sign or
+ -- magnitude of the left operand.
+
+ if Rlo < 0 then
+ Lo := -Maxabs;
+ end if;
+
+ if Rhi > 0 then
+ Hi := Maxabs;
+ end if;
+ end;
+
+ -- Multiplication
+
+ when N_Op_Multiply =>
+
+ -- Possible bounds of multiplication must come from multiplying
+ -- end values of the input ranges (four possibilities).
+
+ declare
+ Mrk : constant Uintp.Save_Mark := Mark;
+ -- Mark so we can release the Ev values
+
+ Ev1 : constant Uint := Llo * Rlo;
+ Ev2 : constant Uint := Llo * Rhi;
+ Ev3 : constant Uint := Lhi * Rlo;
+ Ev4 : constant Uint := Lhi * Rhi;
+
+ begin
+ Lo := UI_Min (UI_Min (Ev1, Ev2), UI_Min (Ev3, Ev4));
+ Hi := UI_Max (UI_Max (Ev1, Ev2), UI_Max (Ev3, Ev4));
+
+ -- Release the Ev values
+
+ Release_And_Save (Mrk, Lo, Hi);
+ end;
+
+ -- Plus operator (affirmation)
+
+ when N_Op_Plus =>
+ Lo := Rlo;
+ Hi := Rhi;
+
+ -- Remainder
+
+ when N_Op_Rem =>
+ declare
+ Maxabs : constant Uint := UI_Max (abs Rlo, abs Rhi) - 1;
+ -- This is the maximum absolute value of the result. Note
+ -- that the result range does not depend on the sign of the
+ -- right operand.
+
+ begin
+ Lo := Uint_0;
+ Hi := Uint_0;
+
+ -- Case of left operand negative, which results in a range
+ -- of -Maxabs .. 0 for those negative values. If there are
+ -- no negative values then Lo value of result is always 0.
+
+ if Llo < 0 then
+ Lo := -Maxabs;
+ end if;
+
+ -- Case of left operand positive
+
+ if Lhi > 0 then
+ Hi := Maxabs;
+ end if;
+ end;
+
+ -- Subtract
+
+ when N_Op_Subtract =>
+ Lo := Llo - Rhi;
+ Hi := Lhi - Rlo;
+
+ -- Nothing else should be possible
+
+ when others =>
+ raise Program_Error;
+ end case;
+ end if;
+
+ -- Here for the case where we have not rewritten anything (no bignum
+ -- operands or long long integer operands), and we know the result.
+ -- If we know we are in the result range, and we do not have Bignum
+ -- operands or Long_Long_Integer operands, we can just reexpand with
+ -- overflow checks turned off (since we know we cannot have overflow).
+ -- As always the reexpansion is required to complete expansion of the
+ -- operator, but we do not need to reanalyze, and we prevent recursion
+ -- by suppressing the check.
+
+ if not (Bignum_Operands or Long_Long_Integer_Operands)
+ and then In_Result_Range
+ then
+ Set_Do_Overflow_Check (N, False);
+ Reexpand (Suppressed);
+ return;
+
+ -- Here we know that we are not in the result range, and in the general
+ -- case we will move into either the Bignum or Long_Long_Integer domain
+ -- to compute the result. However, there is one exception. If we are
+ -- at the top level, and we do not have Bignum or Long_Long_Integer
+ -- operands, we will have to immediately convert the result back to
+ -- the result type, so there is no point in Bignum/Long_Long_Integer
+ -- fiddling.
+
+ elsif Top_Level
+ and then not (Bignum_Operands or Long_Long_Integer_Operands)
+
+ -- One further refinement. If we are at the top level, but our parent
+ -- is a type conversion, then go into bignum or long long integer node
+ -- since the result will be converted to that type directly without
+ -- going through the result type, and we may avoid an overflow. This
+ -- is the case for example of Long_Long_Integer (A ** 4), where A is
+ -- of type Integer, and the result A ** 4 fits in Long_Long_Integer
+ -- but does not fit in Integer.
+
+ and then Nkind (Parent (N)) /= N_Type_Conversion
+ then
+ -- Here we will keep the original types, but we do need an overflow
+ -- check, so we will set Do_Overflow_Check to True (actually it is
+ -- true already, or how would we have got here?).
+
+ pragma Assert (Do_Overflow_Check (N));
+ Set_Analyzed (N, False);
+
+ -- One subtlety. We can't just go ahead and do an analyze operation
+ -- here because it will cause recursion into the whole MINIMIZED/
+ -- ELIMINATED overflow processing which is not what we want. Here
+ -- we are at the top level, and we need a check against the result
+ -- mode (i.e. we want to use Checked mode). So do exactly that!
+ -- Also, we have not modified the node, so this is a case where
+ -- we need to reexpand, but not reanalyze.
+
+ Reexpand (Checked);
+ return;
+
+ -- Cases where we do the operation in Bignum mode. This happens either
+ -- because one of our operands is in Bignum mode already, or because
+ -- the computed bounds are outside the bounds of Long_Long_Integer,
+ -- which in some cases can be indicated by Hi and Lo being No_Uint.
+
+ -- Note: we could do better here and in some cases switch back from
+ -- Bignum mode to normal mode, e.g. big mod 2 must be in the range
+ -- 0 .. 1, but the cases are rare and it is not worth the effort.
+ -- Failing to do this switching back is only an efficiency issue.
+
+ elsif Lo = No_Uint or else Lo < LLLo or else Hi > LLHi then
+
+ -- OK, we are definitely outside the range of Long_Long_Integer. The
+ -- question is whether to move to Bignum mode, or stay in the domain
+ -- of Long_Long_Integer, signalling that an overflow check is needed.
+
+ -- Obviously in MINIMIZED mode we stay with LLI, since we are not in
+ -- the Bignum business. In ELIMINATED mode, we will normally move
+ -- into Bignum mode, but there is an exception if neither of our
+ -- operands is Bignum now, and we are at the top level (Top_Level
+ -- set True). In this case, there is no point in moving into Bignum
+ -- mode to prevent overflow if the caller will immediately convert
+ -- the Bignum value back to LLI with an overflow check. It's more
+ -- efficient to stay in LLI mode with an overflow check.
+
+ if Check_Mode = Minimized
+ or else (Top_Level and not Bignum_Operands)
+ then
+ Enable_Overflow_Check (N);
+
+ -- Since we are doing an overflow check, the result has to be in
+ -- Long_Long_Integer mode, so adjust the possible range to reflect
+ -- this. Note these calls also change No_Uint values from the top
+ -- level case to LLI bounds.
+
+ Max (Lo, LLLo);
+ Min (Hi, LLHi);
+
+ -- Otherwise we are in ELIMINATED mode and we switch to Bignum mode
+
+ else
+ pragma Assert (Check_Mode = Eliminated);
+
+ declare
+ Fent : Entity_Id;
+ Args : List_Id;
+
+ begin
+ case Nkind (N) is
+ when N_Op_Abs =>
+ Fent := RTE (RE_Big_Abs);
+
+ when N_Op_Add =>
+ Fent := RTE (RE_Big_Add);
+
+ when N_Op_Divide =>
+ Fent := RTE (RE_Big_Div);
+
+ when N_Op_Expon =>
+ Fent := RTE (RE_Big_Exp);
+
+ when N_Op_Minus =>
+ Fent := RTE (RE_Big_Neg);
+
+ when N_Op_Mod =>
+ Fent := RTE (RE_Big_Mod);
+
+ when N_Op_Multiply =>
+ Fent := RTE (RE_Big_Mul);
+
+ when N_Op_Rem =>
+ Fent := RTE (RE_Big_Rem);
+
+ when N_Op_Subtract =>
+ Fent := RTE (RE_Big_Sub);
+
+ -- Anything else is an internal error, this includes the
+ -- N_Op_Plus case, since how can plus cause the result
+ -- to be out of range if the operand is in range?
+
+ when others =>
+ raise Program_Error;
+ end case;
+
+ -- Construct argument list for Bignum call, converting our
+ -- operands to Bignum form if they are not already there.
+
+ Args := New_List;
+
+ if Binary then
+ Append_To (Args, Convert_To_Bignum (Left_Opnd (N)));
+ end if;
+
+ Append_To (Args, Convert_To_Bignum (Right_Opnd (N)));
+
+ -- Now rewrite the arithmetic operator with a call to the
+ -- corresponding bignum function.
+
+ Rewrite (N,
+ Make_Function_Call (Loc,
+ Name => New_Occurrence_Of (Fent, Loc),
+ Parameter_Associations => Args));
+ Analyze_And_Resolve (N, RTE (RE_Bignum));
+
+ -- Indicate result is Bignum mode
+
+ Lo := No_Uint;
+ Hi := No_Uint;
+ return;
+ end;
+ end if;
+
+ -- Otherwise we are in range of Long_Long_Integer, so no overflow
+ -- check is required, at least not yet.
+
+ else
+ Set_Do_Overflow_Check (N, False);
+ end if;
+
+ -- Here we are not in Bignum territory, but we may have long long
+ -- integer operands that need special handling. First a special check:
+ -- If an exponentiation operator exponent is of type Long_Long_Integer,
+ -- it means we converted it to prevent overflow, but exponentiation
+ -- requires a Natural right operand, so convert it back to Natural.
+ -- This conversion may raise an exception which is fine.
+
+ if Nkind (N) = N_Op_Expon and then Etype (Right_Opnd (N)) = LLIB then
+ Convert_To_And_Rewrite (Standard_Natural, Right_Opnd (N));
+ end if;
+
+ -- Here we will do the operation in Long_Long_Integer. We do this even
+ -- if we know an overflow check is required, better to do this in long
+ -- long integer mode, since we are less likely to overflow!
+
+ -- Convert right or only operand to Long_Long_Integer, except that
+ -- we do not touch the exponentiation right operand.
+
+ if Nkind (N) /= N_Op_Expon then
+ Convert_To_And_Rewrite (LLIB, Right_Opnd (N));
+ end if;
+
+ -- Convert left operand to Long_Long_Integer for binary case
+
+ if Binary then
+ Convert_To_And_Rewrite (LLIB, Left_Opnd (N));
+ end if;
+
+ -- Reset node to unanalyzed
+
+ Set_Analyzed (N, False);
+ Set_Etype (N, Empty);
+ Set_Entity (N, Empty);
+
+ -- Now analyze this new node. This reanalysis will complete processing
+ -- for the node. In particular we will complete the expansion of an
+ -- exponentiation operator (e.g. changing A ** 2 to A * A), and also
+ -- we will complete any division checks (since we have not changed the
+ -- setting of the Do_Division_Check flag).
+
+ -- If no overflow check, suppress overflow check to avoid an infinite
+ -- recursion into this procedure.
+
+ if not Do_Overflow_Check (N) then
+ Analyze_And_Resolve (N, LLIB, Suppress => Overflow_Check);
+
+ -- If an overflow check is required, do it in normal CHECKED mode.
+ -- That avoids an infinite recursion, making sure we get a normal
+ -- overflow check.
+
+ else
+ declare
+ SG : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ SA : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
+ begin
+ Scope_Suppress.Overflow_Checks_General := Checked;
+ Scope_Suppress.Overflow_Checks_Assertions := Checked;
+ Analyze_And_Resolve (N, LLIB);
+ Scope_Suppress.Overflow_Checks_General := SG;
+ Scope_Suppress.Overflow_Checks_Assertions := SA;
+ end;
+ end if;
+ end Minimize_Eliminate_Overflow_Checks;
+
+ -------------------------
+ -- Overflow_Check_Mode --
+ -------------------------
+
+ function Overflow_Check_Mode (E : Entity_Id) return Overflow_Check_Type is
+ begin
+ -- Check overflow suppressed on entity
+
+ if Present (E) and then Checks_May_Be_Suppressed (E) then
+ if Is_Check_Suppressed (E, Overflow_Check) then
+ return Suppressed;
+ end if;
+ end if;
+
+ -- Else return appropriate scope setting
+
+ if In_Assertion_Expr = 0 then
+ return Scope_Suppress.Overflow_Checks_General;
+ else
+ return Scope_Suppress.Overflow_Checks_Assertions;
+ end if;
+ end Overflow_Check_Mode;
+
--------------------------------
-- Overflow_Checks_Suppressed --
--------------------------------
function Overflow_Checks_Suppressed (E : Entity_Id) return Boolean is
begin
- if Present (E) and then Checks_May_Be_Suppressed (E) then
- return Is_Check_Suppressed (E, Overflow_Check);
- else
- return Scope_Suppress.Suppress (Overflow_Check);
- end if;
+ return Overflow_Check_Mode (E) = Suppressed;
end Overflow_Checks_Suppressed;
-----------------------------
@@ -6324,10 +8100,10 @@ package body Checks is
if Is_Array_Type (T_Typ) and then Is_Array_Type (S_Typ) then
if Is_Constrained (T_Typ) then
- -- The checking code to be generated will freeze the
- -- corresponding array type. However, we must freeze the
- -- type now, so that the freeze node does not appear within
- -- the generated conditional expression, but ahead of it.
+ -- The checking code to be generated will freeze the corresponding
+ -- array type. However, we must freeze the type now, so that the
+ -- freeze node does not appear within the generated if expression,
+ -- but ahead of it.
Freeze_Before (Ck_Node, T_Typ);
@@ -7098,8 +8874,8 @@ package body Checks is
Out_Of_Range : Boolean;
Static_Bounds : constant Boolean :=
- Compile_Time_Known_Value (LB)
- and Compile_Time_Known_Value (UB);
+ Compile_Time_Known_Value (LB)
+ and Compile_Time_Known_Value (UB);
begin
-- Following range tests should use Sem_Eval routine ???
diff --git a/gcc/ada/checks.ads b/gcc/ada/checks.ads
index 83a67dcb8..f7a439938 100644
--- a/gcc/ada/checks.ads
+++ b/gcc/ada/checks.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -67,6 +67,18 @@ package Checks is
-- reason we insist on specifying Empty is to force the caller to think
-- about whether there is any relevant entity that should be checked.
+ function Is_Check_Suppressed (E : Entity_Id; C : Check_Id) return Boolean;
+ -- This function is called if Checks_May_Be_Suppressed (E) is True to
+ -- determine whether check C is suppressed either on the entity E or
+ -- as the result of a scope suppress pragma. If Checks_May_Be_Suppressed
+ -- is False, then the status of the check can be determined simply by
+ -- examining Scope_Checks (C), so this routine is not called in that case.
+
+ function Overflow_Check_Mode (E : Entity_Id) return Overflow_Check_Type;
+ -- Returns current overflow checking mode, taking into account whether
+ -- we are inside an assertion expression. Always returns Suppressed if
+ -- overflow checks are suppressed for entity E.
+
-------------------------------------------
-- Procedures to Activate Checking Flags --
-------------------------------------------
@@ -123,13 +135,14 @@ package Checks is
-- larger than the overlaid object.
procedure Apply_Arithmetic_Overflow_Check (N : Node_Id);
- -- Given a binary arithmetic operator (+ - *) expand a software integer
- -- overflow check using range checks on a larger checking type or a call
- -- to an appropriate runtime routine. This is used for all three operators
- -- for the signed integer case, and for +/- in the fixed-point case. The
- -- check is expanded only if Software_Overflow_Checking is enabled and
- -- Do_Overflow_Check is set on node N. Note that divide is handled
- -- separately using Apply_Arithmetic_Divide_Overflow_Check.
+ -- Handle overflow checking for an arithmetic operator. Also handles the
+ -- cases of ELIMINATED and MINIMIZED overflow checking mode. If the mode
+ -- is one of the latter two, then this routine can also be called with
+ -- an if or case expression node to make sure that we properly handle
+ -- overflow checking for dependent expressions. This routine handles
+ -- front end vs back end overflow checks (in the front end case it expands
+ -- the necessary check). Note that divide is handled separately using
+ -- Apply_Divide_Checks.
procedure Apply_Constraint_Check
(N : Node_Id;
@@ -154,25 +167,29 @@ package Checks is
-- formals, the check is performed only if the corresponding actual is
-- constrained, i.e., whether Lhs'Constrained is True.
+ procedure Apply_Divide_Checks (N : Node_Id);
+ -- The node kind is N_Op_Divide, N_Op_Mod, or N_Op_Rem if either of the
+ -- flags Do_Division_Check or Do_Overflow_Check is set, then this routine
+ -- ensures that the appropriate checks are made. Note that overflow can
+ -- occur in the signed case for the case of the largest negative number
+ -- divided by minus one.
+
+ procedure Apply_Parameter_Aliasing_Checks
+ (Call : Node_Id;
+ Subp : Entity_Id);
+ -- Given a subprogram call Call, add a check to verify that none of the
+ -- actuals overlap. Subp denotes the subprogram being called.
+
+ procedure Apply_Parameter_Validity_Checks (Subp : Entity_Id);
+ -- Given a subprogram Subp, add both a pre and post condition pragmas that
+ -- verify the proper initialization of scalars in parameters and function
+ -- results.
+
procedure Apply_Predicate_Check (N : Node_Id; Typ : Entity_Id);
-- N is an expression to which a predicate check may need to be applied
-- for Typ, if Typ has a predicate function. The check is applied only
-- if the type of N does not match Typ.
- function Build_Discriminant_Checks
- (N : Node_Id;
- T_Typ : Entity_Id)
- return Node_Id;
- -- Subsidiary routine for Apply_Discriminant_Check. Builds the expression
- -- that compares discriminants of the expression with discriminants of the
- -- type. Also used directly for membership tests (see Exp_Ch4.Expand_N_In).
-
- procedure Apply_Divide_Check (N : Node_Id);
- -- The node kind is N_Op_Divide, N_Op_Mod, or N_Op_Rem. An appropriate
- -- check is generated to ensure that the right operand is non-zero. In
- -- the divide case, we also check that we do not have the annoying case
- -- of the largest negative number divided by minus one.
-
procedure Apply_Type_Conversion_Checks (N : Node_Id);
-- N is an N_Type_Conversion node. A type conversion actually involves
-- two sorts of checks. The first check is the checks that ensures that
@@ -189,6 +206,25 @@ package Checks is
-- result type. This routine deals with range and overflow checks needed
-- to make sure that the universal result is in range.
+ function Build_Discriminant_Checks
+ (N : Node_Id;
+ T_Typ : Entity_Id)
+ return Node_Id;
+ -- Subsidiary routine for Apply_Discriminant_Check. Builds the expression
+ -- that compares discriminants of the expression with discriminants of the
+ -- type. Also used directly for membership tests (see Exp_Ch4.Expand_N_In).
+
+ function Convert_From_Bignum (N : Node_Id) return Node_Id;
+ -- Returns result of converting node N from Bignum. The returned value is
+ -- not analyzed, the caller takes responsibility for this. Node N must be
+ -- a subexpression node of type Bignum. The result is Long_Long_Integer.
+
+ function Convert_To_Bignum (N : Node_Id) return Node_Id;
+ -- Returns result of converting node N to Bignum. The returned value is not
+ -- analyzed, the caller takes responsibility for this. Node N must be a
+ -- subexpression node of a signed integer type or Bignum type (if it is
+ -- already a Bignum, the returned value is Relocate_Node (N)).
+
procedure Determine_Range
(N : Node_Id;
OK : out Boolean;
@@ -196,23 +232,114 @@ package Checks is
Hi : out Uint;
Assume_Valid : Boolean := False);
-- N is a node for a subexpression. If N is of a discrete type with no
- -- error indications, and no other peculiarities (e.g. missing type
- -- fields), then OK is True on return, and Lo and Hi are set to a
- -- conservative estimate of the possible range of values of N. Thus if OK
- -- is True on return, the value of the subexpression N is known to like in
- -- the range Lo .. Hi (inclusive). If the expression is not of a discrete
- -- type, or some kind of error condition is detected, then OK is False on
- -- exit, and Lo/Hi are set to No_Uint. Thus the significance of OK being
- -- False on return is that no useful information is available on the range
- -- of the expression. Assume_Valid determines whether the processing is
- -- allowed to assume that values are in range of their subtypes. If it is
- -- set to True, then this assumption is valid, if False, then processing
- -- is done using base types to allow invalid values.
+ -- error indications, and no other peculiarities (e.g. missing Etype),
+ -- then OK is True on return, and Lo and Hi are set to a conservative
+ -- estimate of the possible range of values of N. Thus if OK is True on
+ -- return, the value of the subexpression N is known to lie in the range
+ -- Lo .. Hi (inclusive). If the expression is not of a discrete type, or
+ -- some kind of error condition is detected, then OK is False on exit, and
+ -- Lo/Hi are set to No_Uint. Thus the significance of OK being False on
+ -- return is that no useful information is available on the range of the
+ -- expression. Assume_Valid determines whether the processing is allowed to
+ -- assume that values are in range of their subtypes. If it is set to True,
+ -- then this assumption is valid, if False, then processing is done using
+ -- base types to allow invalid values.
procedure Install_Null_Excluding_Check (N : Node_Id);
-- Determines whether an access node requires a runtime access check and
-- if so inserts the appropriate run-time check.
+ function Make_Bignum_Block (Loc : Source_Ptr) return Node_Id;
+ -- This function is used by top level overflow checking routines to do a
+ -- mark/release operation on the secondary stack around bignum operations.
+ -- The block created looks like:
+ --
+ -- declare
+ -- M : Mark_Id := SS_Mark;
+ -- begin
+ -- SS_Release (M);
+ -- end;
+ --
+ -- The idea is that the caller will insert any needed extra declarations
+ -- after the declaration of M, and any needed statements (in particular
+ -- the bignum operations) before the call to SS_Release, and then do an
+ -- Insert_Action of the whole block (it is returned unanalyzed). The Loc
+ -- parameter is used to supply Sloc values for the constructed tree.
+
+ procedure Minimize_Eliminate_Overflow_Checks
+ (N : Node_Id;
+ Lo : out Uint;
+ Hi : out Uint;
+ Top_Level : Boolean);
+ -- This is the main routine for handling MINIMIZED and ELIMINATED overflow
+ -- checks. On entry N is a node whose result is a signed integer subtype.
+ -- If the node is an arithmetic operation, then a range analysis is carried
+ -- out, and there are three possibilities:
+ --
+ -- The node is left unchanged (apart from expansion of an exponentiation
+ -- operation). This happens if the routine can determine that the result
+ -- is definitely in range. The Do_Overflow_Check flag is turned off in
+ -- this case.
+ --
+ -- The node is transformed into an arithmetic operation with a result
+ -- type of Long_Long_Integer.
+ --
+ -- The node is transformed into a function call that calls an appropriate
+ -- function in the System.Bignums package to compute a Bignum result.
+ --
+ -- In the first two cases, Lo and Hi are set to the bounds of the possible
+ -- range of results, computed as accurately as possible. In the third case
+ -- Lo and Hi are set to No_Uint (there are some cases where we could get an
+ -- advantage from keeping result ranges for Bignum values, but it could use
+ -- a lot of space and is very unlikely to be valuable).
+ --
+ -- If the node is not an arithmetic operation, then it is unchanged but
+ -- Lo and Hi are still set (to the bounds of the result subtype if nothing
+ -- better can be determined).
+ --
+ -- Note: this function is recursive, if called with an arithmetic operator,
+ -- recursive calls are made to process the operands using this procedure.
+ -- So we end up doing things top down. Nothing happens to an arithmetic
+ -- expression until this procedure is called on the top level node and
+ -- then the recursive calls process all the children. We have to do it
+ -- this way. If we try to do it bottom up in natural expansion order, then
+ -- there are two problems. First, where do we stash the bounds, and more
+ -- importantly, semantic processing will be messed up. Consider A+B+C where
+ -- A,B,C are all of type integer, if we processed A+B before doing semantic
+ -- analysis of the addition of this result to C, that addition could end up
+ -- with a Long_Long_Integer left operand and an Integer right operand, and
+ -- we would get a semantic error.
+ --
+ -- The routine is called in three situations if we are operating in either
+ -- MINIMIZED or ELIMINATED modes.
+ --
+ -- Overflow checks applied to the top node of an expression tree when
+ -- that node is an arithmetic operator. In this case the result is
+ -- converted to the appropriate result type (there is special processing
+ -- when the parent is a conversion, see body for details).
+ --
+ -- Overflow checks are applied to the operands of a comparison operation.
+ -- In this case, the comparison is done on the result Long_Long_Integer
+ -- or Bignum values, without raising any exceptions.
+ --
+ -- Overflow checks are applied to the left operand of a membership test.
+ -- In this case no exception is raised if a Long_Long_Integer or Bignum
+ -- result is outside the range of the type of that left operand (it is
+ -- just that the result of IN is false in that case).
+ --
+ -- Note that if Bignum values appear, the caller must take care of doing
+ -- the appropriate mark/release operations on the secondary stack.
+ --
+ -- Top_Level is used to avoid inefficient unnecessary transitions into the
+ -- Bignum domain. If Top_Level is True, it means that the caller will have
+ -- to convert any Bignum value back to Long_Long_Integer, checking that the
+ -- value is in range. This is the normal case for a top level operator in
+ -- a subexpression. There is no point in going into Bignum mode to avoid an
+ -- overflow just so we can check for overflow the next moment. For calls
+ -- from comparisons and membership tests, and for all recursive calls, we
+ -- do want to transition into the Bignum domain if necessary. Note that
+ -- this setting is only relevant in ELIMINATED mode.
+
-------------------------------------------------------
-- Control and Optimization of Range/Overflow Checks --
-------------------------------------------------------
@@ -243,7 +370,9 @@ package Checks is
-- has no effect. If a check is needed then this routine sets the flag
-- Do_Overflow_Check in node N to True, unless it can be determined that
-- the check is not needed. The only condition under which this is the
- -- case is if there was an identical check earlier on.
+ -- case is if there was an identical check earlier on. These optimziations
+ -- apply to CHECKED mode, but not to MINIMIZED/ELIMINATED modes. See the
+ -- body for a full explanation.
procedure Enable_Range_Check (N : Node_Id);
-- Set Do_Range_Check flag in node N True, unless it can be determined
diff --git a/gcc/ada/clean.adb b/gcc/ada/clean.adb
index 276fcc656..f952e18ab 100644
--- a/gcc/ada/clean.adb
+++ b/gcc/ada/clean.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2003-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2003-2012, 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- --
@@ -73,7 +73,7 @@ package body Clean is
-- Changed to "b__" for VMS in the body of the package.
Project_Tree : constant Project_Tree_Ref :=
- new Project_Tree_Data (Is_Root_Tree => True);
+ new Project_Tree_Data (Is_Root_Tree => True);
-- The project tree
Object_Directory_Path : String_Access := null;
@@ -319,7 +319,7 @@ package body Clean is
-- The name of the archive dependency file for this project
Obj_Dir : constant String :=
- Get_Name_String (Project.Object_Directory.Display_Name);
+ Get_Name_String (Project.Object_Directory.Display_Name);
begin
Change_Dir (Obj_Dir);
@@ -463,7 +463,7 @@ package body Clean is
declare
Obj_Dir : constant String :=
- Dir_Name (Get_Name_String (Full_Lib_File));
+ Dir_Name (Get_Name_String (Full_Lib_File));
Obj : constant String := Object_File_Name (Lib_File);
Adt : constant String := Tree_File_Name (Lib_File);
Asm : constant String := Assembly_File_Name (Lib_File);
@@ -489,9 +489,9 @@ package body Clean is
for J in 1 .. Sources.Last loop
declare
Deb : constant String :=
- Debug_File_Name (Sources.Table (J));
+ Debug_File_Name (Sources.Table (J));
Rep : constant String :=
- Repinfo_File_Name (Sources.Table (J));
+ Repinfo_File_Name (Sources.Table (J));
begin
if Is_Regular_File (Obj_Dir & Dir_Separator & Deb) then
@@ -513,9 +513,9 @@ package body Clean is
if not Compile_Only then
declare
Source : constant File_Name_Type :=
- Strip_Suffix (Main_Lib_File);
+ Strip_Suffix (Main_Lib_File);
Executable : constant String :=
- Get_Name_String (Executable_Name (Source));
+ Get_Name_String (Executable_Name (Source));
begin
if Is_Regular_File (Executable) then
Delete ("", Executable);
@@ -548,7 +548,7 @@ package body Clean is
then
declare
Directory : constant String :=
- Get_Name_String (Project.Library_Src_Dir.Display_Name);
+ Get_Name_String (Project.Library_Src_Dir.Display_Name);
begin
Change_Dir (Directory);
@@ -631,9 +631,9 @@ package body Clean is
Lib_Filename : constant String := Get_Name_String (Project.Library_Name);
DLL_Name : String :=
- DLL_Prefix & Lib_Filename & "." & DLL_Ext;
+ DLL_Prefix & Lib_Filename & "." & DLL_Ext;
Archive_Name : String :=
- "lib" & Lib_Filename & "." & Archive_Ext;
+ "lib" & Lib_Filename & "." & Archive_Ext;
Direc : Dir_Type;
Name : String (1 .. 200);
@@ -656,11 +656,9 @@ package body Clean is
declare
Lib_Directory : constant String :=
- Get_Name_String
- (Project.Library_Dir.Display_Name);
+ Get_Name_String (Project.Library_Dir.Display_Name);
Lib_ALI_Directory : constant String :=
- Get_Name_String
- (Project.Library_ALI_Dir.Display_Name);
+ Get_Name_String (Project.Library_ALI_Dir.Display_Name);
begin
Canonical_Case_File_Name (Archive_Name);
@@ -863,8 +861,7 @@ package body Clean is
if Project.Object_Directory /= No_Path_Information then
declare
Obj_Dir : constant String :=
- Get_Name_String
- (Project.Object_Directory.Display_Name);
+ Get_Name_String (Project.Object_Directory.Display_Name);
begin
Change_Dir (Obj_Dir);
@@ -933,17 +930,17 @@ package body Clean is
declare
Asm : constant String :=
- Assembly_File_Name (Lib_File);
+ Assembly_File_Name (Lib_File);
ALI : constant String :=
- ALI_File_Name (Lib_File);
+ ALI_File_Name (Lib_File);
Obj : constant String :=
- Object_File_Name (Lib_File);
+ Object_File_Name (Lib_File);
Adt : constant String :=
- Tree_File_Name (Lib_File);
+ Tree_File_Name (Lib_File);
Deb : constant String :=
- Debug_File_Name (File_Name1);
+ Debug_File_Name (File_Name1);
Rep : constant String :=
- Repinfo_File_Name (File_Name1);
+ Repinfo_File_Name (File_Name1);
Del : Boolean := True;
begin
@@ -1010,9 +1007,9 @@ package body Clean is
if File_Name2 /= No_File then
declare
Deb : constant String :=
- Debug_File_Name (File_Name2);
+ Debug_File_Name (File_Name2);
Rep : constant String :=
- Repinfo_File_Name (File_Name2);
+ Repinfo_File_Name (File_Name2);
begin
if Is_Regular_File (Deb) then
@@ -1155,7 +1152,7 @@ package body Clean is
then
declare
Exec_Dir : constant String :=
- Get_Name_String (Project.Exec_Directory.Display_Name);
+ Get_Name_String (Project.Exec_Directory.Display_Name);
begin
Change_Dir (Exec_Dir);
@@ -1173,7 +1170,7 @@ package body Clean is
declare
Exec_File_Name : constant String :=
- Get_Name_String (Executable);
+ Get_Name_String (Executable);
begin
if Is_Absolute_Path (Name => Exec_File_Name) then
diff --git a/gcc/ada/cstand.adb b/gcc/ada/cstand.adb
index c77afd2dc..82f8697bc 100644
--- a/gcc/ada/cstand.adb
+++ b/gcc/ada/cstand.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -505,13 +505,12 @@ package body CStand is
procedure Pack_String_Type (String_Type : Entity_Id) is
Prag : constant Node_Id :=
- Make_Pragma (Stloc,
- Chars => Name_Pack,
- Pragma_Argument_Associations =>
- New_List (
- Make_Pragma_Argument_Association (Stloc,
- Expression =>
- New_Occurrence_Of (String_Type, Stloc))));
+ Make_Pragma (Stloc,
+ Chars => Name_Pack,
+ Pragma_Argument_Associations =>
+ New_List (
+ Make_Pragma_Argument_Association (Stloc,
+ Expression => New_Occurrence_Of (String_Type, Stloc))));
begin
Append (Prag, Decl_S);
Record_Rep_Item (String_Type, Prag);
diff --git a/gcc/ada/debug.adb b/gcc/ada/debug.adb
index 33f99c68c..f6f24f9c7 100644
--- a/gcc/ada/debug.adb
+++ b/gcc/ada/debug.adb
@@ -129,7 +129,7 @@ package body Debug is
-- d.I SCIL generation mode
-- d.J Disable parallel SCIL generation mode
-- d.K Alfa detection only mode for gnat2why
- -- d.L Depend on back end for limited types in conditional expressions
+ -- d.L Depend on back end for limited types in if and case expressions
-- d.M
-- d.N Add node to all entities
-- d.O Dump internal SCO tables
diff --git a/gcc/ada/einfo.adb b/gcc/ada/einfo.adb
index 6ef644a94..bfa7593dc 100644
--- a/gcc/ada/einfo.adb
+++ b/gcc/ada/einfo.adb
@@ -6214,25 +6214,25 @@ package body Einfo is
-- Global flag table allowing rapid computation of this function
Entity_Is_Base_Type : constant array (Entity_Kind) of Boolean :=
- (E_Enumeration_Subtype |
- E_Incomplete_Type |
- E_Signed_Integer_Subtype |
- E_Modular_Integer_Subtype |
- E_Floating_Point_Subtype |
- E_Ordinary_Fixed_Point_Subtype |
- E_Decimal_Fixed_Point_Subtype |
- E_Array_Subtype |
- E_String_Subtype |
- E_Record_Subtype |
- E_Private_Subtype |
- E_Record_Subtype_With_Private |
- E_Limited_Private_Subtype |
- E_Access_Subtype |
- E_Protected_Subtype |
- E_Task_Subtype |
- E_String_Literal_Subtype |
- E_Class_Wide_Subtype => False,
- others => True);
+ (E_Enumeration_Subtype |
+ E_Incomplete_Type |
+ E_Signed_Integer_Subtype |
+ E_Modular_Integer_Subtype |
+ E_Floating_Point_Subtype |
+ E_Ordinary_Fixed_Point_Subtype |
+ E_Decimal_Fixed_Point_Subtype |
+ E_Array_Subtype |
+ E_String_Subtype |
+ E_Record_Subtype |
+ E_Private_Subtype |
+ E_Record_Subtype_With_Private |
+ E_Limited_Private_Subtype |
+ E_Access_Subtype |
+ E_Protected_Subtype |
+ E_Task_Subtype |
+ E_String_Literal_Subtype |
+ E_Class_Wide_Subtype => False,
+ others => True);
function Is_Base_Type (Id : E) return Boolean is
begin
@@ -7113,6 +7113,7 @@ package body Einfo is
S := Subprograms_For_Type (Id);
Set_Subprograms_For_Type (Id, V);
+ Set_Subprograms_For_Type (V, S);
while Present (S) loop
if Has_Invariants (S) then
@@ -7121,8 +7122,6 @@ package body Einfo is
S := Subprograms_For_Type (S);
end if;
end loop;
-
- Set_Subprograms_For_Type (Id, V);
end Set_Invariant_Procedure;
----------------------------
@@ -7137,6 +7136,7 @@ package body Einfo is
S := Subprograms_For_Type (Id);
Set_Subprograms_For_Type (Id, V);
+ Set_Subprograms_For_Type (V, S);
while Present (S) loop
if Has_Predicates (S) then
@@ -7145,8 +7145,6 @@ package body Einfo is
S := Subprograms_For_Type (S);
end if;
end loop;
-
- Set_Subprograms_For_Type (Id, V);
end Set_Predicate_Function;
-----------------
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 3da53018f..bf360161b 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -3681,7 +3681,7 @@ package Einfo is
-- Status_Flag_Or_Transient_Decl (Node15)
-- Present in variables and constants. Applies to objects that require
-- special treatment by the finalization machinery. Such examples are
--- extended return results, conditional expression results and objects
+-- extended return results, if and case expression results and objects
-- inside N_Expression_With_Actions nodes. The attribute contains the
-- entity of a flag which specifies particular behavior over a region
-- of code or the declaration of a "hook" object.
diff --git a/gcc/ada/errout.adb b/gcc/ada/errout.adb
index b342b7540..64062b29e 100644
--- a/gcc/ada/errout.adb
+++ b/gcc/ada/errout.adb
@@ -198,6 +198,21 @@ package body Errout is
-- spec for precise definition of the conversion that is performed by this
-- routine in OpenVMS mode.
+ --------------------
+ -- Cascaded_Error --
+ --------------------
+
+ procedure Cascaded_Error is
+ begin
+ -- An anomaly has been detected which is assumed to be a consequence of
+ -- a previous error. Raise an exception if no serious error has been
+ -- found so far.
+
+ if Serious_Errors_Detected = 0 then
+ raise Program_Error;
+ end if;
+ end Cascaded_Error;
+
-----------------------
-- Change_Error_Text --
-----------------------
@@ -2445,7 +2460,7 @@ package body Errout is
if Sloc (Error_Msg_Node_1) > Standard_Location then
declare
Iloc : constant Source_Ptr :=
- Instantiation_Location (Sloc (Error_Msg_Node_1));
+ Instantiation_Location (Sloc (Error_Msg_Node_1));
begin
if Iloc /= No_Location
@@ -2938,7 +2953,7 @@ package body Errout is
if Is_Itype (Ent) then
declare
Assoc : constant Node_Id :=
- Associated_Node_For_Itype (Ent);
+ Associated_Node_For_Itype (Ent);
begin
if Nkind (Assoc) in N_Subprogram_Specification then
diff --git a/gcc/ada/errout.ads b/gcc/ada/errout.ads
index 13ce3ac42..7da6493e4 100644
--- a/gcc/ada/errout.ads
+++ b/gcc/ada/errout.ads
@@ -230,7 +230,7 @@ package Errout is
-- one (the plus one is because the number is stored 0-origin and
-- displayed 1-origin).
- -- Insertion character ^ (Carret: insert integer value)
+ -- Insertion character ^ (Caret: insert integer value)
-- The character ^ is replaced by the decimal conversion of the Uint
-- value stored in Error_Msg_Uint_1, with a possible leading minus.
-- A second ^ may occur in the message, in which case it is replaced
@@ -727,6 +727,13 @@ package Errout is
-- This routine can only be called during semantic analysis. It may not
-- be called during parsing.
+ procedure Cascaded_Error;
+ -- When an anomaly is detected, many semantic routines silently bail out,
+ -- assuming that the anomaly was caused by a previously detected error.
+ -- This routine should be called in these cases, and will raise an
+ -- exception if no serious error has been detected. This ensure that the
+ -- anomaly is never allowed to go unnoticed.
+
procedure Change_Error_Text (Error_Id : Error_Msg_Id; New_Msg : String);
-- The error message text of the message identified by Id is replaced by
-- the given text. This text may contain insertion characters in the
diff --git a/gcc/ada/eval_fat.adb b/gcc/ada/eval_fat.adb
index 3d0bff6a3..8ebeb1176 100644
--- a/gcc/ada/eval_fat.adb
+++ b/gcc/ada/eval_fat.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -41,7 +41,7 @@ package body Eval_Fat is
type Radix_Power_Table is array (Int range 1 .. 4) of Int;
Radix_Powers : constant Radix_Power_Table :=
- (Radix ** 1, Radix ** 2, Radix ** 3, Radix ** 4);
+ (Radix ** 1, Radix ** 2, Radix ** 3, Radix ** 4);
-----------------------
-- Local Subprograms --
@@ -188,7 +188,7 @@ package body Eval_Fat is
-- True iff Fraction is even
Most_Significant_Digit : constant UI :=
- Radix ** (Machine_Mantissa_Value (RT) - 1);
+ Radix ** (Machine_Mantissa_Value (RT) - 1);
Uintp_Mark : Uintp.Save_Mark;
-- The code is divided into blocks that systematically release
diff --git a/gcc/ada/exp_aggr.adb b/gcc/ada/exp_aggr.adb
index bcfca25c6..1d42bf899 100644
--- a/gcc/ada/exp_aggr.adb
+++ b/gcc/ada/exp_aggr.adb
@@ -239,12 +239,13 @@ package body Exp_Aggr is
-- N is the N_Aggregate node to be expanded.
function Is_Two_Dim_Packed_Array (Typ : Entity_Id) return Boolean;
-
-- For two-dimensional packed aggregates with constant bounds and constant
-- components, it is preferable to pack the inner aggregates because the
-- whole matrix can then be presented to the back-end as a one-dimensional
-- list of literals. This is much more efficient than expanding into single
- -- component assignments.
+ -- component assignments. This function determines if the type Typ is for
+ -- an array that is suitable for this optimization: it returns True if Typ
+ -- is a two dimensional bit packed array with component size 1, 2, or 4.
function Late_Expansion
(N : Node_Id;
@@ -320,17 +321,13 @@ package body Exp_Aggr is
-- components.
Max_Aggr_Size : constant Nat :=
- 5000 + (2 ** 24 - 5000) *
- Boolean'Pos
- (Restriction_Active (No_Elaboration_Code)
- or else
- Restriction_Active (No_Implicit_Loops)
- or else
- Is_Two_Dim_Packed_Array (Typ)
- or else
- ((Ekind (Current_Scope) = E_Package
- and then
- Static_Elaboration_Desired (Current_Scope))));
+ 5000 + (2 ** 24 - 5000) *
+ Boolean'Pos
+ (Restriction_Active (No_Elaboration_Code)
+ or else Restriction_Active (No_Implicit_Loops)
+ or else Is_Two_Dim_Packed_Array (Typ)
+ or else ((Ekind (Current_Scope) = E_Package
+ and then Static_Elaboration_Desired (Current_Scope))));
function Component_Count (T : Entity_Id) return Int;
-- The limit is applied to the total number of components that the
@@ -362,9 +359,9 @@ package body Exp_Aggr is
elsif Is_Array_Type (T) then
declare
Lo : constant Node_Id :=
- Type_Low_Bound (Etype (First_Index (T)));
+ Type_Low_Bound (Etype (First_Index (T)));
Hi : constant Node_Id :=
- Type_High_Bound (Etype (First_Index (T)));
+ Type_High_Bound (Etype (First_Index (T)));
Siz : constant Int := Component_Count (Component_Type (T));
@@ -422,9 +419,8 @@ package body Exp_Aggr is
then
declare
Index_Type : constant Entity_Id :=
- Etype
- (First_Index
- (Etype (Defining_Identifier (Parent (N)))));
+ Etype
+ (First_Index (Etype (Defining_Identifier (Parent (N)))));
Indx : Node_Id;
begin
@@ -2525,8 +2521,7 @@ package body Exp_Aggr is
and then CPP_Num_Prims (Typ) > 0
then
Invoke_Constructor : declare
- CPP_Parent : constant Entity_Id :=
- Enclosing_CPP_Parent (Typ);
+ CPP_Parent : constant Entity_Id := Enclosing_CPP_Parent (Typ);
procedure Invoke_IC_Proc (T : Entity_Id);
-- Recursive routine used to climb to parents. Required because
@@ -2719,19 +2714,18 @@ package body Exp_Aggr is
SubE : constant Entity_Id := Make_Temporary (Loc, 'T');
SubD : constant Node_Id :=
- Make_Subtype_Declaration (Loc,
- Defining_Identifier => SubE,
- Subtype_Indication =>
- Make_Subtype_Indication (Loc,
- Subtype_Mark =>
- New_Reference_To
- (Etype (Comp_Type), Loc),
- Constraint =>
- Make_Index_Or_Discriminant_Constraint
- (Loc,
- Constraints => New_List (
- New_Copy_Tree
- (Aggregate_Bounds (Expr_Q))))));
+ Make_Subtype_Declaration (Loc,
+ Defining_Identifier => SubE,
+ Subtype_Indication =>
+ Make_Subtype_Indication (Loc,
+ Subtype_Mark =>
+ New_Reference_To (Etype (Comp_Type), Loc),
+ Constraint =>
+ Make_Index_Or_Discriminant_Constraint
+ (Loc,
+ Constraints => New_List (
+ New_Copy_Tree
+ (Aggregate_Bounds (Expr_Q))))));
-- Create a temporary array of the above subtype which
-- will be used to capture the aggregate assignments.
@@ -2739,10 +2733,9 @@ package body Exp_Aggr is
TmpE : constant Entity_Id := Make_Temporary (Loc, 'A', N);
TmpD : constant Node_Id :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => TmpE,
- Object_Definition =>
- New_Reference_To (SubE, Loc));
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => TmpE,
+ Object_Definition => New_Reference_To (SubE, Loc));
begin
Set_No_Initialization (TmpD);
@@ -2963,9 +2956,8 @@ package body Exp_Aggr is
Temp : constant Entity_Id := Defining_Identifier (Decl);
Occ : constant Node_Id :=
- Unchecked_Convert_To (Typ,
- Make_Explicit_Dereference (Loc,
- New_Reference_To (Temp, Loc)));
+ Unchecked_Convert_To (Typ,
+ Make_Explicit_Dereference (Loc, New_Reference_To (Temp, Loc)));
begin
if Is_Array_Type (Typ) then
@@ -3548,7 +3540,7 @@ package body Exp_Aggr is
declare
P : constant Entity_Id :=
- Cunit_Entity (Current_Sem_Unit);
+ Cunit_Entity (Current_Sem_Unit);
begin
-- Check if duplication OK and if so continue
@@ -3847,7 +3839,7 @@ package body Exp_Aggr is
-- possible, provided other conditions are met on the LHS.
Others_Present : array (1 .. Aggr_Dimension) of Boolean :=
- (others => False);
+ (others => False);
-- If Others_Present (J) is True, then there is an others choice
-- in one of the sub-aggregates of N at dimension J.
@@ -5792,11 +5784,10 @@ package body Exp_Aggr is
elsif Tagged_Type_Expansion then
declare
Tag_Name : constant Node_Id :=
- New_Occurrence_Of
- (First_Tag_Component (Typ), Loc);
+ New_Occurrence_Of (First_Tag_Component (Typ), Loc);
Typ_Tag : constant Entity_Id := RTE (RE_Tag);
Conv_Node : constant Node_Id :=
- Unchecked_Convert_To (Typ_Tag, Tag_Value);
+ Unchecked_Convert_To (Typ_Tag, Tag_Value);
begin
Set_Etype (Conv_Node, Typ_Tag);
@@ -5924,8 +5915,7 @@ package body Exp_Aggr is
begin
return Number_Dimensions (Typ) = 2
and then Is_Bit_Packed_Array (Typ)
- and then
- (C = 1 or else C = 2 or else C = 4);
+ and then (C = 1 or else C = 2 or else C = 4);
end Is_Two_Dim_Packed_Array;
--------------------
@@ -6177,21 +6167,30 @@ package body Exp_Aggr is
Expr : Node_Id;
-- Next expression from positional parameters of aggregate
+ Left_Justified : Boolean;
+ -- Set True if we are filling the high order bits of the target
+ -- value (i.e. the value is left justified).
+
begin
-- For little endian, we fill up the low order bits of the target
-- value. For big endian we fill up the high order bits of the
-- target value (which is a left justified modular value).
- -- Above comment needs extending for the code below, which is by
- -- the way incomprehensible, I have no idea what a xor b xor c
- -- means, and it hurts my brain to try to figure it out???
- -- Let's introduce a new variable, perhaps Effectively_Big_Endian
- -- and compute it with clearer code ???
+ Left_Justified := Bytes_Big_Endian;
- if Bytes_Big_Endian
- xor Debug_Flag_8
- xor Reverse_Storage_Order (Base_Type (Typ))
- then
+ -- Switch justification if using -gnatd8
+
+ if Debug_Flag_8 then
+ Left_Justified := not Left_Justified;
+ end if;
+
+ -- Switch justfification if reverse storage order
+
+ if Reverse_Storage_Order (Base_Type (Typ)) then
+ Left_Justified := not Left_Justified;
+ end if;
+
+ if Left_Justified then
Shift := Csiz * (Len - 1);
Incr := -Csiz;
else
diff --git a/gcc/ada/exp_attr.adb b/gcc/ada/exp_attr.adb
index 105df466b..04930a9bd 100644
--- a/gcc/ada/exp_attr.adb
+++ b/gcc/ada/exp_attr.adb
@@ -3324,13 +3324,13 @@ package body Exp_Attr is
-- Furthermore, (-value - 1) can be expressed as -(value + 1)
-- which we can compute using the integer base type.
- -- Once this is done we analyze the conditional expression without
- -- range checks, because we know everything is in range, and we
- -- want to prevent spurious warnings on either branch.
+ -- Once this is done we analyze the if expression without range
+ -- checks, because we know everything is in range, and we want
+ -- to prevent spurious warnings on either branch.
else
Rewrite (N,
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Ge (Loc,
Left_Opnd => Duplicate_Subexpr (Arg),
@@ -3500,7 +3500,7 @@ package body Exp_Attr is
Right_Opnd => Y_Addr);
Rewrite (N,
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
New_List (
Cond,
@@ -5643,8 +5643,8 @@ package body Exp_Attr is
Analyze_And_Resolve (N, Standard_Boolean);
- -- For record types, we build a big conditional expression, applying
- -- Valid or Valid_Scalars as appropriate to all relevant components.
+ -- For record types, we build a big if expression, applying Valid or
+ -- Valid_Scalars as appropriate to all relevant components.
elsif (Is_Record_Type (Ptyp) or else Has_Discriminants (Ptyp))
and then not No_Scalar_Parts (Ptyp)
diff --git a/gcc/ada/exp_ch2.adb b/gcc/ada/exp_ch2.adb
index d9143673b..37a5bda65 100644
--- a/gcc/ada/exp_ch2.adb
+++ b/gcc/ada/exp_ch2.adb
@@ -177,7 +177,7 @@ package body Exp_Ch2 is
if Nkind (CV) in N_Subexpr then
Val := CV;
- -- Case of Current_Value is a conditional expression reference
+ -- Case of Current_Value is an if expression reference
else
Get_Current_Value_Condition (N, Op, Val);
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 066b37d17..af5dadd9a 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -88,6 +88,22 @@ package body Exp_Ch3 is
-- used for attachment of any actions required in its construction.
-- It also supplies the source location used for the procedure.
+ function Build_Array_Invariant_Proc
+ (A_Type : Entity_Id;
+ Nod : Node_Id) return Node_Id;
+ -- If the component of type of array type has invariants, build procedure
+ -- that checks invariant on all components of the array. Ada 2012 specifies
+ -- that an invariant on some type T must be applied to in-out parameters
+ -- and return values that include a part of type T. If the array type has
+ -- an otherwise specified invariant, the component check procedure is
+ -- called from within the user-specified invariant. Otherwise this becomes
+ -- the invariant procedure for the array type.
+
+ function Build_Record_Invariant_Proc
+ (R_Type : Entity_Id;
+ Nod : Node_Id) return Node_Id;
+ -- Ditto for record types.
+
function Build_Discriminant_Formals
(Rec_Id : Entity_Id;
Use_Dl : Boolean) return List_Id;
@@ -180,6 +196,14 @@ package body Exp_Ch3 is
-- Treat user-defined stream operations as renaming_as_body if the
-- subprogram they rename is not frozen when the type is frozen.
+ procedure Insert_Component_Invariant_Checks
+ (N : Node_Id;
+ Typ : Entity_Id;
+ Proc : Node_Id);
+ -- If a composite type has invariants and also has components with defined
+ -- invariants. the component invariant procedure is inserted into the user-
+ -- defined invariant procedure and added to the checks to be performed.
+
procedure Initialization_Warning (E : Entity_Id);
-- If static elaboration of the package is requested, indicate
-- when a type does meet the conditions for static initialization. If
@@ -635,7 +659,7 @@ package body Exp_Ch3 is
-- but it properly belongs with the array type declaration. However, if
-- the freeze node is for a subtype of a type declared in another unit
-- it seems preferable to use the freeze node as the source location of
- -- of the init proc. In any case this is preferable for gcov usage, and
+ -- the init proc. In any case this is preferable for gcov usage, and
-- the Sloc is not otherwise used by the compiler.
if In_Open_Scopes (Scope (A_Type)) then
@@ -784,7 +808,10 @@ package body Exp_Ch3 is
-- Build_Array_Invariant_Proc --
--------------------------------
- procedure Build_Array_Invariant_Proc (A_Type : Entity_Id; Nod : Node_Id) is
+ function Build_Array_Invariant_Proc
+ (A_Type : Entity_Id;
+ Nod : Node_Id) return Node_Id
+ is
Loc : constant Source_Ptr := Sloc (Nod);
Object_Name : constant Name_Id := New_Internal_Name ('I');
@@ -878,9 +905,7 @@ package body Exp_Ch3 is
Proc_Id :=
Make_Defining_Identifier (Loc,
- Chars => New_External_Name (Chars (A_Type), "Invariant"));
- Set_Has_Invariants (Proc_Id);
- Set_Invariant_Procedure (A_Type, Proc_Id);
+ Chars => New_External_Name (Chars (A_Type), "CInvariant"));
Body_Stmts := Check_One_Dimension (1);
@@ -908,10 +933,7 @@ package body Exp_Ch3 is
Set_Debug_Info_Off (Proc_Id);
end if;
- -- The procedure body is placed after the freeze node for the type.
-
- Insert_After (Nod, Proc_Body);
- Analyze (Proc_Body);
+ return Proc_Body;
end Build_Array_Invariant_Proc;
--------------------------------
@@ -3611,6 +3633,207 @@ package body Exp_Ch3 is
end if;
end Build_Record_Init_Proc;
+ --------------------------------
+ -- Build_Record_Invariant_Proc --
+ --------------------------------
+
+ function Build_Record_Invariant_Proc
+ (R_Type : Entity_Id;
+ Nod : Node_Id) return Node_Id
+ is
+ Loc : constant Source_Ptr := Sloc (Nod);
+
+ Object_Name : constant Name_Id := New_Internal_Name ('I');
+ -- Name for argument of invariant procedure
+
+ Object_Entity : constant Node_Id :=
+ Make_Defining_Identifier (Loc, Object_Name);
+ -- The procedure declaration entity for the argument
+
+ Invariant_Found : Boolean;
+ -- Set if any component needs an invariant check.
+
+ Proc_Id : Entity_Id;
+ Proc_Body : Node_Id;
+ Stmts : List_Id;
+ Type_Def : Node_Id;
+
+ function Build_Invariant_Checks (Comp_List : Node_Id) return List_Id;
+ -- Recursive procedure that generates a list of checks for components
+ -- that need it, and recurses through variant parts when present.
+
+ function Build_Component_Invariant_Call (Comp : Entity_Id)
+ return Node_Id;
+ -- Build call to invariant procedure for a record component.
+
+ ------------------------------------
+ -- Build_Component_Invariant_Call --
+ ------------------------------------
+
+ function Build_Component_Invariant_Call (Comp : Entity_Id)
+ return Node_Id
+ is
+ Sel_Comp : Node_Id;
+ Typ : Entity_Id;
+ Call : Node_Id;
+
+ begin
+ Invariant_Found := True;
+ Typ := Etype (Comp);
+
+ Sel_Comp :=
+ Make_Selected_Component (Loc,
+ Prefix => New_Occurrence_Of (Object_Entity, Loc),
+ Selector_Name => New_Occurrence_Of (Comp, Loc));
+
+ if Is_Access_Type (Typ) then
+ Sel_Comp := Make_Explicit_Dereference (Loc, Sel_Comp);
+ Typ := Designated_Type (Typ);
+ end if;
+
+ Call :=
+ Make_Procedure_Call_Statement (Loc,
+ Name =>
+ New_Occurrence_Of (Invariant_Procedure (Typ), Loc),
+ Parameter_Associations => New_List (Sel_Comp));
+
+ if Is_Access_Type (Etype (Comp)) then
+ Call :=
+ Make_If_Statement (Loc,
+ Condition =>
+ Make_Op_Ne (Loc,
+ Left_Opnd => Make_Null (Loc),
+ Right_Opnd =>
+ Make_Selected_Component (Loc,
+ Prefix => New_Occurrence_Of (Object_Entity, Loc),
+ Selector_Name => New_Occurrence_Of (Comp, Loc))),
+ Then_Statements => New_List (Call));
+ end if;
+
+ return Call;
+ end Build_Component_Invariant_Call;
+
+ ----------------------------
+ -- Build_Invariant_Checks --
+ ----------------------------
+
+ function Build_Invariant_Checks (Comp_List : Node_Id) return List_Id is
+ Decl : Node_Id;
+ Id : Entity_Id;
+ Stmts : List_Id;
+
+ begin
+ Stmts := New_List;
+ Decl := First_Non_Pragma (Component_Items (Comp_List));
+ while Present (Decl) loop
+ if Nkind (Decl) = N_Component_Declaration then
+ Id := Defining_Identifier (Decl);
+
+ if Has_Invariants (Etype (Id))
+ and then In_Open_Scopes (Scope (R_Type))
+ then
+ Append_To (Stmts, Build_Component_Invariant_Call (Id));
+
+ elsif Is_Access_Type (Etype (Id))
+ and then not Is_Access_Constant (Etype (Id))
+ and then Has_Invariants (Designated_Type (Etype (Id)))
+ and then In_Open_Scopes (Scope (Designated_Type (Etype (Id))))
+ then
+ Append_To (Stmts, Build_Component_Invariant_Call (Id));
+ end if;
+ end if;
+
+ Next (Decl);
+ end loop;
+
+ if Present (Variant_Part (Comp_List)) then
+ declare
+ Variant_Alts : constant List_Id := New_List;
+ Var_Loc : Source_Ptr;
+ Variant : Node_Id;
+ Variant_Stmts : List_Id;
+
+ begin
+ Variant :=
+ First_Non_Pragma (Variants (Variant_Part (Comp_List)));
+ while Present (Variant) loop
+ Variant_Stmts :=
+ Build_Invariant_Checks (Component_List (Variant));
+ Var_Loc := Sloc (Variant);
+ Append_To (Variant_Alts,
+ Make_Case_Statement_Alternative (Var_Loc,
+ Discrete_Choices =>
+ New_Copy_List (Discrete_Choices (Variant)),
+ Statements => Variant_Stmts));
+
+ Next_Non_Pragma (Variant);
+ end loop;
+
+ -- The expression in the case statement is the reference to
+ -- the discriminant of the target object.
+
+ Append_To (Stmts,
+ Make_Case_Statement (Var_Loc,
+ Expression =>
+ Make_Selected_Component (Var_Loc,
+ Prefix => New_Occurrence_Of (Object_Entity, Var_Loc),
+ Selector_Name => New_Occurrence_Of
+ (Entity
+ (Name (Variant_Part (Comp_List))), Var_Loc)),
+ Alternatives => Variant_Alts));
+ end;
+ end if;
+
+ return Stmts;
+ end Build_Invariant_Checks;
+
+ -- Start of processing for Build_Record_Invariant_Proc
+
+ begin
+ Invariant_Found := False;
+ Type_Def := Type_Definition (Parent (R_Type));
+
+ if Nkind (Type_Def) = N_Record_Definition
+ and then not Null_Present (Type_Def)
+ then
+ Stmts := Build_Invariant_Checks (Component_List (Type_Def));
+ else
+ return Empty;
+ end if;
+
+ if not Invariant_Found then
+ return Empty;
+ end if;
+
+ Proc_Id :=
+ Make_Defining_Identifier (Loc,
+ Chars => New_External_Name (Chars (R_Type), "Invariant"));
+
+ Proc_Body :=
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => Proc_Id,
+ Parameter_Specifications => New_List (
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier => Object_Entity,
+ Parameter_Type => New_Occurrence_Of (R_Type, Loc)))),
+
+ Declarations => Empty_List,
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => Stmts));
+
+ Set_Ekind (Proc_Id, E_Procedure);
+ Set_Is_Public (Proc_Id, Is_Public (R_Type));
+ Set_Is_Internal (Proc_Id);
+ Set_Has_Completion (Proc_Id);
+
+ return Proc_Body;
+ -- Insert_After (Nod, Proc_Body);
+ -- Analyze (Proc_Body);
+ end Build_Record_Invariant_Proc;
+
----------------------------
-- Build_Slice_Assignment --
----------------------------
@@ -4910,8 +5133,15 @@ package body Exp_Ch3 is
-- Expr's type, both types share the same dispatch table and there is
-- no need to displace the pointer.
- elsif Comes_From_Source (N)
- and then Is_Interface (Typ)
+ elsif Is_Interface (Typ)
+
+ -- Avoid never-ending recursion because if Equivalent_Type is set
+ -- then we've done it already and must not do it again!
+
+ and then not
+ (Nkind (Object_Definition (N)) = N_Identifier
+ and then
+ Present (Equivalent_Type (Entity (Object_Definition (N)))))
then
pragma Assert (Is_Class_Wide_Type (Typ));
@@ -5195,6 +5425,8 @@ package body Exp_Ch3 is
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
declare
Full_Typ : constant Entity_Id := Underlying_Type (Typ);
@@ -5661,8 +5893,17 @@ package body Exp_Ch3 is
Build_Array_Init_Proc (Base, N);
end if;
- if Has_Invariants (Component_Type (Base)) then
- Build_Array_Invariant_Proc (Base, N);
+ if Has_Invariants (Component_Type (Base))
+ and then In_Open_Scopes (Scope (Component_Type (Base)))
+ then
+ -- Generate component invariant checking procedure. This is only
+ -- relevant if the array type is within the scope of the component
+ -- type. Otherwise an array object can only be built using the public
+ -- subprograms for the component type, and calls to those will have
+ -- invariant checks.
+
+ Insert_Component_Invariant_Checks
+ (N, Base, Build_Array_Invariant_Proc (Base, N));
end if;
end Expand_Freeze_Array_Type;
@@ -6630,6 +6871,12 @@ package body Exp_Ch3 is
end loop;
end;
end if;
+
+ -- Check whether individual components have a defined invariant,
+ -- and add the corresponding component invariant checks.
+
+ Insert_Component_Invariant_Checks
+ (N, Def_Id, Build_Record_Invariant_Proc (Def_Id, N));
end Expand_Freeze_Record_Type;
------------------------------
@@ -7394,6 +7641,63 @@ package body Exp_Ch3 is
return Is_RTU (S1, System) or else Is_RTU (S1, Ada);
end In_Runtime;
+ ---------------------------------------
+ -- Insert_Component_Invariant_Checks --
+ ---------------------------------------
+
+ procedure Insert_Component_Invariant_Checks
+ (N : Node_Id;
+ Typ : Entity_Id;
+ Proc : Node_Id)
+ is
+ Loc : constant Source_Ptr := Sloc (Typ);
+ Proc_Id : Entity_Id;
+
+ begin
+ if Present (Proc) then
+ Proc_Id := Defining_Entity (Proc);
+
+ if not Has_Invariants (Typ) then
+ Set_Has_Invariants (Typ);
+ Set_Has_Invariants (Proc_Id);
+ Set_Invariant_Procedure (Typ, Proc_Id);
+ Insert_After (N, Proc);
+ Analyze (Proc);
+
+ else
+
+ -- Find already created invariant body, insert body of component
+ -- invariant proc in it, and add call after other checks.
+
+ declare
+ Bod : Node_Id;
+ Inv_Id : constant Entity_Id := Invariant_Procedure (Typ);
+ Call : constant Node_Id :=
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Occurrence_Of (Proc_Id, Loc),
+ Parameter_Associations =>
+ New_List
+ (New_Reference_To (First_Formal (Inv_Id), Loc)));
+
+ begin
+
+ -- The invariant body has not been analyzed yet, so we do a
+ -- sequential search forward, and retrieve it by name.
+
+ Bod := Next (N);
+ while Present (Bod) loop
+ exit when Nkind (Bod) = N_Subprogram_Body
+ and then Chars (Defining_Entity (Bod)) = Chars (Inv_Id);
+ Next (Bod);
+ end loop;
+
+ Append_To (Declarations (Bod), Proc);
+ Append_To (Statements (Handled_Statement_Sequence (Bod)), Call);
+ end;
+ end if;
+ end if;
+ end Insert_Component_Invariant_Checks;
+
----------------------------
-- Initialization_Warning --
----------------------------
diff --git a/gcc/ada/exp_ch3.ads b/gcc/ada/exp_ch3.ads
index 1abc4567a..d43366812 100644
--- a/gcc/ada/exp_ch3.ads
+++ b/gcc/ada/exp_ch3.ads
@@ -46,12 +46,6 @@ package Exp_Ch3 is
procedure Expand_Record_Extension (T : Entity_Id; Def : Node_Id);
-- Add a field _parent in the extension part of the record
- procedure Build_Array_Invariant_Proc (A_Type : Entity_Id; Nod : Node_Id);
- -- If the component of type of array type has invariants, build procedure
- -- that checks invariant on all components of the array. Ada 2012 specifies
- -- that an invariant on some type T must be applied to in-out parameters
- -- and return values that include a part of type T.
-
procedure Build_Discr_Checking_Funcs (N : Node_Id);
-- Builds function which checks whether the component name is consistent
-- with the current discriminants. N is the full type declaration node,
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index 9cc8865b6..ee9ce0c50 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -140,6 +140,10 @@ package body Exp_Ch4 is
procedure Expand_Short_Circuit_Operator (N : Node_Id);
-- Common expansion processing for short-circuit boolean operators
+ procedure Expand_Compare_Minimize_Eliminate_Overflow (N : Node_Id);
+ -- Deal with comparison in MINIMIZED/ELIMINATED overflow mode. This is
+ -- where we allow comparison of "out of range" values.
+
function Expand_Composite_Equality
(Nod : Node_Id;
Typ : Entity_Id;
@@ -160,6 +164,12 @@ package body Exp_Ch4 is
-- concatenation. The operands can be of any appropriate type, and can
-- include both arrays and singleton elements.
+ procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id);
+ -- N is an N_In membership test mode, with the overflow check mode set to
+ -- MINIMIZED or ELIMINATED, and the type of the left operand is a signed
+ -- integer type. This is a case where top level processing is required to
+ -- handle overflow checks in subtrees.
+
procedure Fixup_Universal_Fixed_Operation (N : Node_Id);
-- N is a N_Op_Divide or N_Op_Multiply node whose result is universal
-- fixed. We do not have such a type at runtime, so the purpose of this
@@ -202,6 +212,21 @@ package body Exp_Ch4 is
-- constrained type (the caller has ensured this by using
-- Convert_To_Actual_Subtype if necessary).
+ function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean;
+ -- For signed arithmetic operations with Do_Overflow_Check set when the
+ -- current overflow mode is MINIMIZED or ELIMINATED, we need to make a
+ -- call to Apply_Arithmetic_Overflow_Checks as the first thing we do. We
+ -- then return. We count on the recursive apparatus for overflow checks
+ -- to call us back with an equivalent operation that does not have the
+ -- Do_Overflow_Check flag set, and that is when we will proceed with the
+ -- expansion of the operator (e.g. converting X+0 to X, or X**2 to X*X).
+ -- We cannot do these optimizations without first making this check, since
+ -- there may be operands further down the tree that are relying on the
+ -- recursive calls triggered by the top level nodes to properly process
+ -- overflow checking and remaining expansion on these nodes. Note that
+ -- this call back may be skipped if the operation is done in Bignum mode
+ -- but that's fine, since the Bignum call takes care of everything.
+
procedure Optimize_Length_Comparison (N : Node_Id);
-- Given an expression, if it is of the form X'Length op N (or the other
-- way round), where N is known at compile time to be 0 or 1, and X is a
@@ -842,6 +867,15 @@ package body Exp_Ch4 is
-- Start of processing for Expand_Allocator_Expression
begin
+ -- Handle call to C++ constructor
+
+ if Is_CPP_Constructor_Call (Exp) then
+ Make_CPP_Constructor_Call_In_Allocator
+ (Allocator => N,
+ Function_Call => Exp);
+ return;
+ end if;
+
-- In the case of an Ada 2012 allocator whose initial value comes from a
-- function call, pass "the accessibility level determined by the point
-- of call" (AI05-0234) to the function. Conceptually, this belongs in
@@ -871,61 +905,9 @@ package body Exp_Ch4 is
end;
end if;
- -- Would be nice to comment the branches of this very long if ???
+ -- Case of tagged type or type requiring finalization
if Is_Tagged_Type (T) or else Needs_Finalization (T) then
- if Is_CPP_Constructor_Call (Exp) then
-
- -- Generate:
- -- Pnnn : constant ptr_T := new (T);
- -- Init (Pnnn.all,...);
-
- -- Allocate the object without an expression
-
- Node := Relocate_Node (N);
- Set_Expression (Node, New_Reference_To (Etype (Exp), Loc));
-
- -- Avoid its expansion to avoid generating a call to the default
- -- C++ constructor.
-
- Set_Analyzed (Node);
-
- Temp := Make_Temporary (Loc, 'P', N);
-
- Temp_Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Temp,
- Constant_Present => True,
- Object_Definition => New_Reference_To (PtrT, Loc),
- Expression => Node);
- Insert_Action (N, Temp_Decl);
-
- Apply_Accessibility_Check (Temp);
-
- -- Locate the enclosing list and insert the C++ constructor call
-
- declare
- P : Node_Id;
-
- begin
- P := Parent (Node);
- while not Is_List_Member (P) loop
- P := Parent (P);
- end loop;
-
- Insert_List_After_And_Analyze (P,
- Build_Initialization_Call (Loc,
- Id_Ref =>
- Make_Explicit_Dereference (Loc,
- Prefix => New_Reference_To (Temp, Loc)),
- Typ => Etype (Exp),
- Constructor_Ref => Exp));
- end;
-
- Rewrite (N, New_Reference_To (Temp, Loc));
- Analyze_And_Resolve (N, PtrT);
- return;
- end if;
-- Ada 2005 (AI-318-02): If the initialization expression is a call
-- to a build-in-place function, then access to the allocated object
@@ -1089,7 +1071,8 @@ package body Exp_Ch4 is
Make_Access_To_Object_Definition (Loc,
All_Present => True,
Null_Exclusion_Present => False,
- Constant_Present => False,
+ Constant_Present =>
+ Is_Access_Constant (Etype (N)),
Subtype_Indication =>
New_Reference_To (Etype (Exp), Loc)));
@@ -2275,6 +2258,245 @@ package body Exp_Ch4 is
end;
end Expand_Boolean_Operator;
+ ------------------------------------------------
+ -- Expand_Compare_Minimize_Eliminate_Overflow --
+ ------------------------------------------------
+
+ procedure Expand_Compare_Minimize_Eliminate_Overflow (N : Node_Id) is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ Result_Type : constant Entity_Id := Etype (N);
+ -- Capture result type (could be a derived boolean type)
+
+ Llo, Lhi : Uint;
+ Rlo, Rhi : Uint;
+
+ LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
+ -- Entity for Long_Long_Integer'Base
+
+ Check : constant Overflow_Check_Type := Overflow_Check_Mode (Empty);
+ -- Current checking mode
+
+ procedure Set_True;
+ procedure Set_False;
+ -- These procedures rewrite N with an occurrence of Standard_True or
+ -- Standard_False, and then makes a call to Warn_On_Known_Condition.
+
+ ---------------
+ -- Set_False --
+ ---------------
+
+ procedure Set_False is
+ begin
+ Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
+ Warn_On_Known_Condition (N);
+ end Set_False;
+
+ --------------
+ -- Set_True --
+ --------------
+
+ procedure Set_True is
+ begin
+ Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
+ Warn_On_Known_Condition (N);
+ end Set_True;
+
+ -- Start of processing for Expand_Compare_Minimize_Eliminate_Overflow
+
+ begin
+ -- Nothing to do unless we have a comparison operator with operands
+ -- that are signed integer types, and we are operating in either
+ -- MINIMIZED or ELIMINATED overflow checking mode.
+
+ if Nkind (N) not in N_Op_Compare
+ or else Check not in Minimized_Or_Eliminated
+ or else not Is_Signed_Integer_Type (Etype (Left_Opnd (N)))
+ then
+ return;
+ end if;
+
+ -- OK, this is the case we are interested in. First step is to process
+ -- our operands using the Minimize_Eliminate circuitry which applies
+ -- this processing to the two operand subtrees.
+
+ Minimize_Eliminate_Overflow_Checks
+ (Left_Opnd (N), Llo, Lhi, Top_Level => False);
+ Minimize_Eliminate_Overflow_Checks
+ (Right_Opnd (N), Rlo, Rhi, Top_Level => False);
+
+ -- See if the range information decides the result of the comparison.
+ -- We can only do this if we in fact have full range information (which
+ -- won't be the case if either operand is bignum at this stage).
+
+ if Llo /= No_Uint and then Rlo /= No_Uint then
+ case N_Op_Compare (Nkind (N)) is
+ when N_Op_Eq =>
+ if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
+ Set_True;
+ elsif Llo > Rhi or else Lhi < Rlo then
+ Set_False;
+ end if;
+
+ when N_Op_Ge =>
+ if Llo >= Rhi then
+ Set_True;
+ elsif Lhi < Rlo then
+ Set_False;
+ end if;
+
+ when N_Op_Gt =>
+ if Llo > Rhi then
+ Set_True;
+ elsif Lhi <= Rlo then
+ Set_False;
+ end if;
+
+ when N_Op_Le =>
+ if Llo > Rhi then
+ Set_False;
+ elsif Lhi <= Rlo then
+ Set_True;
+ end if;
+
+ when N_Op_Lt =>
+ if Llo >= Rhi then
+ Set_False;
+ elsif Lhi < Rlo then
+ Set_True;
+ end if;
+
+ when N_Op_Ne =>
+ if Llo = Lhi and then Rlo = Rhi and then Llo = Rlo then
+ Set_False;
+ elsif Llo > Rhi or else Lhi < Rlo then
+ Set_True;
+ end if;
+ end case;
+
+ -- All done if we did the rewrite
+
+ if Nkind (N) not in N_Op_Compare then
+ return;
+ end if;
+ end if;
+
+ -- Otherwise, time to do the comparison
+
+ declare
+ Ltype : constant Entity_Id := Etype (Left_Opnd (N));
+ Rtype : constant Entity_Id := Etype (Right_Opnd (N));
+
+ begin
+ -- If the two operands have the same signed integer type we are
+ -- all set, nothing more to do. This is the case where either
+ -- both operands were unchanged, or we rewrote both of them to
+ -- be Long_Long_Integer.
+
+ -- Note: Entity for the comparison may be wrong, but it's not worth
+ -- the effort to change it, since the back end does not use it.
+
+ if Is_Signed_Integer_Type (Ltype)
+ and then Base_Type (Ltype) = Base_Type (Rtype)
+ then
+ return;
+
+ -- Here if bignums are involved (can only happen in ELIMINATED mode)
+
+ elsif Is_RTE (Ltype, RE_Bignum) or else Is_RTE (Rtype, RE_Bignum) then
+ declare
+ Left : Node_Id := Left_Opnd (N);
+ Right : Node_Id := Right_Opnd (N);
+ -- Bignum references for left and right operands
+
+ begin
+ if not Is_RTE (Ltype, RE_Bignum) then
+ Left := Convert_To_Bignum (Left);
+ elsif not Is_RTE (Rtype, RE_Bignum) then
+ Right := Convert_To_Bignum (Right);
+ end if;
+
+ -- We rewrite our node with:
+
+ -- do
+ -- Bnn : Result_Type;
+ -- declare
+ -- M : Mark_Id := SS_Mark;
+ -- begin
+ -- Bnn := Big_xx (Left, Right); (xx = EQ, NT etc)
+ -- SS_Release (M);
+ -- end;
+ -- in
+ -- Bnn
+ -- end
+
+ declare
+ Blk : constant Node_Id := Make_Bignum_Block (Loc);
+ Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
+ Ent : RE_Id;
+
+ begin
+ case N_Op_Compare (Nkind (N)) is
+ when N_Op_Eq => Ent := RE_Big_EQ;
+ when N_Op_Ge => Ent := RE_Big_GE;
+ when N_Op_Gt => Ent := RE_Big_GT;
+ when N_Op_Le => Ent := RE_Big_LE;
+ when N_Op_Lt => Ent := RE_Big_LT;
+ when N_Op_Ne => Ent := RE_Big_NE;
+ end case;
+
+ -- Insert assignment to Bnn into the bignum block
+
+ Insert_Before
+ (First (Statements (Handled_Statement_Sequence (Blk))),
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Bnn, Loc),
+ Expression =>
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (Ent), Loc),
+ Parameter_Associations => New_List (Left, Right))));
+
+ -- Now do the rewrite with expression actions
+
+ Rewrite (N,
+ Make_Expression_With_Actions (Loc,
+ Actions => New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Bnn,
+ Object_Definition =>
+ New_Occurrence_Of (Result_Type, Loc)),
+ Blk),
+ Expression => New_Occurrence_Of (Bnn, Loc)));
+ Analyze_And_Resolve (N, Result_Type);
+ end;
+ end;
+
+ -- No bignums involved, but types are different, so we must have
+ -- rewritten one of the operands as a Long_Long_Integer but not
+ -- the other one.
+
+ -- If left operand is Long_Long_Integer, convert right operand
+ -- and we are done (with a comparison of two Long_Long_Integers).
+
+ elsif Ltype = LLIB then
+ Convert_To_And_Rewrite (LLIB, Right_Opnd (N));
+ Analyze_And_Resolve (Right_Opnd (N), LLIB, Suppress => All_Checks);
+ return;
+
+ -- If right operand is Long_Long_Integer, convert left operand
+ -- and we are done (with a comparison of two Long_Long_Integers).
+
+ -- This is the only remaining possibility
+
+ else pragma Assert (Rtype = LLIB);
+ Convert_To_And_Rewrite (LLIB, Left_Opnd (N));
+ Analyze_And_Resolve (Left_Opnd (N), LLIB, Suppress => All_Checks);
+ return;
+ end if;
+ end;
+ end Expand_Compare_Minimize_Eliminate_Overflow;
+
-------------------------------
-- Expand_Composite_Equality --
-------------------------------
@@ -3147,7 +3369,7 @@ package body Exp_Ch4 is
Low_Bound := Opnd_Low_Bound (1);
-- OK, we don't know the lower bound, we have to build a horrible
- -- conditional expression node of the form
+ -- if expression node of the form
-- if Cond1'Length /= 0 then
-- Opnd1 low bound
@@ -3178,7 +3400,7 @@ package body Exp_Ch4 is
else
return
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Ne (Loc,
@@ -3232,7 +3454,7 @@ package body Exp_Ch4 is
if Result_May_Be_Null then
Low_Bound :=
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Eq (Loc,
Left_Opnd => New_Copy (Aggr_Length (NN)),
@@ -3241,7 +3463,7 @@ package body Exp_Ch4 is
Low_Bound));
High_Bound :=
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Eq (Loc,
Left_Opnd => New_Copy (Aggr_Length (NN)),
@@ -3466,9 +3688,403 @@ package body Exp_Ch4 is
(N => Cnode,
Msg => "concatenation result upper bound out of range?",
Reason => CE_Range_Check_Failed);
- -- Set_Etype (Cnode, Atyp);
end Expand_Concatenate;
+ ---------------------------------------------------
+ -- Expand_Membership_Minimize_Eliminate_Overflow --
+ ---------------------------------------------------
+
+ procedure Expand_Membership_Minimize_Eliminate_Overflow (N : Node_Id) is
+ pragma Assert (Nkind (N) = N_In);
+ -- Despite the name, this routine applies only to N_In, not to
+ -- N_Not_In. The latter is always rewritten as not (X in Y).
+
+ Result_Type : constant Entity_Id := Etype (N);
+ -- Capture result type, may be a derived boolean type
+
+ Loc : constant Source_Ptr := Sloc (N);
+ Lop : constant Node_Id := Left_Opnd (N);
+ Rop : constant Node_Id := Right_Opnd (N);
+
+ -- Note: there are many referencs to Etype (Lop) and Etype (Rop). It
+ -- is thus tempting to capture these values, but due to the rewrites
+ -- that occur as a result of overflow checking, these values change
+ -- as we go along, and it is safe just to always use Etype explicitly.
+
+ Restype : constant Entity_Id := Etype (N);
+ -- Save result type
+
+ Lo, Hi : Uint;
+ -- Bounds in Minimize calls, not used yet ???
+
+ LLIB : constant Entity_Id := Base_Type (Standard_Long_Long_Integer);
+ -- Entity for Long_Long_Integer'Base (Standard should export this???)
+
+ begin
+ Minimize_Eliminate_Overflow_Checks (Lop, Lo, Hi, Top_Level => False);
+
+ -- If right operand is a subtype name, and the subtype name has no
+ -- predicate, then we can just replace the right operand with an
+ -- explicit range T'First .. T'Last, and use the explicit range code.
+
+ if Nkind (Rop) /= N_Range
+ and then No (Predicate_Function (Etype (Rop)))
+ then
+ declare
+ Rtyp : constant Entity_Id := Etype (Rop);
+ begin
+ Rewrite (Rop,
+ Make_Range (Loc,
+ Low_Bound =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_First,
+ Prefix => New_Reference_To (Rtyp, Loc)),
+ High_Bound =>
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Last,
+ Prefix => New_Reference_To (Rtyp, Loc))));
+ Analyze_And_Resolve (Rop, Rtyp, Suppress => All_Checks);
+ end;
+ end if;
+
+ -- Here for the explicit range case. Note that the bounds of the range
+ -- have not been processed for minimized or eliminated checks.
+
+ if Nkind (Rop) = N_Range then
+ Minimize_Eliminate_Overflow_Checks
+ (Low_Bound (Rop), Lo, Hi, Top_Level => False);
+ Minimize_Eliminate_Overflow_Checks
+ (High_Bound (Rop), Lo, Hi, Top_Level => False);
+
+ -- We have A in B .. C, treated as A >= B and then A <= C
+
+ -- Bignum case
+
+ if Is_RTE (Etype (Lop), RE_Bignum)
+ or else Is_RTE (Etype (Low_Bound (Rop)), RE_Bignum)
+ or else Is_RTE (Etype (High_Bound (Rop)), RE_Bignum)
+ then
+ declare
+ Blk : constant Node_Id := Make_Bignum_Block (Loc);
+ Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
+ L : constant Entity_Id :=
+ Make_Defining_Identifier (Loc, Name_uL);
+ Lopnd : constant Node_Id := Convert_To_Bignum (Lop);
+ Lbound : constant Node_Id :=
+ Convert_To_Bignum (Low_Bound (Rop));
+ Hbound : constant Node_Id :=
+ Convert_To_Bignum (High_Bound (Rop));
+
+ -- Now we rewrite the membership test node to look like
+
+ -- do
+ -- Bnn : Result_Type;
+ -- declare
+ -- M : Mark_Id := SS_Mark;
+ -- L : Bignum := Lopnd;
+ -- begin
+ -- Bnn := Big_GE (L, Lbound) and then Big_LE (L, Hbound)
+ -- SS_Release (M);
+ -- end;
+ -- in
+ -- Bnn
+ -- end
+
+ begin
+ -- Insert declaration of L into declarations of bignum block
+
+ Insert_After
+ (Last (Declarations (Blk)),
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => L,
+ Object_Definition =>
+ New_Occurrence_Of (RTE (RE_Bignum), Loc),
+ Expression => Lopnd));
+
+ -- Insert assignment to Bnn into expressions of bignum block
+
+ Insert_Before
+ (First (Statements (Handled_Statement_Sequence (Blk))),
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Bnn, Loc),
+ Expression =>
+ Make_And_Then (Loc,
+ Left_Opnd =>
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Big_GE), Loc),
+ Parameter_Associations => New_List (
+ New_Occurrence_Of (L, Loc),
+ Lbound)),
+ Right_Opnd =>
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_Big_LE), Loc),
+ Parameter_Associations => New_List (
+ New_Occurrence_Of (L, Loc),
+ Hbound)))));
+
+ -- Now rewrite the node
+
+ Rewrite (N,
+ Make_Expression_With_Actions (Loc,
+ Actions => New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Bnn,
+ Object_Definition =>
+ New_Occurrence_Of (Result_Type, Loc)),
+ Blk),
+ Expression => New_Occurrence_Of (Bnn, Loc)));
+ Analyze_And_Resolve (N, Result_Type);
+ return;
+ end;
+
+ -- Here if no bignums around
+
+ else
+ -- Case where types are all the same
+
+ if Base_Type (Etype (Lop)) = Base_Type (Etype (Low_Bound (Rop)))
+ and then
+ Base_Type (Etype (Lop)) = Base_Type (Etype (High_Bound (Rop)))
+ then
+ null;
+
+ -- If types are not all the same, it means that we have rewritten
+ -- at least one of them to be of type Long_Long_Integer, and we
+ -- will convert the other operands to Long_Long_Integer.
+
+ else
+ Convert_To_And_Rewrite (LLIB, Lop);
+ Set_Analyzed (Lop, False);
+ Analyze_And_Resolve (Lop, LLIB);
+
+ -- For the right operand, avoid unnecessary recursion into
+ -- this routine, we know that overflow is not possible.
+
+ Convert_To_And_Rewrite (LLIB, Low_Bound (Rop));
+ Convert_To_And_Rewrite (LLIB, High_Bound (Rop));
+ Set_Analyzed (Rop, False);
+ Analyze_And_Resolve (Rop, LLIB, Suppress => Overflow_Check);
+ end if;
+
+ -- Now the three operands are of the same signed integer type,
+ -- so we can use the normal expansion routine for membership,
+ -- setting the flag to prevent recursion into this procedure.
+
+ Set_No_Minimize_Eliminate (N);
+ Expand_N_In (N);
+ end if;
+
+ -- Right operand is a subtype name and the subtype has a predicate. We
+ -- have to make sure predicate is checked, and for that we need to use
+ -- the standard N_In circuitry with appropriate types.
+
+ else
+ pragma Assert (Present (Predicate_Function (Etype (Rop))));
+
+ -- If types are "right", just call Expand_N_In preventing recursion
+
+ if Base_Type (Etype (Lop)) = Base_Type (Etype (Rop)) then
+ Set_No_Minimize_Eliminate (N);
+ Expand_N_In (N);
+
+ -- Bignum case
+
+ elsif Is_RTE (Etype (Lop), RE_Bignum) then
+
+ -- For X in T, we want to rewrite our node as
+
+ -- do
+ -- Bnn : Result_Type;
+
+ -- declare
+ -- M : Mark_Id := SS_Mark;
+ -- Lnn : Long_Long_Integer'Base
+ -- Nnn : Bignum;
+
+ -- begin
+ -- Nnn := X;
+
+ -- if not Bignum_In_LLI_Range (Nnn) then
+ -- Bnn := False;
+ -- else
+ -- Lnn := From_Bignum (Nnn);
+ -- Bnn :=
+ -- Lnn in LLIB (T'Base'First) .. LLIB (T'Base'Last)
+ -- and then T'Base (Lnn) in T;
+ -- end if;
+ --
+ -- SS_Release (M);
+ -- end
+ -- in
+ -- Bnn
+ -- end
+
+ -- A bit gruesome, but here goes.
+
+ declare
+ Blk : constant Node_Id := Make_Bignum_Block (Loc);
+ Bnn : constant Entity_Id := Make_Temporary (Loc, 'B', N);
+ Lnn : constant Entity_Id := Make_Temporary (Loc, 'L', N);
+ Nnn : constant Entity_Id := Make_Temporary (Loc, 'N', N);
+ T : constant Entity_Id := Etype (Rop);
+ TB : constant Entity_Id := Base_Type (T);
+ Nin : Node_Id;
+
+ begin
+ -- Mark the last membership operation to prevent recursion
+
+ Nin :=
+ Make_In (Loc,
+ Left_Opnd =>
+ Convert_To (Base_Type (Etype (Rop)),
+ New_Occurrence_Of (Lnn, Loc)),
+ Right_Opnd => New_Occurrence_Of (Etype (Rop), Loc));
+ Set_No_Minimize_Eliminate (Nin);
+
+ -- Now decorate the block
+
+ Insert_After
+ (Last (Declarations (Blk)),
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Lnn,
+ Object_Definition => New_Occurrence_Of (LLIB, Loc)));
+
+ Insert_After
+ (Last (Declarations (Blk)),
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Nnn,
+ Object_Definition =>
+ New_Occurrence_Of (RTE (RE_Bignum), Loc)));
+
+ Insert_List_Before
+ (First (Statements (Handled_Statement_Sequence (Blk))),
+ New_List (
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Nnn, Loc),
+ Expression => Relocate_Node (Lop)),
+
+ Make_If_Statement (Loc,
+ Condition =>
+ Make_Op_Not (Loc,
+ Right_Opnd =>
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of
+ (RTE (RE_Bignum_In_LLI_Range), Loc),
+ Parameter_Associations => New_List (
+ New_Occurrence_Of (Nnn, Loc)))),
+
+ Then_Statements => New_List (
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Bnn, Loc),
+ Expression =>
+ New_Occurrence_Of (Standard_False, Loc))),
+
+ Else_Statements => New_List (
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Lnn, Loc),
+ Expression =>
+ Make_Function_Call (Loc,
+ Name =>
+ New_Occurrence_Of (RTE (RE_From_Bignum), Loc),
+ Parameter_Associations => New_List (
+ New_Occurrence_Of (Nnn, Loc)))),
+
+ Make_Assignment_Statement (Loc,
+ Name => New_Occurrence_Of (Bnn, Loc),
+ Expression =>
+ Make_And_Then (Loc,
+ Left_Opnd =>
+ Make_In (Loc,
+ Left_Opnd => New_Occurrence_Of (Lnn, Loc),
+ Right_Opnd =>
+ Make_Range (Loc,
+ Low_Bound =>
+ Convert_To (LLIB,
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_First,
+ Prefix =>
+ New_Occurrence_Of (TB, Loc))),
+
+ High_Bound =>
+ Convert_To (LLIB,
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Last,
+ Prefix =>
+ New_Occurrence_Of (TB, Loc))))),
+
+ Right_Opnd => Nin))))));
+
+ -- Now we can do the rewrite
+
+ Rewrite (N,
+ Make_Expression_With_Actions (Loc,
+ Actions => New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Bnn,
+ Object_Definition =>
+ New_Occurrence_Of (Result_Type, Loc)),
+ Blk),
+ Expression => New_Occurrence_Of (Bnn, Loc)));
+ Analyze_And_Resolve (N, Result_Type);
+ return;
+ end;
+
+ -- Not bignum case, but types don't match (this means we rewrote the
+ -- left operand to be Long_Long_Integer).
+
+ else
+ pragma Assert (Base_Type (Etype (Lop)) = LLIB);
+
+ -- We rewrite the membership test as (where T is the type with
+ -- the predicate, i.e. the type of the right operand)
+
+ -- Lop in LLIB (T'Base'First) .. LLIB (T'Base'Last)
+ -- and then T'Base (Lop) in T
+
+ declare
+ T : constant Entity_Id := Etype (Rop);
+ TB : constant Entity_Id := Base_Type (T);
+ Nin : Node_Id;
+
+ begin
+ -- The last membership test is marked to prevent recursion
+
+ Nin :=
+ Make_In (Loc,
+ Left_Opnd => Convert_To (TB, Duplicate_Subexpr (Lop)),
+ Right_Opnd => New_Occurrence_Of (T, Loc));
+ Set_No_Minimize_Eliminate (Nin);
+
+ -- Now do the rewrite
+
+ Rewrite (N,
+ Make_And_Then (Loc,
+ Left_Opnd =>
+ Make_In (Loc,
+ Left_Opnd => Lop,
+ Right_Opnd =>
+ Make_Range (Loc,
+ Low_Bound =>
+ Convert_To (LLIB,
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_First,
+ Prefix => New_Occurrence_Of (TB, Loc))),
+ High_Bound =>
+ Convert_To (LLIB,
+ Make_Attribute_Reference (Loc,
+ Attribute_Name => Name_Last,
+ Prefix => New_Occurrence_Of (TB, Loc))))),
+ Right_Opnd => Nin));
+ Set_Analyzed (N, False);
+ Analyze_And_Resolve (N, Restype);
+ end;
+ end if;
+ end if;
+ end Expand_Membership_Minimize_Eliminate_Overflow;
+
------------------------
-- Expand_N_Allocator --
------------------------
@@ -4059,8 +4675,8 @@ package body Exp_Ch4 is
end;
-- We set the allocator as analyzed so that when we analyze
- -- the conditional expression node, we do not get an unwanted
- -- recursive expansion of the allocator expression.
+ -- the if expression node, we do not get an unwanted recursive
+ -- expansion of the allocator expression.
Set_Analyzed (N, True);
Nod := Relocate_Node (N);
@@ -4205,6 +4821,13 @@ package body Exp_Ch4 is
Fexp : Node_Id;
begin
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
-- We expand
-- case X is when A => AX, when B => BX ...
@@ -4226,7 +4849,7 @@ package body Exp_Ch4 is
-- wrong for unconstrained types (since the bounds may not be the
-- same in all branches). Furthermore it involves an extra copy
-- for large objects. So we take care of this by using the following
- -- modified expansion for non-scalar types:
+ -- modified expansion for non-elementary types:
-- do
-- type Pnn is access all typ;
@@ -4249,7 +4872,7 @@ package body Exp_Ch4 is
-- Scalar case
- if Is_Scalar_Type (Typ) then
+ if Is_Elementary_Type (Typ) then
Ttyp := Typ;
else
@@ -4284,7 +4907,7 @@ package body Exp_Ch4 is
-- As described above, take Unrestricted_Access for case of non-
-- scalar types, to avoid big copies, and special cases.
- if not Is_Scalar_Type (Typ) then
+ if not Is_Elementary_Type (Typ) then
Aexp :=
Make_Attribute_Reference (Aloc,
Prefix => Relocate_Node (Aexp),
@@ -4319,7 +4942,7 @@ package body Exp_Ch4 is
-- Construct and return final expression with actions
- if Is_Scalar_Type (Typ) then
+ if Is_Elementary_Type (Typ) then
Fexp := New_Occurrence_Of (Tnn, Loc);
else
Fexp :=
@@ -4335,21 +4958,188 @@ package body Exp_Ch4 is
Analyze_And_Resolve (N, Typ);
end Expand_N_Case_Expression;
- -------------------------------------
- -- Expand_N_Conditional_Expression --
- -------------------------------------
+ -----------------------------------
+ -- Expand_N_Explicit_Dereference --
+ -----------------------------------
+
+ procedure Expand_N_Explicit_Dereference (N : Node_Id) is
+ begin
+ -- Insert explicit dereference call for the checked storage pool case
+
+ Insert_Dereference_Action (Prefix (N));
+
+ -- If the type is an Atomic type for which Atomic_Sync is enabled, then
+ -- we set the atomic sync flag.
+
+ if Is_Atomic (Etype (N))
+ and then not Atomic_Synchronization_Disabled (Etype (N))
+ then
+ Activate_Atomic_Synchronization (N);
+ end if;
+ end Expand_N_Explicit_Dereference;
+
+ --------------------------------------
+ -- Expand_N_Expression_With_Actions --
+ --------------------------------------
+
+ procedure Expand_N_Expression_With_Actions (N : Node_Id) is
+
+ procedure Process_Transient_Object (Decl : Node_Id);
+ -- Given the declaration of a controlled transient declared inside the
+ -- Actions list of an Expression_With_Actions, generate all necessary
+ -- types and hooks in order to properly finalize the transient. This
+ -- mechanism works in conjunction with Build_Finalizer.
+
+ ------------------------------
+ -- Process_Transient_Object --
+ ------------------------------
+
+ procedure Process_Transient_Object (Decl : Node_Id) is
+
+ function Find_Insertion_Node return Node_Id;
+ -- Complex conditions in if statements may be converted into nested
+ -- EWAs. In this case, any generated code must be inserted before the
+ -- if statement to ensure proper visibility of the hook objects. This
+ -- routine returns the top most short circuit operator or the parent
+ -- of the EWA if no nesting was detected.
+
+ -------------------------
+ -- Find_Insertion_Node --
+ -------------------------
+
+ function Find_Insertion_Node return Node_Id is
+ Par : Node_Id;
+
+ begin
+ -- Climb up the branches of a complex condition
+
+ Par := N;
+ while Nkind_In (Parent (Par), N_And_Then, N_Op_Not, N_Or_Else) loop
+ Par := Parent (Par);
+ end loop;
+
+ return Par;
+ end Find_Insertion_Node;
+
+ -- Local variables
+
+ Ins_Node : constant Node_Id := Find_Insertion_Node;
+ Loc : constant Source_Ptr := Sloc (Decl);
+ Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
+ Obj_Typ : constant Entity_Id := Etype (Obj_Id);
+ Desig_Typ : Entity_Id;
+ Expr : Node_Id;
+ Ptr_Decl : Node_Id;
+ Ptr_Id : Entity_Id;
+ Temp_Decl : Node_Id;
+ Temp_Id : Node_Id;
+
+ -- Start of processing for Process_Transient_Object
+
+ begin
+ -- Step 1: Create the access type which provides a reference to the
+ -- transient object.
+
+ if Is_Access_Type (Obj_Typ) then
+ Desig_Typ := Directly_Designated_Type (Obj_Typ);
+ else
+ Desig_Typ := Obj_Typ;
+ end if;
+
+ -- Generate:
+ -- Ann : access [all] <Desig_Typ>;
+
+ Ptr_Id := Make_Temporary (Loc, 'A');
+
+ Ptr_Decl :=
+ Make_Full_Type_Declaration (Loc,
+ Defining_Identifier => Ptr_Id,
+ Type_Definition =>
+ Make_Access_To_Object_Definition (Loc,
+ All_Present =>
+ Ekind (Obj_Typ) = E_General_Access_Type,
+ Subtype_Indication => New_Reference_To (Desig_Typ, Loc)));
+
+ Insert_Action (Ins_Node, Ptr_Decl);
+ Analyze (Ptr_Decl);
+
+ -- Step 2: Create a temporary which acts as a hook to the transient
+ -- object. Generate:
+
+ -- Temp : Ptr_Id := null;
+
+ Temp_Id := Make_Temporary (Loc, 'T');
+
+ Temp_Decl :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp_Id,
+ Object_Definition => New_Reference_To (Ptr_Id, Loc));
+
+ Insert_Action (Ins_Node, Temp_Decl);
+ Analyze (Temp_Decl);
+
+ -- Mark this temporary as created for the purposes of exporting the
+ -- transient declaration out of the Actions list. This signals the
+ -- machinery in Build_Finalizer to recognize this special case.
+
+ Set_Status_Flag_Or_Transient_Decl (Temp_Id, Decl);
+
+ -- Step 3: Hook the transient object to the temporary
+
+ if Is_Access_Type (Obj_Typ) then
+ Expr := Convert_To (Ptr_Id, New_Reference_To (Obj_Id, Loc));
+ else
+ Expr :=
+ Make_Attribute_Reference (Loc,
+ Prefix => New_Reference_To (Obj_Id, Loc),
+ Attribute_Name => Name_Unrestricted_Access);
+ end if;
+
+ -- Generate:
+ -- Temp := Ptr_Id (Obj_Id);
+ -- <or>
+ -- Temp := Obj_Id'Unrestricted_Access;
+
+ Insert_After_And_Analyze (Decl,
+ Make_Assignment_Statement (Loc,
+ Name => New_Reference_To (Temp_Id, Loc),
+ Expression => Expr));
+ end Process_Transient_Object;
+
+ -- Local variables
+
+ Decl : Node_Id;
+
+ -- Start of processing for Expand_N_Expression_With_Actions
+
+ begin
+ Decl := First (Actions (N));
+ while Present (Decl) loop
+ if Nkind (Decl) = N_Object_Declaration
+ and then Is_Finalizable_Transient (Decl, N)
+ then
+ Process_Transient_Object (Decl);
+ end if;
+
+ Next (Decl);
+ end loop;
+ end Expand_N_Expression_With_Actions;
+
+ ----------------------------
+ -- Expand_N_If_Expression --
+ ----------------------------
-- Deal with limited types and condition actions
- procedure Expand_N_Conditional_Expression (N : Node_Id) is
+ procedure Expand_N_If_Expression (N : Node_Id) is
function Create_Alternative
(Loc : Source_Ptr;
Temp_Id : Entity_Id;
Flag_Id : Entity_Id;
Expr : Node_Id) return List_Id;
- -- Build the statements of a "then" or "else" conditional expression
- -- alternative. Temp_Id is the conditional expression result, Flag_Id
- -- is a finalization flag created to service expression Expr.
+ -- Build the statements of a "then" or "else" dependent expression
+ -- alternative. Temp_Id is the if expression result, Flag_Id is a
+ -- finalization flag created to service expression Expr.
function Is_Controlled_Function_Call (Expr : Node_Id) return Boolean;
-- Determine if expression Expr is a rewritten controlled function call
@@ -4420,10 +5210,17 @@ package body Exp_Ch4 is
New_N : Node_Id;
begin
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
-- Fold at compile time if condition known. We have already folded
- -- static conditional expressions, but it is possible to fold any
- -- case in which the condition is known at compile time, even though
- -- the result is non-static.
+ -- static if expressions, but it is possible to fold any case in which
+ -- the condition is known at compile time, even though the result is
+ -- non-static.
-- Note that we don't do the fold of such cases in Sem_Elab because
-- it can cause infinite loops with the expander adding a conditional
@@ -4460,7 +5257,7 @@ package body Exp_Ch4 is
end if;
-- Note that the result is never static (legitimate cases of static
- -- conditional expressions were folded in Sem_Eval).
+ -- if expressions were folded in Sem_Eval).
Set_Is_Static_Expression (N, False);
return;
@@ -4484,7 +5281,7 @@ package body Exp_Ch4 is
-- Cnn := else-expr'Unrestricted_Access;
-- end if;
- -- and replace the conditional expression by a reference to Cnn.all.
+ -- and replace the if expression by a reference to Cnn.all.
-- This special case can be skipped if the back end handles limited
-- types properly and ensures that no incorrect copies are made.
@@ -4499,7 +5296,7 @@ package body Exp_Ch4 is
begin
Flag_Id := Empty;
- -- At least one of the conditional expression alternatives uses a
+ -- At least one of the if expression dependent expressions uses a
-- controlled function to provide the result. Create a status flag
-- to signal the finalization machinery that Cnn needs special
-- handling.
@@ -4599,7 +5396,7 @@ package body Exp_Ch4 is
-- Cnn := else-expr
-- end if;
- -- and replace the conditional expression by a reference to Cnn
+ -- and replace the if expression by a reference to Cnn
else
Cnn := Make_Temporary (Loc, 'C', N);
@@ -4666,174 +5463,7 @@ package body Exp_Ch4 is
Insert_Action (N, New_If);
Rewrite (N, New_N);
Analyze_And_Resolve (N, Typ);
- end Expand_N_Conditional_Expression;
-
- -----------------------------------
- -- Expand_N_Explicit_Dereference --
- -----------------------------------
-
- procedure Expand_N_Explicit_Dereference (N : Node_Id) is
- begin
- -- Insert explicit dereference call for the checked storage pool case
-
- Insert_Dereference_Action (Prefix (N));
-
- -- If the type is an Atomic type for which Atomic_Sync is enabled, then
- -- we set the atomic sync flag.
-
- if Is_Atomic (Etype (N))
- and then not Atomic_Synchronization_Disabled (Etype (N))
- then
- Activate_Atomic_Synchronization (N);
- end if;
- end Expand_N_Explicit_Dereference;
-
- --------------------------------------
- -- Expand_N_Expression_With_Actions --
- --------------------------------------
-
- procedure Expand_N_Expression_With_Actions (N : Node_Id) is
-
- procedure Process_Transient_Object (Decl : Node_Id);
- -- Given the declaration of a controlled transient declared inside the
- -- Actions list of an Expression_With_Actions, generate all necessary
- -- types and hooks in order to properly finalize the transient. This
- -- mechanism works in conjunction with Build_Finalizer.
-
- ------------------------------
- -- Process_Transient_Object --
- ------------------------------
-
- procedure Process_Transient_Object (Decl : Node_Id) is
-
- function Find_Insertion_Node return Node_Id;
- -- Complex conditions in if statements may be converted into nested
- -- EWAs. In this case, any generated code must be inserted before the
- -- if statement to ensure proper visibility of the hook objects. This
- -- routine returns the top most short circuit operator or the parent
- -- of the EWA if no nesting was detected.
-
- -------------------------
- -- Find_Insertion_Node --
- -------------------------
-
- function Find_Insertion_Node return Node_Id is
- Par : Node_Id;
-
- begin
- -- Climb up the branches of a complex condition
-
- Par := N;
- while Nkind_In (Parent (Par), N_And_Then, N_Op_Not, N_Or_Else) loop
- Par := Parent (Par);
- end loop;
-
- return Par;
- end Find_Insertion_Node;
-
- -- Local variables
-
- Ins_Node : constant Node_Id := Find_Insertion_Node;
- Loc : constant Source_Ptr := Sloc (Decl);
- Obj_Id : constant Entity_Id := Defining_Identifier (Decl);
- Obj_Typ : constant Entity_Id := Etype (Obj_Id);
- Desig_Typ : Entity_Id;
- Expr : Node_Id;
- Ptr_Decl : Node_Id;
- Ptr_Id : Entity_Id;
- Temp_Decl : Node_Id;
- Temp_Id : Node_Id;
-
- -- Start of processing for Process_Transient_Object
-
- begin
- -- Step 1: Create the access type which provides a reference to the
- -- transient object.
-
- if Is_Access_Type (Obj_Typ) then
- Desig_Typ := Directly_Designated_Type (Obj_Typ);
- else
- Desig_Typ := Obj_Typ;
- end if;
-
- -- Generate:
- -- Ann : access [all] <Desig_Typ>;
-
- Ptr_Id := Make_Temporary (Loc, 'A');
-
- Ptr_Decl :=
- Make_Full_Type_Declaration (Loc,
- Defining_Identifier => Ptr_Id,
- Type_Definition =>
- Make_Access_To_Object_Definition (Loc,
- All_Present =>
- Ekind (Obj_Typ) = E_General_Access_Type,
- Subtype_Indication => New_Reference_To (Desig_Typ, Loc)));
-
- Insert_Action (Ins_Node, Ptr_Decl);
- Analyze (Ptr_Decl);
-
- -- Step 2: Create a temporary which acts as a hook to the transient
- -- object. Generate:
-
- -- Temp : Ptr_Id := null;
-
- Temp_Id := Make_Temporary (Loc, 'T');
-
- Temp_Decl :=
- Make_Object_Declaration (Loc,
- Defining_Identifier => Temp_Id,
- Object_Definition => New_Reference_To (Ptr_Id, Loc));
-
- Insert_Action (Ins_Node, Temp_Decl);
- Analyze (Temp_Decl);
-
- -- Mark this temporary as created for the purposes of exporting the
- -- transient declaration out of the Actions list. This signals the
- -- machinery in Build_Finalizer to recognize this special case.
-
- Set_Status_Flag_Or_Transient_Decl (Temp_Id, Decl);
-
- -- Step 3: Hook the transient object to the temporary
-
- if Is_Access_Type (Obj_Typ) then
- Expr := Convert_To (Ptr_Id, New_Reference_To (Obj_Id, Loc));
- else
- Expr :=
- Make_Attribute_Reference (Loc,
- Prefix => New_Reference_To (Obj_Id, Loc),
- Attribute_Name => Name_Unrestricted_Access);
- end if;
-
- -- Generate:
- -- Temp := Ptr_Id (Obj_Id);
- -- <or>
- -- Temp := Obj_Id'Unrestricted_Access;
-
- Insert_After_And_Analyze (Decl,
- Make_Assignment_Statement (Loc,
- Name => New_Reference_To (Temp_Id, Loc),
- Expression => Expr));
- end Process_Transient_Object;
-
- -- Local variables
-
- Decl : Node_Id;
-
- -- Start of processing for Expand_N_Expression_With_Actions
-
- begin
- Decl := First (Actions (N));
- while Present (Decl) loop
- if Nkind (Decl) = N_Object_Declaration
- and then Is_Finalizable_Transient (Decl, N)
- then
- Process_Transient_Object (Decl);
- end if;
-
- Next (Decl);
- end loop;
- end Expand_N_Expression_With_Actions;
+ end Expand_N_If_Expression;
-----------------
-- Expand_N_In --
@@ -4866,9 +5496,16 @@ package body Exp_Ch4 is
Analyze_And_Resolve (N, Restyp);
- Error_Msg_N ("?explicit membership test may be optimized away", N);
- Error_Msg_N -- CODEFIX
- ("\?use ''Valid attribute instead", N);
+ -- Give warning unless overflow checking is MINIMIZED or ELIMINATED,
+ -- in which case, this usage makes sense, and in any case, we have
+ -- actually eliminated the danger of optimization above.
+
+ if Overflow_Check_Mode (Restyp) not in Minimized_Or_Eliminated then
+ Error_Msg_N ("?explicit membership test may be optimized away", N);
+ Error_Msg_N -- CODEFIX
+ ("\?use ''Valid attribute instead", N);
+ end if;
+
return;
end Substitute_Valid_Check;
@@ -4887,20 +5524,49 @@ package body Exp_Ch4 is
Ltyp := Etype (Left_Opnd (N));
Rtyp := Etype (Right_Opnd (N));
+ -- If MINIMIZED/ELIMINATED overflow mode and type is a signed integer
+ -- type, then expand with a separate procedure. Note the use of the
+ -- flag No_Minimize_Eliminate to prevent infinite recursion.
+
+ if Overflow_Check_Mode (Empty) in Minimized_Or_Eliminated
+ and then Is_Signed_Integer_Type (Ltyp)
+ and then not No_Minimize_Eliminate (N)
+ then
+ Expand_Membership_Minimize_Eliminate_Overflow (N);
+ return;
+ end if;
+
-- Check case of explicit test for an expression in range of its
-- subtype. This is suspicious usage and we replace it with a 'Valid
- -- test and give a warning. For floating point types however, this is a
- -- standard way to check for finite numbers, and using 'Valid would
- -- typically be a pessimization. Also skip this test for predicated
- -- types, since it is perfectly reasonable to check if a value meets
- -- its predicate.
+ -- test and give a warning for scalar types.
if Is_Scalar_Type (Ltyp)
+
+ -- Only relevant for source comparisons
+
+ and then Comes_From_Source (N)
+
+ -- In floating-point this is a standard way to check for finite values
+ -- and using 'Valid would typically be a pessimization.
+
and then not Is_Floating_Point_Type (Ltyp)
+
+ -- Don't give the message unless right operand is a type entity and
+ -- the type of the left operand matches this type. Note that this
+ -- 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 Ltyp = Entity (Rop)
- and then Comes_From_Source (N)
+
+ -- Skip in VM mode, where we have no sense of invalid values. The
+ -- warning still seems relevant, but not important enough to worry.
+
and then VM_Target = No_VM
+
+ -- Skip this for predicated types, where such expressions are a
+ -- reasonable way of testing if something meets the predicate.
+
and then not (Is_Discrete_Type (Ltyp)
and then Present (Predicate_Function (Ltyp)))
then
@@ -4953,15 +5619,30 @@ package body Exp_Ch4 is
-- Could use some individual comments for this complex test ???
if Is_Scalar_Type (Ltyp)
+
+ -- 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
+ -- type of the left operand.
+
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 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 Entity (Prefix (Hi_Orig)) = Ltyp
+
+ -- Relevant only for source cases
+
and then Comes_From_Source (N)
+
+ -- Omit for VM cases, where we don't have invalid values
+
and then VM_Target = No_VM
then
Substitute_Valid_Check;
@@ -4982,9 +5663,9 @@ package body Exp_Ch4 is
and then Expr_Value (Type_High_Bound (Ltyp)) = Expr_Value (Hi)
and then Expr_Value (Type_Low_Bound (Ltyp)) = Expr_Value (Lo)
- -- Kill warnings in instances, since they may be cases where we
- -- have a test in the generic that makes sense with some types
- -- and not with other types.
+ -- Kill warnings in instances, since they may be cases where we
+ -- have a test in the generic that makes sense with some types
+ -- and not with other types.
and then not In_Instance
then
@@ -5145,8 +5826,8 @@ package body Exp_Ch4 is
-- 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 check the predicate!
elsif Is_Scalar_Type (Typ) then
if No (Predicate_Function (Typ)) then
@@ -5155,12 +5836,12 @@ package body Exp_Ch4 is
Low_Bound =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_First,
- Prefix => New_Reference_To (Typ, Loc)),
+ Prefix => New_Reference_To (Typ, Loc)),
High_Bound =>
Make_Attribute_Reference (Loc,
Attribute_Name => Name_Last,
- Prefix => New_Reference_To (Typ, Loc))));
+ Prefix => New_Reference_To (Typ, Loc))));
Analyze_And_Resolve (N, Restyp);
end if;
@@ -5180,7 +5861,7 @@ package body Exp_Ch4 is
Reason => PE_Unchecked_Union_Restriction));
-- Prevent Gigi from generating incorrect code by rewriting the
- -- test as False.
+ -- test as False. What is this undocumented thing about ???
Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
goto Leave;
@@ -5720,6 +6401,13 @@ package body Exp_Ch4 is
begin
Unary_Op_Validity_Checks (N);
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
-- Deal with software overflow checking
if not Backend_Overflow_Checks_On_Target
@@ -5763,6 +6451,13 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
-- N + 0 = 0 + N = N for integer types
if Is_Integer_Type (Typ) then
@@ -5905,6 +6600,15 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
+ -- Otherwise proceed with expansion of division
+
if Rknow then
Rval := Expr_Value (Ropnd);
end if;
@@ -5998,7 +6702,7 @@ package body Exp_Ch4 is
-- Non-fixed point cases, do integer zero divide and overflow checks
elsif Is_Integer_Type (Typ) then
- Apply_Divide_Check (N);
+ Apply_Divide_Checks (N);
-- Deal with Vax_Float
@@ -6359,6 +7063,8 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Deal with private types
+
if Ekind (Typl) = E_Private_Type then
Typl := Underlying_Type (Typl);
elsif Ekind (Typl) = E_Private_Subtype then
@@ -6377,6 +7083,15 @@ package body Exp_Ch4 is
Typl := Base_Type (Typl);
+ -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
+ -- means we no longer have a comparison operation, we are all done.
+
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+
+ if Nkind (N) /= N_Op_Eq then
+ return;
+ end if;
+
-- Boolean types (requiring handling of non-standard case)
if Is_Boolean_Type (Typl) then
@@ -6536,7 +7251,7 @@ package body Exp_Ch4 is
Reason => PE_Unchecked_Union_Restriction));
-- Prevent Gigi from generating incorrect code by rewriting the
- -- equality as a standard False.
+ -- equality as a standard False. (is this documented somewhere???)
Rewrite (N,
New_Occurrence_Of (Standard_False, Loc));
@@ -6563,7 +7278,7 @@ package body Exp_Ch4 is
Reason => PE_Unchecked_Union_Restriction));
-- Prevent Gigi from generating incorrect code by rewriting
- -- the equality as a standard False.
+ -- the equality as a standard False (documented where???).
Rewrite (N,
New_Occurrence_Of (Standard_False, Loc));
@@ -6620,11 +7335,11 @@ package body Exp_Ch4 is
Exptyp : constant Entity_Id := Etype (Exp);
Ovflo : constant Boolean := Do_Overflow_Check (N);
Expv : Uint;
- Xnode : Node_Id;
Temp : Node_Id;
Rent : RE_Id;
Ent : Entity_Id;
Etyp : Entity_Id;
+ Xnode : Node_Id;
begin
Binary_Op_Validity_Checks (N);
@@ -6662,7 +7377,15 @@ package body Exp_Ch4 is
end;
end if;
- -- Test for case of known right argument
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
+ -- Test for case of known right argument where we can replace the
+ -- exponentiation by an equivalent expression using multiplication.
if Compile_Time_Known_Value (Exp) then
Expv := Expr_Value (Exp);
@@ -6716,27 +7439,34 @@ package body Exp_Ch4 is
Right_Opnd => Duplicate_Subexpr_No_Checks (Base));
-- X ** 4 ->
+
+ -- do
-- En : constant base'type := base * base;
- -- ...
+ -- in
-- En * En
- else -- Expv = 4
+ else
+ pragma Assert (Expv = 4);
Temp := Make_Temporary (Loc, 'E', Base);
- Insert_Actions (N, New_List (
- Make_Object_Declaration (Loc,
- Defining_Identifier => Temp,
- Constant_Present => True,
- Object_Definition => New_Reference_To (Typ, Loc),
+ Xnode :=
+ Make_Expression_With_Actions (Loc,
+ Actions => New_List (
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Temp,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To (Typ, Loc),
+ Expression =>
+ Make_Op_Multiply (Loc,
+ Left_Opnd =>
+ Duplicate_Subexpr (Base),
+ Right_Opnd =>
+ Duplicate_Subexpr_No_Checks (Base)))),
+
Expression =>
Make_Op_Multiply (Loc,
- Left_Opnd => Duplicate_Subexpr (Base),
- Right_Opnd => Duplicate_Subexpr_No_Checks (Base)))));
-
- Xnode :=
- Make_Op_Multiply (Loc,
- Left_Opnd => New_Reference_To (Temp, Loc),
- Right_Opnd => New_Reference_To (Temp, Loc));
+ Left_Opnd => New_Reference_To (Temp, Loc),
+ Right_Opnd => New_Reference_To (Temp, Loc)));
end if;
Rewrite (N, Xnode);
@@ -6947,11 +7677,24 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
+ -- means we no longer have a comparison operation, we are all done.
+
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+
+ if Nkind (N) /= N_Op_Ge then
+ return;
+ end if;
+
+ -- Array type case
+
if Is_Array_Type (Typ1) then
Expand_Array_Comparison (N);
return;
end if;
+ -- Deal with boolean operands
+
if Is_Boolean_Type (Typ1) then
Adjust_Condition (Op1);
Adjust_Condition (Op2);
@@ -6984,11 +7727,24 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
+ -- means we no longer have a comparison operation, we are all done.
+
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+
+ if Nkind (N) /= N_Op_Gt then
+ return;
+ end if;
+
+ -- Deal with array type operands
+
if Is_Array_Type (Typ1) then
Expand_Array_Comparison (N);
return;
end if;
+ -- Deal with boolean type operands
+
if Is_Boolean_Type (Typ1) then
Adjust_Condition (Op1);
Adjust_Condition (Op2);
@@ -7021,11 +7777,24 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
+ -- means we no longer have a comparison operation, we are all done.
+
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+
+ if Nkind (N) /= N_Op_Le then
+ return;
+ end if;
+
+ -- Deal with array type operands
+
if Is_Array_Type (Typ1) then
Expand_Array_Comparison (N);
return;
end if;
+ -- Deal with Boolean type operands
+
if Is_Boolean_Type (Typ1) then
Adjust_Condition (Op1);
Adjust_Condition (Op2);
@@ -7058,11 +7827,24 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if that
+ -- means we no longer have a comparison operation, we are all done.
+
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+
+ if Nkind (N) /= N_Op_Lt then
+ return;
+ end if;
+
+ -- Deal with array type operands
+
if Is_Array_Type (Typ1) then
Expand_Array_Comparison (N);
return;
end if;
+ -- Deal with Boolean type operands
+
if Is_Boolean_Type (Typ1) then
Adjust_Condition (Op1);
Adjust_Condition (Op2);
@@ -7093,6 +7875,13 @@ package body Exp_Ch4 is
begin
Unary_Op_Validity_Checks (N);
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
if not Backend_Overflow_Checks_On_Target
and then Is_Signed_Integer_Type (Etype (N))
and then Do_Overflow_Check (N)
@@ -7120,11 +7909,12 @@ package body Exp_Ch4 is
procedure Expand_N_Op_Mod (N : Node_Id) is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
- Left : constant Node_Id := Left_Opnd (N);
- Right : constant Node_Id := Right_Opnd (N);
DOC : constant Boolean := Do_Overflow_Check (N);
DDC : constant Boolean := Do_Division_Check (N);
+ Left : Node_Id;
+ Right : Node_Id;
+
LLB : Uint;
Llo : Uint;
Lhi : Uint;
@@ -7138,6 +7928,29 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
+ if Is_Integer_Type (Etype (N)) then
+ Apply_Divide_Checks (N);
+
+ -- All done if we don't have a MOD any more, which can happen as a
+ -- result of overflow expansion in MINIMIZED or ELIMINATED modes.
+
+ if Nkind (N) /= N_Op_Mod then
+ return;
+ end if;
+ end if;
+
+ -- Proceed with expansion of mod operator
+
+ Left := Left_Opnd (N);
+ Right := Right_Opnd (N);
+
Determine_Range (Right, ROK, Rlo, Rhi, Assume_Valid => True);
Determine_Range (Left, LOK, Llo, Lhi, Assume_Valid => True);
@@ -7169,10 +7982,6 @@ package body Exp_Ch4 is
-- Otherwise, normal mod processing
else
- if Is_Integer_Type (Etype (N)) then
- Apply_Divide_Check (N);
- end if;
-
-- Apply optimization x mod 1 = 0. We don't really need that with
-- gcc, but it is useful with other back ends (e.g. AAMP), and is
-- certainly harmless.
@@ -7200,32 +8009,39 @@ package body Exp_Ch4 is
-- the mod value is always 0, and we can just ignore the left operand
-- completely in this case.
- -- The operand type may be private (e.g. in the expansion of an
- -- intrinsic operation) so we must use the underlying type to get the
- -- bounds, and convert the literals explicitly.
+ -- This only applies if we still have a mod operator. Skip if we
+ -- have already rewritten this (e.g. in the case of eliminated
+ -- overflow checks which have driven us into bignum mode).
- LLB :=
- Expr_Value
- (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
+ if Nkind (N) = N_Op_Mod then
- if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
- and then
- ((not LOK) or else (Llo = LLB))
- then
- Rewrite (N,
- Make_Conditional_Expression (Loc,
- Expressions => New_List (
- Make_Op_Eq (Loc,
- Left_Opnd => Duplicate_Subexpr (Right),
- Right_Opnd =>
- Unchecked_Convert_To (Typ,
- Make_Integer_Literal (Loc, -1))),
- Unchecked_Convert_To (Typ,
- Make_Integer_Literal (Loc, Uint_0)),
- Relocate_Node (N))));
+ -- The operand type may be private (e.g. in the expansion of an
+ -- intrinsic operation) so we must use the underlying type to get
+ -- the bounds, and convert the literals explicitly.
- Set_Analyzed (Next (Next (First (Expressions (N)))));
- Analyze_And_Resolve (N, Typ);
+ LLB :=
+ Expr_Value
+ (Type_Low_Bound (Base_Type (Underlying_Type (Etype (Left)))));
+
+ if ((not ROK) or else (Rlo <= (-1) and then (-1) <= Rhi))
+ and then
+ ((not LOK) or else (Llo = LLB))
+ then
+ Rewrite (N,
+ Make_If_Expression (Loc,
+ Expressions => New_List (
+ Make_Op_Eq (Loc,
+ Left_Opnd => Duplicate_Subexpr (Right),
+ Right_Opnd =>
+ Unchecked_Convert_To (Typ,
+ Make_Integer_Literal (Loc, -1))),
+ Unchecked_Convert_To (Typ,
+ Make_Integer_Literal (Loc, Uint_0)),
+ Relocate_Node (N))));
+
+ Set_Analyzed (Next (Next (First (Expressions (N)))));
+ Analyze_And_Resolve (N, Typ);
+ end if;
end if;
end if;
end Expand_N_Op_Mod;
@@ -7254,6 +8070,13 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
-- Special optimizations for integer types
if Is_Integer_Type (Typ) then
@@ -7439,6 +8262,15 @@ package body Exp_Ch4 is
then
Binary_Op_Validity_Checks (N);
+ -- Deal with overflow checks in MINIMIZED/ELIMINATED mode and if
+ -- means we no longer have a /= operation, we are all done.
+
+ Expand_Compare_Minimize_Eliminate_Overflow (N);
+
+ if Nkind (N) /= N_Op_Ne then
+ return;
+ end if;
+
-- Boolean types (requiring handling of non-standard case)
if Is_Boolean_Type (Typ) then
@@ -7767,6 +8599,13 @@ package body Exp_Ch4 is
procedure Expand_N_Op_Plus (N : Node_Id) is
begin
Unary_Op_Validity_Checks (N);
+
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
end Expand_N_Op_Plus;
---------------------
@@ -7777,8 +8616,8 @@ package body Exp_Ch4 is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
- Left : constant Node_Id := Left_Opnd (N);
- Right : constant Node_Id := Right_Opnd (N);
+ Left : Node_Id;
+ Right : Node_Id;
Lo : Uint;
Hi : Uint;
@@ -7793,10 +8632,29 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
if Is_Integer_Type (Etype (N)) then
- Apply_Divide_Check (N);
+ Apply_Divide_Checks (N);
+
+ -- All done if we don't have a REM any more, which can happen as a
+ -- result of overflow expansion in MINIMIZED or ELIMINATED modes.
+
+ if Nkind (N) /= N_Op_Rem then
+ return;
+ end if;
end if;
+ -- Proceed with expansion of REM
+
+ Left := Left_Opnd (N);
+ Right := Right_Opnd (N);
+
-- Apply optimization x rem 1 = 0. We don't really need that with gcc,
-- but it is useful with other back ends (e.g. AAMP), and is certainly
-- harmless.
@@ -7837,7 +8695,7 @@ package body Exp_Ch4 is
if Lneg and Rneg then
Rewrite (N,
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Eq (Loc,
Left_Opnd => Duplicate_Subexpr (Right),
@@ -7909,6 +8767,13 @@ package body Exp_Ch4 is
begin
Binary_Op_Validity_Checks (N);
+ -- Check for MINIMIZED/ELIMINATED overflow mode
+
+ if Minimized_Eliminated_Overflow_Check (N) then
+ Apply_Arithmetic_Overflow_Check (N);
+ return;
+ end if;
+
-- N - 0 = N for integer types
if Is_Integer_Type (Typ)
@@ -9291,7 +10156,7 @@ package body Exp_Ch4 is
-- of the object designated by the result value identifies T.
-- Constraint_Error is raised if this check fails.
- if Nkind (Parent (N)) = Sinfo.N_Return_Statement then
+ if Nkind (Parent (N)) = N_Simple_Return_Statement then
declare
Func : Entity_Id;
Func_Typ : Entity_Id;
@@ -9498,7 +10363,7 @@ package body Exp_Ch4 is
then
-- To prevent Gigi from generating illegal code, we generate a
-- Program_Error node, but we give it the target type of the
- -- conversion.
+ -- conversion (is this requirement documented somewhere ???)
declare
PE : constant Node_Id := Make_Raise_Program_Error (Loc,
@@ -10911,6 +11776,18 @@ package body Exp_Ch4 is
return Func_Body;
end Make_Boolean_Array_Op;
+ -----------------------------------------
+ -- Minimized_Eliminated_Overflow_Check --
+ -----------------------------------------
+
+ function Minimized_Eliminated_Overflow_Check (N : Node_Id) return Boolean is
+ begin
+ return
+ Is_Signed_Integer_Type (Etype (N))
+ and then Do_Overflow_Check (N)
+ and then Overflow_Check_Mode (Empty) in Minimized_Or_Eliminated;
+ end Minimized_Eliminated_Overflow_Check;
+
--------------------------------
-- Optimize_Length_Comparison --
--------------------------------
@@ -11501,7 +12378,7 @@ package body Exp_Ch4 is
end if;
end Is_Safe_Operand;
- -- Start of processing for Is_Safe_In_Place_Array_Op
+ -- Start of processing for Safe_In_Place_Array_Op
begin
-- Skip this processing if the component size is different from system
diff --git a/gcc/ada/exp_ch4.ads b/gcc/ada/exp_ch4.ads
index 2e9c68b83..277a7550a 100644
--- a/gcc/ada/exp_ch4.ads
+++ b/gcc/ada/exp_ch4.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -32,9 +32,9 @@ package Exp_Ch4 is
procedure Expand_N_Allocator (N : Node_Id);
procedure Expand_N_And_Then (N : Node_Id);
procedure Expand_N_Case_Expression (N : Node_Id);
- procedure Expand_N_Conditional_Expression (N : Node_Id);
procedure Expand_N_Explicit_Dereference (N : Node_Id);
procedure Expand_N_Expression_With_Actions (N : Node_Id);
+ procedure Expand_N_If_Expression (N : Node_Id);
procedure Expand_N_In (N : Node_Id);
procedure Expand_N_Indexed_Component (N : Node_Id);
procedure Expand_N_Not_In (N : Node_Id);
diff --git a/gcc/ada/exp_ch5.adb b/gcc/ada/exp_ch5.adb
index a1aaa3736..e9ec75ed0 100644
--- a/gcc/ada/exp_ch5.adb
+++ b/gcc/ada/exp_ch5.adb
@@ -3039,10 +3039,18 @@ package body Exp_Ch5 is
Cursor := Make_Temporary (Loc, 'I');
-- For an container element iterator, the iterator type
- -- is obtained from the corresponding aspect.
+ -- is obtained from the corresponding aspect, whose return
+ -- type is descended from the corresponding interface type
+ -- in some instance of Ada.Iterator_Interfaces. The actuals
+ -- of that instantiation are Cursor and Has_Element.
Iter_Type := Etype (Default_Iter);
- Pack := Scope (Iter_Type);
+
+ -- The iterator type, which is a class_wide type, may itself
+ -- be derived locally, so the desired instantiation is the
+ -- scope of the root type of the iterator type.
+
+ Pack := Scope (Root_Type (Etype (Iter_Type)));
-- Rewrite domain of iteration as a call to the default
-- iterator for the container type. If the container is
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 930f82bef..8d9ef9b38 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -1217,8 +1217,8 @@ package body Exp_Ch6 is
and then
Present (Effective_Extra_Accessibility (Entity (Lhs)))
then
- -- Copyback target is an Ada 2012 stand-alone object
- -- of an anonymous access type
+ -- Copyback target is an Ada 2012 stand-alone object of an
+ -- anonymous access type.
pragma Assert (Ada_Version >= Ada_2012);
@@ -2392,10 +2392,6 @@ package body Exp_Ch6 is
Expand_Put_Call_With_Symbol (Call_Node);
end if;
- -- Remove the dimensions of every parameters in call
-
- Remove_Dimension_In_Call (N);
-
-- Ignore if previous error
if Nkind (Call_Node) in N_Has_Etype
@@ -3050,7 +3046,7 @@ package body Exp_Ch6 is
Set_Last_Assignment (Ent, Sav);
Set_Is_Known_Valid (Ent, False);
- -- For all other cases, just kill the current values
+ -- For all other cases, just kill the current values
else
Kill_Current_Values (Ent);
@@ -3205,7 +3201,7 @@ package body Exp_Ch6 is
end;
end if;
- -- If we are expanding a rhs of an assignment we need to check if tag
+ -- If we are expanding the RHS of an assignment we need to check if tag
-- propagation is needed. You might expect this processing to be in
-- Analyze_Assignment but has to be done earlier (bottom-up) because the
-- assignment might be transformed to a declaration for an unconstrained
@@ -3404,6 +3400,14 @@ package body Exp_Ch6 is
Expand_Actuals (Call_Node, Subp);
+ -- Verify that the actuals do not share storage. This check must be done
+ -- on the caller side rather that inside the subprogram to avoid issues
+ -- of parameter passing.
+
+ if Check_Aliasing_Of_Parameters then
+ Apply_Parameter_Aliasing_Checks (Call_Node, Subp);
+ end if;
+
-- If the subprogram is a renaming, or if it is inherited, replace it in
-- the call with the name of the actual subprogram being called. If this
-- is a dispatching call, the run-time decides what to call. The Alias
@@ -4045,7 +4049,10 @@ package body Exp_Ch6 is
Context := Parent (N);
while Present (Context) loop
- if Nkind (Context) = N_Conditional_Expression then
+ -- The following could use a comment (and why is N_Case_Expression
+ -- not treated in a similar manner ???
+
+ if Nkind (Context) = N_If_Expression then
exit;
-- Stop the search when reaching any statement because we have
@@ -4088,13 +4095,15 @@ package body Exp_Ch6 is
Remove_Side_Effects (N);
- -- The function call is part of a conditional expression alternative.
- -- The temporary result must live as long as the conditional expression
- -- itself, otherwise it will be finalized too early. Mark the transient
- -- as processed to avoid untimely finalization.
+ -- The function call is part of an if expression dependent expression.
+ -- The temporary result must live as long as the if expression itself,
+ -- otherwise it will be finalized too early. Mark the transient as
+ -- processed to avoid untimely finalization.
+
+ -- Why no special handling for case expressions here ???
if Present (Context)
- and then Nkind (Context) = N_Conditional_Expression
+ and then Nkind (Context) = N_If_Expression
and then Nkind (N) = N_Explicit_Dereference
then
Set_Is_Processed_Transient (Entity (Prefix (N)));
@@ -4210,9 +4219,7 @@ package body Exp_Ch6 is
Ret : Node_Id;
begin
- if Is_Entity_Name (N)
- and then Present (Entity (N))
- then
+ if Is_Entity_Name (N) and then Present (Entity (N)) then
E := Entity (N);
if Is_Formal (E)
@@ -4772,31 +4779,31 @@ package body Exp_Ch6 is
else
pragma Assert
(Nkind
- (First
- (Statements (Handled_Statement_Sequence (Orig_Bod))))
+ (First
+ (Statements (Handled_Statement_Sequence (Orig_Bod))))
= N_Block_Statement);
declare
Blk_Stmt : constant Node_Id :=
First
(Statements
- (Handled_Statement_Sequence (Orig_Bod)));
+ (Handled_Statement_Sequence (Orig_Bod)));
First_Stmt : constant Node_Id :=
First
(Statements
- (Handled_Statement_Sequence (Blk_Stmt)));
+ (Handled_Statement_Sequence (Blk_Stmt)));
Second_Stmt : constant Node_Id := Next (First_Stmt);
begin
pragma Assert
(Nkind (First_Stmt) = N_Procedure_Call_Statement
- and then Nkind (Second_Stmt) = Sinfo.N_Return_Statement
- and then No (Next (Second_Stmt)));
+ and then Nkind (Second_Stmt) = N_Simple_Return_Statement
+ and then No (Next (Second_Stmt)));
Bod :=
Copy_Generic_Node
(First
- (Statements (Handled_Statement_Sequence (Orig_Bod))),
+ (Statements (Handled_Statement_Sequence (Orig_Bod))),
Empty, Instantiating => True);
Blk := Bod;
@@ -5120,8 +5127,8 @@ package body Exp_Ch6 is
-- Remove the return statement
pragma Assert
- (Nkind (Last (Statements (Handled_Statement_Sequence (Blk))))
- = Sinfo.N_Return_Statement);
+ (Nkind (Last (Statements (Handled_Statement_Sequence (Blk)))) =
+ N_Simple_Return_Statement);
Remove (Last (Statements (Handled_Statement_Sequence (Blk))));
end if;
@@ -9112,6 +9119,96 @@ package body Exp_Ch6 is
end if;
end Make_Build_In_Place_Call_In_Object_Declaration;
+ --------------------------------------------
+ -- Make_CPP_Constructor_Call_In_Allocator --
+ --------------------------------------------
+
+ procedure Make_CPP_Constructor_Call_In_Allocator
+ (Allocator : Node_Id;
+ Function_Call : Node_Id)
+ is
+ Loc : constant Source_Ptr := Sloc (Function_Call);
+ Acc_Type : constant Entity_Id := Etype (Allocator);
+ Function_Id : constant Entity_Id := Entity (Name (Function_Call));
+ Result_Subt : constant Entity_Id := Available_View (Etype (Function_Id));
+
+ New_Allocator : Node_Id;
+ Return_Obj_Access : Entity_Id;
+ Tmp_Obj : Node_Id;
+
+ begin
+ pragma Assert (Nkind (Allocator) = N_Allocator
+ and then Nkind (Function_Call) = N_Function_Call);
+ pragma Assert (Convention (Function_Id) = Convention_CPP
+ and then Is_Constructor (Function_Id));
+ pragma Assert (Is_Constrained (Underlying_Type (Result_Subt)));
+
+ -- Replace the initialized allocator of form "new T'(Func (...))" with
+ -- an uninitialized allocator of form "new T", where T is the result
+ -- subtype of the called function. The call to the function is handled
+ -- separately further below.
+
+ New_Allocator :=
+ Make_Allocator (Loc,
+ Expression => New_Reference_To (Result_Subt, Loc));
+ Set_No_Initialization (New_Allocator);
+
+ -- Copy attributes to new allocator. Note that the new allocator
+ -- logically comes from source if the original one did, so copy the
+ -- relevant flag. This ensures proper treatment of the restriction
+ -- No_Implicit_Heap_Allocations in this case.
+
+ Set_Storage_Pool (New_Allocator, Storage_Pool (Allocator));
+ Set_Procedure_To_Call (New_Allocator, Procedure_To_Call (Allocator));
+ Set_Comes_From_Source (New_Allocator, Comes_From_Source (Allocator));
+
+ Rewrite (Allocator, New_Allocator);
+
+ -- Create a new access object and initialize it to the result of the
+ -- new uninitialized allocator. Note: we do not use Allocator as the
+ -- Related_Node of Return_Obj_Access in call to Make_Temporary below
+ -- as this would create a sort of infinite "recursion".
+
+ Return_Obj_Access := Make_Temporary (Loc, 'R');
+ Set_Etype (Return_Obj_Access, Acc_Type);
+
+ -- Generate:
+ -- Rnnn : constant ptr_T := new (T);
+ -- Init (Rnn.all,...);
+
+ Tmp_Obj :=
+ Make_Object_Declaration (Loc,
+ Defining_Identifier => Return_Obj_Access,
+ Constant_Present => True,
+ Object_Definition => New_Reference_To (Acc_Type, Loc),
+ Expression => Relocate_Node (Allocator));
+ Insert_Action (Allocator, Tmp_Obj);
+
+ Insert_List_After_And_Analyze (Tmp_Obj,
+ Build_Initialization_Call (Loc,
+ Id_Ref =>
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Reference_To (Return_Obj_Access, Loc)),
+ Typ => Etype (Function_Id),
+ Constructor_Ref => Function_Call));
+
+ -- Finally, replace the allocator node with a reference to the result of
+ -- the function call itself (which will effectively be an access to the
+ -- object created by the allocator).
+
+ Rewrite (Allocator, New_Reference_To (Return_Obj_Access, Loc));
+
+ -- Ada 2005 (AI-251): If the type of the allocator is an interface then
+ -- generate an implicit conversion to force displacement of the "this"
+ -- pointer.
+
+ if Is_Interface (Designated_Type (Acc_Type)) then
+ Rewrite (Allocator, Convert_To (Acc_Type, Relocate_Node (Allocator)));
+ end if;
+
+ Analyze_And_Resolve (Allocator, Acc_Type);
+ end Make_CPP_Constructor_Call_In_Allocator;
+
-----------------------------------
-- Needs_BIP_Finalization_Master --
-----------------------------------
diff --git a/gcc/ada/exp_ch6.ads b/gcc/ada/exp_ch6.ads
index 42ba07d20..0f65a5bf7 100644
--- a/gcc/ada/exp_ch6.ads
+++ b/gcc/ada/exp_ch6.ads
@@ -205,6 +205,16 @@ package Exp_Ch6 is
-- for which Is_Build_In_Place_Call is True, or an N_Qualified_Expression
-- node applied to such a function call.
+ procedure Make_CPP_Constructor_Call_In_Allocator
+ (Allocator : Node_Id;
+ Function_Call : Node_Id);
+ -- Handle a call to a CPP constructor that occurs as the expression that
+ -- initializes an allocator, by passing access to the allocated object as
+ -- an additional parameter of the constructor call. A new access object is
+ -- declared that is initialized to the result of the allocator, passed to
+ -- the constructor, and the allocator is rewritten to refer to that access
+ -- object. Function_Call must denote a call to a CPP_Constructor function.
+
function Needs_BIP_Alloc_Form (Func_Id : Entity_Id) return Boolean;
-- Ada 2005 (AI-318-02): Return True if the function needs an implicit
-- BIP_Alloc_Form parameter (see type BIP_Formal_Kind).
diff --git a/gcc/ada/exp_ch7.adb b/gcc/ada/exp_ch7.adb
index 725cd2ac4..78ad5d27d 100644
--- a/gcc/ada/exp_ch7.adb
+++ b/gcc/ada/exp_ch7.adb
@@ -1892,8 +1892,8 @@ package body Exp_Ch7 is
then
Processing_Actions (Has_No_Init => True);
- -- Process intermediate results of conditional expression with
- -- one of the alternatives using a controlled function call.
+ -- Process intermediate results of an if expression with one
+ -- of the alternatives using a controlled function call.
elsif Is_Access_Type (Obj_Typ)
and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
@@ -3639,9 +3639,13 @@ package body Exp_Ch7 is
-- If the node to wrap is an iteration_scheme, the expression is
-- one of the bounds, and the expansion will make an explicit
-- declaration for it (see Analyze_Iteration_Scheme, sem_ch5.adb),
- -- so do not apply any transformations here.
+ -- so do not apply any transformations here. Same for an Ada 2012
+ -- iterator specification, where a block is created for the expression
+ -- that build the container.
- elsif Nkind (Wrap_Node) = N_Iteration_Scheme then
+ elsif Nkind_In (Wrap_Node, N_Iteration_Scheme,
+ N_Iterator_Specification)
+ then
null;
-- In formal verification mode, if the node to wrap is a pragma check,
@@ -4585,9 +4589,6 @@ package body Exp_Ch7 is
-- finalization blocks, and we put everything into a wrapper
-- block to clearly expose the construct to the back-end.
- -- This requirement for "clearly expose" must be properly
- -- documented in sinfo/einfo ???
-
if Present (Prev_Fin) then
Insert_Before_And_Analyze (Prev_Fin, Fin_Block);
else
diff --git a/gcc/ada/exp_ch9.adb b/gcc/ada/exp_ch9.adb
index 248984d89..8a7089eff 100644
--- a/gcc/ada/exp_ch9.adb
+++ b/gcc/ada/exp_ch9.adb
@@ -10194,7 +10194,7 @@ package body Exp_Ch9 is
if Present (Condition (Alt)) then
Expr :=
- Make_Conditional_Expression (Eloc, New_List (
+ Make_If_Expression (Eloc, New_List (
Condition (Alt),
Entry_Index_Expression (Eloc, Eent, Index, Scope (Eent)),
New_Reference_To (RTE (RE_Null_Task_Entry), Eloc)));
@@ -10582,7 +10582,7 @@ package body Exp_Ch9 is
-- In the above declaration, null-body is True if the corresponding
-- accept has no body, and false otherwise. The entry is either the
-- entry index expression if there is no guard, or if a guard is
- -- present, then a conditional expression of the form:
+ -- present, then an if expression of the form:
-- (if guard then entry-index else Null_Task_Entry)
@@ -10753,7 +10753,7 @@ package body Exp_Ch9 is
-- Simple_Mode; otherwise use Terminate_Mode.
if Present (Condition (Terminate_Alt)) then
- Select_Mode := Make_Conditional_Expression (Loc,
+ Select_Mode := Make_If_Expression (Loc,
New_List (Condition (Terminate_Alt),
New_Reference_To (RTE (RE_Terminate_Mode), Loc),
New_Reference_To (RTE (RE_Simple_Mode), Loc)));
diff --git a/gcc/ada/exp_disp.adb b/gcc/ada/exp_disp.adb
index f24828263..9b5cb5716 100644
--- a/gcc/ada/exp_disp.adb
+++ b/gcc/ada/exp_disp.adb
@@ -1068,6 +1068,32 @@ package body Exp_Disp is
-- to avoid the generation of spurious warnings under ZFP run-time.
Analyze_And_Resolve (Call_Node, Call_Typ, Suppress => All_Checks);
+
+ -- For functions returning interface types add implicit conversion to
+ -- force the displacement of the pointer to the object to reference
+ -- the corresponding secondary dispatch table. This is needed to
+ -- handle well nested calls through secondary dispatch tables
+ -- (for example Obj.Prim1.Prim2).
+
+ if Is_Interface (Res_Typ) then
+ Rewrite (Call_Node,
+ Make_Type_Conversion (Loc,
+ Subtype_Mark => New_Occurrence_Of (Res_Typ, Loc),
+ Expression => Relocate_Node (Call_Node)));
+ Set_Etype (Call_Node, Res_Typ);
+ Expand_Interface_Conversion (Call_Node, Is_Static => False);
+ Force_Evaluation (Call_Node);
+
+ pragma Assert (Nkind (Call_Node) = N_Explicit_Dereference
+ and then Nkind (Prefix (Call_Node)) = N_Identifier
+ and then Nkind (Parent (Entity (Prefix (Call_Node))))
+ = N_Object_Declaration);
+ Set_Assignment_OK (Parent (Entity (Prefix (Call_Node))));
+
+ if Nkind (Parent (Call_Node)) = N_Object_Declaration then
+ Set_Assignment_OK (Parent (Call_Node));
+ end if;
+ end if;
end Expand_Dispatching_Call;
---------------------------------
@@ -8421,115 +8447,57 @@ package body Exp_Disp is
procedure Set_CPP_Constructors (Typ : Entity_Id) is
- procedure Set_CPP_Constructors_Old (Typ : Entity_Id);
- -- For backward compatibility this routine handles CPP constructors
- -- of non-tagged types.
+ function Gen_Parameters_Profile (E : Entity_Id) return List_Id;
+ -- Duplicate the parameters profile of the imported C++ constructor
+ -- adding an access to the object as an additional parameter.
- procedure Set_CPP_Constructors_Old (Typ : Entity_Id) is
- Loc : Source_Ptr;
- Init : Entity_Id;
- E : Entity_Id;
- Found : Boolean := False;
- P : Node_Id;
+ function Gen_Parameters_Profile (E : Entity_Id) return List_Id is
+ Loc : constant Source_Ptr := Sloc (E);
Parms : List_Id;
+ P : Node_Id;
begin
- -- Look for the constructor entities
-
- E := Next_Entity (Typ);
- while Present (E) loop
- if Ekind (E) = E_Function
- and then Is_Constructor (E)
- then
- -- Create the init procedure
-
- Found := True;
- Loc := Sloc (E);
- Init := Make_Defining_Identifier (Loc,
- Make_Init_Proc_Name (Typ));
- Parms :=
- New_List (
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc, Name_X),
- Parameter_Type =>
- New_Reference_To (Typ, Loc)));
-
- if Present (Parameter_Specifications (Parent (E))) then
- P := First (Parameter_Specifications (Parent (E)));
- while Present (P) loop
- Append_To (Parms,
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars (Defining_Identifier (P))),
- Parameter_Type =>
- New_Copy_Tree (Parameter_Type (P))));
- Next (P);
- end loop;
- end if;
-
- Discard_Node (
- Make_Subprogram_Declaration (Loc,
- Make_Procedure_Specification (Loc,
- Defining_Unit_Name => Init,
- Parameter_Specifications => Parms)));
-
- Set_Init_Proc (Typ, Init);
- Set_Is_Imported (Init);
- Set_Is_Constructor (Init);
- Set_Interface_Name (Init, Interface_Name (E));
- Set_Convention (Init, Convention_CPP);
- Set_Is_Public (Init);
- Set_Has_Completion (Init);
- end if;
-
- Next_Entity (E);
- end loop;
-
- -- If there are no constructors, mark the type as abstract since we
- -- won't be able to declare objects of that type.
-
- if not Found then
- Set_Is_Abstract_Type (Typ);
+ Parms :=
+ New_List (
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier =>
+ Make_Defining_Identifier (Loc, Name_uInit),
+ Parameter_Type => New_Reference_To (Typ, Loc)));
+
+ if Present (Parameter_Specifications (Parent (E))) then
+ P := First (Parameter_Specifications (Parent (E)));
+ while Present (P) loop
+ Append_To (Parms,
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier =>
+ Make_Defining_Identifier (Loc,
+ Chars => Chars (Defining_Identifier (P))),
+ Parameter_Type => New_Copy_Tree (Parameter_Type (P)),
+ Expression => New_Copy_Tree (Expression (P))));
+ Next (P);
+ end loop;
end if;
- end Set_CPP_Constructors_Old;
+
+ return Parms;
+ end Gen_Parameters_Profile;
-- Local variables
- Loc : Source_Ptr;
- E : Entity_Id;
- Found : Boolean := False;
- P : Node_Id;
- Parms : List_Id;
+ Loc : Source_Ptr;
+ E : Entity_Id;
+ Found : Boolean := False;
+ IP : Entity_Id;
+ IP_Body : Node_Id;
+ P : Node_Id;
+ Parms : List_Id;
+
+ Covers_Default_Constructor : Entity_Id := Empty;
- Constructor_Decl_Node : Node_Id;
- Constructor_Id : Entity_Id;
- Wrapper_Id : Entity_Id;
- Wrapper_Body_Node : Node_Id;
- Actuals : List_Id;
- Body_Stmts : List_Id;
- Init_Tags_List : List_Id;
+ -- Start of processing for Set_CPP_Constructor
begin
pragma Assert (Is_CPP_Class (Typ));
- -- For backward compatibility the compiler accepts C++ classes
- -- imported through non-tagged record types. In such case the
- -- wrapper of the C++ constructor is useless because the _tag
- -- component is not available.
-
- -- Example:
- -- type Root is limited record ...
- -- pragma Import (CPP, Root);
- -- function New_Root return Root;
- -- pragma CPP_Constructor (New_Root, ... );
-
- if not Is_Tagged_Type (Typ) then
- Set_CPP_Constructors_Old (Typ);
- return;
- end if;
-
-- Look for the constructor entities
E := Next_Entity (Typ);
@@ -8539,154 +8507,178 @@ package body Exp_Disp is
then
Found := True;
Loc := Sloc (E);
+ Parms := Gen_Parameters_Profile (E);
+ IP :=
+ Make_Defining_Identifier (Loc,
+ Chars => Make_Init_Proc_Name (Typ));
+
+ -- Case 1: Constructor of non-tagged type
+
+ -- If the C++ class has no virtual methods then the matching Ada
+ -- type is a non-tagged record type. In such case there is no need
+ -- to generate a wrapper of the C++ constructor because the _tag
+ -- component is not available.
+
+ if not Is_Tagged_Type (Typ) then
+ Discard_Node
+ (Make_Subprogram_Declaration (Loc,
+ Specification =>
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => IP,
+ Parameter_Specifications => Parms)));
+
+ Set_Init_Proc (Typ, IP);
+ Set_Is_Imported (IP);
+ Set_Is_Constructor (IP);
+ Set_Interface_Name (IP, Interface_Name (E));
+ Set_Convention (IP, Convention_CPP);
+ Set_Is_Public (IP);
+ Set_Has_Completion (IP);
+
+ -- Case 2: Constructor of a tagged type
+
+ -- In this case we generate the IP as a wrapper of the the
+ -- C++ constructor because IP must also save copy of the _tag
+ -- generated in the C++ side. The copy of the _tag is used by
+ -- Build_CPP_Init_Procedure to elaborate derivations of C++ types.
- -- Generate the declaration of the imported C++ constructor
-
- Parms :=
- New_List (
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc, Name_uInit),
- Parameter_Type =>
- New_Reference_To (Typ, Loc)));
-
- if Present (Parameter_Specifications (Parent (E))) then
- P := First (Parameter_Specifications (Parent (E)));
- while Present (P) loop
- Append_To (Parms,
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars (Defining_Identifier (P))),
- Parameter_Type => New_Copy_Tree (Parameter_Type (P))));
- Next (P);
- end loop;
- end if;
-
- Constructor_Id := Make_Temporary (Loc, 'P');
-
- Constructor_Decl_Node :=
- Make_Subprogram_Declaration (Loc,
- Make_Procedure_Specification (Loc,
- Defining_Unit_Name => Constructor_Id,
- Parameter_Specifications => Parms));
-
- Set_Is_Imported (Constructor_Id);
- Set_Is_Constructor (Constructor_Id);
- Set_Interface_Name (Constructor_Id, Interface_Name (E));
- Set_Convention (Constructor_Id, Convention_CPP);
- Set_Is_Public (Constructor_Id);
- Set_Has_Completion (Constructor_Id);
+ -- Generate:
+ -- procedure IP (_init : Typ; ...) is
+ -- procedure ConstructorP (_init : Typ; ...);
+ -- pragma Import (ConstructorP);
+ -- begin
+ -- ConstructorP (_init, ...);
+ -- if Typ._tag = null then
+ -- Typ._tag := _init._tag;
+ -- end if;
+ -- end IP;
- -- Build the wrapper of this constructor
+ else
+ declare
+ Body_Stmts : constant List_Id := New_List;
+ Constructor_Id : Entity_Id;
+ Constructor_Decl_Node : Node_Id;
+ Init_Tags_List : List_Id;
- Parms :=
- New_List (
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc, Name_uInit),
- Parameter_Type =>
- New_Reference_To (Typ, Loc)));
-
- if Present (Parameter_Specifications (Parent (E))) then
- P := First (Parameter_Specifications (Parent (E)));
- while Present (P) loop
- Append_To (Parms,
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc,
- Chars (Defining_Identifier (P))),
- Parameter_Type => New_Copy_Tree (Parameter_Type (P))));
- Next (P);
- end loop;
- end if;
+ begin
+ Constructor_Id := Make_Temporary (Loc, 'P');
- Body_Stmts := New_List;
+ Constructor_Decl_Node :=
+ Make_Subprogram_Declaration (Loc,
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => Constructor_Id,
+ Parameter_Specifications => Parms));
- -- Invoke the C++ constructor
+ Set_Is_Imported (Constructor_Id);
+ Set_Is_Constructor (Constructor_Id);
+ Set_Interface_Name (Constructor_Id, Interface_Name (E));
+ Set_Convention (Constructor_Id, Convention_CPP);
+ Set_Is_Public (Constructor_Id);
+ Set_Has_Completion (Constructor_Id);
- Actuals := New_List;
+ -- Build the init procedure as a wrapper of this constructor
- P := First (Parms);
- while Present (P) loop
- Append_To (Actuals,
- New_Reference_To (Defining_Identifier (P), Loc));
- Next (P);
- end loop;
+ Parms := Gen_Parameters_Profile (E);
- Append_To (Body_Stmts,
- Make_Procedure_Call_Statement (Loc,
- Name => New_Reference_To (Constructor_Id, Loc),
- Parameter_Associations => Actuals));
+ -- Invoke the C++ constructor
- -- Initialize copies of C++ primary and secondary tags
+ declare
+ Actuals : constant List_Id := New_List;
- Init_Tags_List := New_List;
+ begin
+ P := First (Parms);
+ while Present (P) loop
+ Append_To (Actuals,
+ New_Reference_To (Defining_Identifier (P), Loc));
+ Next (P);
+ end loop;
- declare
- Tag_Elmt : Elmt_Id;
- Tag_Comp : Node_Id;
+ Append_To (Body_Stmts,
+ Make_Procedure_Call_Statement (Loc,
+ Name => New_Reference_To (Constructor_Id, Loc),
+ Parameter_Associations => Actuals));
+ end;
- begin
- Tag_Elmt := First_Elmt (Access_Disp_Table (Typ));
- Tag_Comp := First_Tag_Component (Typ);
+ -- Initialize copies of C++ primary and secondary tags
- while Present (Tag_Elmt)
- and then Is_Tag (Node (Tag_Elmt))
- loop
- -- Skip the following assertion with primary tags because
- -- Related_Type is not set on primary tag components
+ Init_Tags_List := New_List;
- pragma Assert (Tag_Comp = First_Tag_Component (Typ)
- or else Related_Type (Node (Tag_Elmt))
- = Related_Type (Tag_Comp));
+ declare
+ Tag_Elmt : Elmt_Id;
+ Tag_Comp : Node_Id;
- Append_To (Init_Tags_List,
- Make_Assignment_Statement (Loc,
- Name =>
- New_Reference_To (Node (Tag_Elmt), Loc),
- Expression =>
- Make_Selected_Component (Loc,
- Prefix =>
- Make_Identifier (Loc, Name_uInit),
- Selector_Name =>
- New_Reference_To (Tag_Comp, Loc))));
+ begin
+ Tag_Elmt := First_Elmt (Access_Disp_Table (Typ));
+ Tag_Comp := First_Tag_Component (Typ);
- Tag_Comp := Next_Tag_Component (Tag_Comp);
- Next_Elmt (Tag_Elmt);
- end loop;
- end;
+ while Present (Tag_Elmt)
+ and then Is_Tag (Node (Tag_Elmt))
+ loop
+ -- Skip the following assertion with primary tags
+ -- because Related_Type is not set on primary tag
+ -- components
+
+ pragma Assert
+ (Tag_Comp = First_Tag_Component (Typ)
+ or else Related_Type (Node (Tag_Elmt))
+ = Related_Type (Tag_Comp));
+
+ Append_To (Init_Tags_List,
+ Make_Assignment_Statement (Loc,
+ Name =>
+ New_Reference_To (Node (Tag_Elmt), Loc),
+ Expression =>
+ Make_Selected_Component (Loc,
+ Prefix =>
+ Make_Identifier (Loc, Name_uInit),
+ Selector_Name =>
+ New_Reference_To (Tag_Comp, Loc))));
- Append_To (Body_Stmts,
- Make_If_Statement (Loc,
- Condition =>
- Make_Op_Eq (Loc,
- Left_Opnd =>
- New_Reference_To
- (Node (First_Elmt (Access_Disp_Table (Typ))),
- Loc),
- Right_Opnd =>
- Unchecked_Convert_To (RTE (RE_Tag),
- New_Reference_To (RTE (RE_Null_Address), Loc))),
- Then_Statements => Init_Tags_List));
+ Tag_Comp := Next_Tag_Component (Tag_Comp);
+ Next_Elmt (Tag_Elmt);
+ end loop;
+ end;
- Wrapper_Id := Make_Defining_Identifier (Loc,
- Make_Init_Proc_Name (Typ));
+ Append_To (Body_Stmts,
+ Make_If_Statement (Loc,
+ Condition =>
+ Make_Op_Eq (Loc,
+ Left_Opnd =>
+ New_Reference_To
+ (Node (First_Elmt (Access_Disp_Table (Typ))),
+ Loc),
+ Right_Opnd =>
+ Unchecked_Convert_To (RTE (RE_Tag),
+ New_Reference_To (RTE (RE_Null_Address), Loc))),
+ Then_Statements => Init_Tags_List));
+
+ IP_Body :=
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => IP,
+ Parameter_Specifications => Parms),
+ Declarations => New_List (Constructor_Decl_Node),
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => Body_Stmts,
+ Exception_Handlers => No_List));
+
+ Discard_Node (IP_Body);
+ Set_Init_Proc (Typ, IP);
+ end;
+ end if;
- Wrapper_Body_Node :=
- Make_Subprogram_Body (Loc,
- Specification =>
- Make_Procedure_Specification (Loc,
- Defining_Unit_Name => Wrapper_Id,
- Parameter_Specifications => Parms),
- Declarations => New_List (Constructor_Decl_Node),
- Handled_Statement_Sequence =>
- Make_Handled_Sequence_Of_Statements (Loc,
- Statements => Body_Stmts,
- Exception_Handlers => No_List));
+ -- If this constructor has parameters and all its parameters
+ -- have defaults then it covers the default constructor. The
+ -- semantic analyzer ensures that only one constructor with
+ -- defaults covers the default constructor.
- Discard_Node (Wrapper_Body_Node);
- Set_Init_Proc (Typ, Wrapper_Id);
+ if Present (Parameter_Specifications (Parent (E)))
+ and then Needs_No_Actuals (E)
+ then
+ Covers_Default_Constructor := IP;
+ end if;
end if;
Next_Entity (E);
@@ -8699,6 +8691,49 @@ package body Exp_Disp is
Set_Is_Abstract_Type (Typ);
end if;
+ -- Handle constructor that has all its parameters with defaults and
+ -- hence it covers the default constructor. We generate a wrapper IP
+ -- which calls the covering constructor.
+
+ if Present (Covers_Default_Constructor) then
+ declare
+ Body_Stmts : List_Id;
+
+ begin
+ Loc := Sloc (Covers_Default_Constructor);
+
+ Body_Stmts := New_List (
+ Make_Procedure_Call_Statement (Loc,
+ Name =>
+ New_Reference_To (Covers_Default_Constructor, Loc),
+ Parameter_Associations => New_List (
+ Make_Identifier (Loc, Name_uInit))));
+
+ IP := Make_Defining_Identifier (Loc, Make_Init_Proc_Name (Typ));
+
+ IP_Body :=
+ Make_Subprogram_Body (Loc,
+ Specification =>
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => IP,
+ Parameter_Specifications => New_List (
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier =>
+ Make_Defining_Identifier (Loc, Name_uInit),
+ Parameter_Type => New_Reference_To (Typ, Loc)))),
+
+ Declarations => No_List,
+
+ Handled_Statement_Sequence =>
+ Make_Handled_Sequence_Of_Statements (Loc,
+ Statements => Body_Stmts,
+ Exception_Handlers => No_List));
+
+ Discard_Node (IP_Body);
+ Set_Init_Proc (Typ, IP);
+ end;
+ end if;
+
-- If the CPP type has constructors then it must import also the default
-- C++ constructor. It is required for default initialization of objects
-- of the type. It is also required to elaborate objects of Ada types
diff --git a/gcc/ada/exp_imgv.adb b/gcc/ada/exp_imgv.adb
index f2e22f768..5da403bb3 100644
--- a/gcc/ada/exp_imgv.adb
+++ b/gcc/ada/exp_imgv.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2012, 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- --
@@ -1063,9 +1063,9 @@ package body Exp_Imgv is
-- for depending on the element type for typI.
-- Finally if Discard_Names is in effect for an enumeration type, then
- -- a special conditional expression is built that yields the space needed
- -- for the decimal representation of the largest pos value in the subtype.
- -- See code below for details.
+ -- a special if expression is built that yields the space needed for the
+ -- decimal representation of the largest pos value in the subtype. See
+ -- code below for details.
procedure Expand_Width_Attribute (N : Node_Id; Attr : Atype := Normal) is
Loc : constant Source_Ptr := Sloc (N);
@@ -1134,7 +1134,7 @@ package body Exp_Imgv is
elsif Is_Real_Type (Rtyp) then
Rewrite (N,
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Gt (Loc,
@@ -1214,8 +1214,8 @@ package body Exp_Imgv is
Prefix => New_Occurrence_Of (Ptyp, Loc),
Attribute_Name => Name_Last))))));
- -- OK, now we need to build the conditional expression. First
- -- get the value of M, the largest possible value needed.
+ -- OK, now we need to build the if expression. First get the
+ -- value of M, the largest possible value needed.
P := UI_To_Int
(Enumeration_Pos (Entity (Type_High_Bound (Rtyp))));
@@ -1238,7 +1238,7 @@ package body Exp_Imgv is
K := K - 1;
Cexpr :=
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Lt (Loc,
Left_Opnd => New_Occurrence_Of (Tnn, Loc),
@@ -1252,7 +1252,7 @@ package body Exp_Imgv is
Rewrite (N,
Convert_To (Typ,
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Eq (Loc,
Left_Opnd =>
diff --git a/gcc/ada/exp_intr.adb b/gcc/ada/exp_intr.adb
index dcf6b5265..bc43a4b4e 100644
--- a/gcc/ada/exp_intr.adb
+++ b/gcc/ada/exp_intr.adb
@@ -603,7 +603,7 @@ package body Exp_Intr is
-- end if;
Rewrite (N,
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Lt (Loc,
Left_Opnd => Duplicate_Subexpr (Opnd),
@@ -611,7 +611,7 @@ package body Exp_Intr is
New_Occurrence_Of (Standard_True, Loc),
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Gt (Loc,
Left_Opnd => Duplicate_Subexpr_No_Checks (Opnd),
@@ -1311,7 +1311,7 @@ package body Exp_Intr is
Obj := Make_Explicit_Dereference (Loc, Relocate_Node (Arg));
Rewrite (N,
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (
Make_Op_Eq (Loc,
Left_Opnd => New_Copy_Tree (Arg),
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index f7b9d4501..cc3213d03 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -710,8 +710,11 @@ package body Exp_Util is
Subpool := Subpool_Handle_Name (Expr);
end if;
+ -- If a subpool is present it can be an arbitrary name, so make
+ -- the actual by copying the tree.
+
if Present (Subpool) then
- Append_To (Actuals, New_Reference_To (Entity (Subpool), Loc));
+ Append_To (Actuals, New_Copy_Tree (Subpool, New_Sloc => Loc));
else
Append_To (Actuals, Make_Null (Loc));
end if;
@@ -2163,6 +2166,7 @@ package body Exp_Util is
(Var : Entity_Id;
Rep_Clause : Node_Id) return Node_Id
is
+ Par : constant Node_Id := Parent (Var);
Typ : constant Entity_Id := Etype (Var);
Init_Proc : Entity_Id;
@@ -2201,6 +2205,7 @@ package body Exp_Util is
begin
if not Has_Non_Null_Base_Init_Proc (Typ) then
+
-- No init proc for the type, so obviously no call to be found
return Empty;
@@ -2210,7 +2215,7 @@ package body Exp_Util is
-- First scan the list containing the declaration of Var
- Init_Call := Find_Init_Call_In_List (From => Next (Parent (Var)));
+ Init_Call := Find_Init_Call_In_List (From => Next (Par));
-- If not found, also look on Var's freeze actions list, if any, since
-- the init call may have been moved there (case of an address clause
@@ -2221,6 +2226,23 @@ package body Exp_Util is
Find_Init_Call_In_List (First (Actions (Freeze_Node (Var))));
end if;
+ -- If the initialization call has actuals that use the secondary stack,
+ -- the call may have been wrapped into a temporary block, in which case
+ -- the block itself has to be removed.
+
+ if No (Init_Call) and then Nkind (Next (Par)) = N_Block_Statement then
+ declare
+ Blk : constant Node_Id := Next (Par);
+ begin
+ if Present
+ (Find_Init_Call_In_List
+ (First (Statements (Handled_Statement_Sequence (Blk)))))
+ then
+ Init_Call := Blk;
+ end if;
+ end;
+ end if;
+
return Init_Call;
end Find_Init_Call;
@@ -3293,11 +3315,11 @@ package body Exp_Util is
return;
end if;
- -- Then or Else operand of conditional expression. Add actions to
- -- Then_Actions or Else_Actions field as appropriate. The actions
- -- will be moved further out when the conditional is expanded.
+ -- Then or Else dependent expression of an if expression. Add
+ -- actions to Then_Actions or Else_Actions field as appropriate.
+ -- The actions will be moved further out when the if is expanded.
- when N_Conditional_Expression =>
+ when N_If_Expression =>
declare
ThenX : constant Node_Id := Next (First (Expressions (P)));
ElseX : constant Node_Id := Next (ThenX);
@@ -3311,9 +3333,9 @@ package body Exp_Util is
null;
-- Actions belong to the then expression, temporarily place
- -- them as Then_Actions of the conditional expr. They will
- -- be moved to the proper place later when the conditional
- -- expression is expanded.
+ -- them as Then_Actions of the if expression. They will be
+ -- moved to the proper place later when the if expression
+ -- is expanded.
elsif N = ThenX then
if Present (Then_Actions (P)) then
@@ -3326,10 +3348,10 @@ package body Exp_Util is
return;
- -- Actions belong to the else expression, temporarily
- -- place them as Else_Actions of the conditional expr.
- -- They will be moved to the proper place later when
- -- the conditional expression is expanded.
+ -- Actions belong to the else expression, temporarily place
+ -- them as Else_Actions of the if expression. They will be
+ -- moved to the proper place later when the if expression
+ -- is expanded.
elsif N = ElseX then
if Present (Else_Actions (P)) then
@@ -7187,8 +7209,8 @@ package body Exp_Util is
then
return True;
- -- Processing for intermediate results of conditional expressions
- -- where one of the alternatives uses a controlled function call.
+ -- Processing for intermediate results of if expressions where
+ -- one of the alternatives uses a controlled function call.
elsif Is_Access_Type (Obj_Typ)
and then Present (Status_Flag_Or_Transient_Decl (Obj_Id))
diff --git a/gcc/ada/exp_util.ads b/gcc/ada/exp_util.ads
index e25d48e66..f89a0ac16 100644
--- a/gcc/ada/exp_util.ads
+++ b/gcc/ada/exp_util.ads
@@ -72,8 +72,8 @@ package Exp_Util is
-- For actions appearing in the then or else expression of a conditional
-- expression, these actions are similarly placed in the node, using the
-- Then_Actions or Else_Actions field as appropriate. Once again the
- -- expansion of the N_Conditional_Expression node rewrites the node so
- -- that the actions can be normally positioned.
+ -- expansion of the N_If_Expression node rewrites the node so that the
+ -- actions can be positioned normally.
-- Basically what we do is to climb up to the tree looking for the
-- proper insertion point, as described by one of the above cases,
diff --git a/gcc/ada/expander.adb b/gcc/ada/expander.adb
index 8dcc19da3..af367d951 100644
--- a/gcc/ada/expander.adb
+++ b/gcc/ada/expander.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -182,9 +182,6 @@ package body Expander is
when N_Conditional_Entry_Call =>
Expand_N_Conditional_Entry_Call (N);
- when N_Conditional_Expression =>
- Expand_N_Conditional_Expression (N);
-
when N_Delay_Relative_Statement =>
Expand_N_Delay_Relative_Statement (N);
@@ -248,6 +245,9 @@ package body Expander is
when N_Identifier =>
Expand_N_Identifier (N);
+ when N_If_Expression =>
+ Expand_N_If_Expression (N);
+
when N_Indexed_Component =>
Expand_N_Indexed_Component (N);
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index ad9f06a06..9e0cbcacf 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -24,6 +24,7 @@
------------------------------------------------------------------------------
with Atree; use Atree;
+with Checks; use Checks;
with Debug; use Debug;
with Einfo; use Einfo;
with Elists; use Elists;
@@ -2570,8 +2571,15 @@ package body Freeze is
-- It is improper to freeze an external entity within a generic because
-- its freeze node will appear in a non-valid context. The entity will
-- be frozen in the proper scope after the current generic is analyzed.
+ -- However, aspects must be analyzed because they may be queried later
+ -- within the generic itself, and the corresponding pragma or attribute
+ -- definition has not been analyzed yet.
elsif Inside_A_Generic and then External_Ref_In_Generic (Test_E) then
+ if Has_Delayed_Aspects (E) then
+ Analyze_Aspects_At_Freeze_Point (E);
+ end if;
+
return No_List;
-- AI05-0213: A formal incomplete type does not freeze the actual. In
@@ -2655,12 +2663,20 @@ package body Freeze is
end;
end if;
- -- Deal with delayed aspect specifications. The analysis of the
- -- aspect is required to be delayed to the freeze point, thus we
- -- analyze the pragma or attribute definition clause in the tree at
- -- this point. We also analyze the aspect specification node at the
- -- freeze point when the aspect doesn't correspond to
- -- pragma/attribute definition clause.
+ -- Add checks to detect proper initialization of scalars that may appear
+ -- as subprogram parameters.
+
+ if Is_Subprogram (E)
+ and then Check_Validity_Of_Parameters
+ then
+ Apply_Parameter_Validity_Checks (E);
+ end if;
+
+ -- Deal with delayed aspect specifications. The analysis of the aspect
+ -- is required to be delayed to the freeze point, thus we analyze the
+ -- pragma or attribute definition clause in the tree at this point. We
+ -- also analyze the aspect specification node at the freeze point when
+ -- the aspect doesn't correspond to pragma/attribute definition clause.
if Has_Delayed_Aspects (E) then
Analyze_Aspects_At_Freeze_Point (E);
@@ -5140,43 +5156,63 @@ package body Freeze is
-- subprogram body that we are inside.
if In_Exp_Body (Parent_P) then
-
- -- However, we *do* want to freeze at this point if we have
- -- an entity to freeze, and that entity is declared *inside*
- -- the body of the expander generated procedure. This case
- -- is recognized by the scope of the type, which is either
- -- the spec for some enclosing body, or (in the case of
- -- init_procs, for which there are no separate specs) the
- -- current scope.
-
declare
Subp : constant Node_Id := Parent (Parent_P);
- Cspc : Entity_Id;
+ Spec : Entity_Id;
begin
+ -- Freeze the entity only when it is declared inside the
+ -- body of the expander generated procedure. This case
+ -- is recognized by the scope of the entity or its type,
+ -- which is either the spec for some enclosing body, or
+ -- (in the case of init_procs, for which there are no
+ -- separate specs) the current scope.
+
if Nkind (Subp) = N_Subprogram_Body then
- Cspc := Corresponding_Spec (Subp);
+ Spec := Corresponding_Spec (Subp);
- if (Present (Typ) and then Scope (Typ) = Cspc)
+ if (Present (Typ) and then Scope (Typ) = Spec)
or else
- (Present (Nam) and then Scope (Nam) = Cspc)
+ (Present (Nam) and then Scope (Nam) = Spec)
then
exit;
elsif Present (Typ)
and then Scope (Typ) = Current_Scope
- and then Current_Scope = Defining_Entity (Subp)
+ and then Defining_Entity (Subp) = Current_Scope
then
exit;
end if;
end if;
- end;
- -- If not that exception to the exception, then this is
- -- where we delay the freeze till outside the body.
+ -- An expression function may act as a completion of
+ -- a function declaration. As such, it can reference
+ -- entities declared between the two views:
- Parent_P := Parent (Parent_P);
- Freeze_Outside := True;
+ -- Hidden []; -- 1
+ -- function F return ...;
+ -- private
+ -- function Hidden return ...;
+ -- function F return ... is (Hidden); -- 2
+
+ -- Refering to the example above, freezing the expression
+ -- of F (2) would place Hidden's freeze node (1) in the
+ -- wrong place. Avoid explicit freezing and let the usual
+ -- scenarios do the job - for example, reaching the end
+ -- of the private declarations.
+
+ if Nkind (Original_Node (Subp)) =
+ N_Expression_Function
+ then
+ null;
+
+ -- Freeze outside the body
+
+ else
+ Parent_P := Parent (Parent_P);
+ Freeze_Outside := True;
+ end if;
+ end;
-- Here if normal case where we are in handled statement
-- sequence and want to do the insertion right there.
diff --git a/gcc/ada/g-comlin.adb b/gcc/ada/g-comlin.adb
index 723ff120f..f11846fbb 100644
--- a/gcc/ada/g-comlin.adb
+++ b/gcc/ada/g-comlin.adb
@@ -39,6 +39,10 @@ with GNAT.OS_Lib; use GNAT.OS_Lib;
package body GNAT.Command_Line is
+ -- General note: this entire body could use much more commenting. There
+ -- are large sections of uncommented code throughout, and many formal
+ -- parameters of local subprograms are not documented at all ???
+
package CL renames Ada.Command_Line;
type Switch_Parameter_Type is
@@ -56,6 +60,12 @@ package body GNAT.Command_Line is
Extra : Character := ASCII.NUL);
pragma Inline (Set_Parameter);
-- Set the parameter that will be returned by Parameter below
+ --
+ -- Extra is a character that needs to be added when reporting Full_Switch.
+ -- (it will in general be the switch character, for instance '-').
+ -- Otherwise, Full_Switch will report 'f' instead of '-f'. In particular,
+ -- it needs to be set when reporting an invalid switch or handling '*'.
+ --
-- Parameters need to be defined ???
function Goto_Next_Argument_In_Section (Parser : Opt_Parser) return Boolean;
@@ -95,9 +105,9 @@ package body GNAT.Command_Line is
Index_In_Switches : out Integer;
Switch_Length : out Integer;
Param : out Switch_Parameter_Type);
- -- Return the Longest switch from Switches that at least partially
- -- partially Arg. Index_In_Switches is set to 0 if none matches.
- -- What are other parameters??? in particular Param is not always set???
+ -- Return the Longest switch from Switches that at least partially matches
+ -- Arg. Index_In_Switches is set to 0 if none matches. What are other
+ -- parameters??? in particular Param is not always set???
procedure Unchecked_Free is new Ada.Unchecked_Deallocation
(Argument_List, Argument_List_Access);
@@ -663,17 +673,45 @@ package body GNAT.Command_Line is
if Index_Switches = 0 then
- -- Depending on the value of Concatenate, the full switch is
- -- a single character or the rest of the argument.
+ -- Find the current switch that we did not recognize. This is in
+ -- fact difficult because Getopt does not know explicitly about
+ -- short and long switches. Ideally, we would want the following
+ -- behavior:
+
+ -- * for short switches, with Concatenate:
+ -- if -a is not recognized, and the command line has -daf
+ -- we should report the invalid switch as "-a".
+
+ -- * for short switches, wihtout Concatenate:
+ -- we should report the invalid switch as "-daf".
+
+ -- * for long switches:
+ -- if the commadn line is "--long" we should report --long
+ -- as unrecongized.
+
+ -- Unfortunately, the fact that long switches start with a
+ -- duplicate switch character is just a convention (so we could
+ -- have a long switch "-long" for instance). We'll still rely on
+ -- this convention here to try and get as helpful an error message
+ -- as possible.
+
+ -- Long switch case (starting with double switch character)
- End_Index :=
- (if Concatenate then Parser.Current_Index else Arg'Last);
+ if Arg (Arg'First + 1) = Parser.Switch_Character then
+ End_Index := Arg'Last;
+
+ -- Short switch case
+
+ else
+ End_Index :=
+ (if Concatenate then Parser.Current_Index else Arg'Last);
+ end if;
if Switches (Switches'First) = '*' then
- -- Always prepend the switch character, so that users know that
- -- this comes from a switch on the command line. This is
- -- especially important when Concatenate is False, since
+ -- Always prepend the switch character, so that users know
+ -- that this comes from a switch on the command line. This
+ -- is especially important when Concatenate is False, since
-- otherwise the current argument first character is lost.
if Parser.Section (Parser.Current_Argument) = 0 then
@@ -696,11 +734,21 @@ package body GNAT.Command_Line is
end if;
end if;
- Set_Parameter
- (Parser.The_Switch,
- Arg_Num => Parser.Current_Argument,
- First => Parser.Current_Index,
- Last => End_Index);
+ if Parser.Current_Index = Arg'First then
+ Set_Parameter
+ (Parser.The_Switch,
+ Arg_Num => Parser.Current_Argument,
+ First => Parser.Current_Index,
+ Last => End_Index);
+ else
+ Set_Parameter
+ (Parser.The_Switch,
+ Arg_Num => Parser.Current_Argument,
+ First => Parser.Current_Index,
+ Last => End_Index,
+ Extra => Parser.Switch_Character);
+ end if;
+
Parser.Current_Index := End_Index + 1;
raise Invalid_Switch;
@@ -762,7 +810,7 @@ package body GNAT.Command_Line is
raise Invalid_Parameter;
end if;
- -- If the switch is of the form <switch> xxx
+ -- Case of switch of the form <switch> xxx
elsif Parser.Current_Argument < Parser.Arg_Count
and then Parser.Section (Parser.Current_Argument + 1) /= 0
@@ -830,7 +878,8 @@ package body GNAT.Command_Line is
(Parser.The_Switch,
Arg_Num => Parser.Current_Argument,
First => Parser.Current_Index,
- Last => Arg'Last);
+ Last => Arg'Last,
+ Extra => Parser.Switch_Character);
Parser.Current_Index := Arg'Last + 1;
raise Invalid_Switch;
end if;
@@ -1170,9 +1219,7 @@ package body GNAT.Command_Line is
procedure Unchecked_Free is new
Ada.Unchecked_Deallocation (Opt_Parser_Data, Opt_Parser);
begin
- if Parser /= null
- and then Parser /= Command_Line_Parser
- then
+ if Parser /= null and then Parser /= Command_Line_Parser then
Free (Parser.Arguments);
Unchecked_Free (Parser);
end if;
@@ -1189,6 +1236,7 @@ package body GNAT.Command_Line is
Section : String := "")
is
Def : Alias_Definition;
+
begin
if Config = null then
Config := new Command_Line_Configuration_Record;
@@ -1255,8 +1303,9 @@ package body GNAT.Command_Line is
-- Add --
---------
- procedure Add (Def : in out Alias_Definitions_List;
- Alias : Alias_Definition)
+ procedure Add
+ (Def : in out Alias_Definitions_List;
+ Alias : Alias_Definition)
is
procedure Unchecked_Free is new
Ada.Unchecked_Deallocation
@@ -1511,7 +1560,7 @@ package body GNAT.Command_Line is
Foreach (Config, Section => Section);
- -- Adding relevant aliases
+ -- Add relevant aliases
if Config.Aliases /= null then
for A in Config.Aliases'Range loop
@@ -1585,8 +1634,8 @@ package body GNAT.Command_Line is
function Real_Full_Switch
(S : Character;
Parser : Opt_Parser) return String;
- -- Ensure that the returned switch value contains the
- -- Switch_Char prefix if needed.
+ -- Ensure that the returned switch value contains the Switch_Char prefix
+ -- if needed.
----------------------
-- Real_Full_Switch --
@@ -2465,13 +2514,12 @@ package body GNAT.Command_Line is
((Cmd.Params (C) = null and then Param = "")
or else
(Cmd.Params (C) /= null
- and then
- -- Ignore the separator stored in Parameter
+ -- Ignore the separator stored in Parameter
+ and then
Cmd.Params (C) (Cmd.Params (C)'First + 1
- .. Cmd.Params (C)'Last) =
- Param))
+ .. Cmd.Params (C)'Last) = Param))
then
Remove (Cmd.Expanded, C);
Remove (Cmd.Params, C);
@@ -2550,9 +2598,7 @@ package body GNAT.Command_Line is
-- Start of processing for Group_Switches
begin
- if Cmd.Config = null
- or else Cmd.Config.Prefixes = null
- then
+ if Cmd.Config = null or else Cmd.Config.Prefixes = null then
return;
end if;
@@ -2638,10 +2684,9 @@ package body GNAT.Command_Line is
First : Natural;
procedure Check_Cb (Switch, Separator, Param : String; Index : Integer);
- -- Checks whether the command line contains [Switch].
- -- Sets the global variable [Found] appropriately.
- -- This will be called for each simple switch that make up an alias, to
- -- know whether the alias should be applied.
+ -- Checks whether the command line contains [Switch]. Sets the global
+ -- variable [Found] appropriately. This is called for each simple switch
+ -- that make up an alias, to know whether the alias should be applied.
procedure Remove_Cb (Switch, Separator, Param : String; Index : Integer);
-- Remove the simple switch [Switch] from the command line, since it is
@@ -2708,9 +2753,7 @@ package body GNAT.Command_Line is
-- Start of processing for Alias_Switches
begin
- if Cmd.Config = null
- or else Cmd.Config.Aliases = null
- then
+ if Cmd.Config = null or else Cmd.Config.Aliases = null then
return;
end if;
@@ -3079,7 +3122,7 @@ package body GNAT.Command_Line is
procedure Display_Help (Config : Command_Line_Configuration) is
function Switch_Name
- (Def : Switch_Definition;
+ (Def : Switch_Definition;
Section : String) return String;
-- Return the "-short, --long=ARG" string for Def.
-- Returns "" if the switch is not in the section.
@@ -3194,7 +3237,7 @@ package body GNAT.Command_Line is
-----------------
function Switch_Name
- (Def : Switch_Definition;
+ (Def : Switch_Definition;
Section : String) return String
is
use Ada.Strings.Unbounded;
@@ -3488,7 +3531,7 @@ package body GNAT.Command_Line is
Put_Line (Standard_Error,
Base_Name (Ada.Command_Line.Command_Name)
& ": unrecognized option '"
- & Parser.Switch_Character & Full_Switch (Parser)
+ & Full_Switch (Parser)
& "'");
Put_Line (Standard_Error,
"Try `"
diff --git a/gcc/ada/g-socket.adb b/gcc/ada/g-socket.adb
index ac03f4216..731919be3 100644
--- a/gcc/ada/g-socket.adb
+++ b/gcc/ada/g-socket.adb
@@ -123,7 +123,7 @@ package body GNAT.Sockets is
function Resolve_Error
(Error_Value : Integer;
From_Errno : Boolean := True) return Error_Type;
- -- Associate an enumeration value (error_type) to en error value (errno).
+ -- Associate an enumeration value (error_type) to an error value (errno).
-- From_Errno prevents from mixing h_errno with errno.
function To_Name (N : String) return Name_Type;
@@ -702,6 +702,13 @@ package body GNAT.Sockets is
Req : Request_Type;
-- Used to set Socket to non-blocking I/O
+ Conn_Err : aliased Integer;
+ -- Error status of the socket after completion of select(2)
+
+ Res : C.int;
+ Conn_Err_Size : aliased C.int := Conn_Err'Size / 8;
+ -- For getsockopt(2) call
+
begin
if Selector /= null and then not Is_Open (Selector.all) then
raise Program_Error with "closed selector";
@@ -735,10 +742,32 @@ package body GNAT.Sockets is
Selector => Selector,
Status => Status);
+ -- Check error condition (the asynchronous connect may have terminated
+ -- with an error, e.g. ECONNREFUSED) if select(2) completed.
+
+ if Status = Completed then
+ Res := C_Getsockopt
+ (C.int (Socket), SOSC.SOL_SOCKET, SOSC.SO_ERROR,
+ Conn_Err'Address, Conn_Err_Size'Access);
+
+ if Res /= 0 then
+ Conn_Err := Socket_Errno;
+ end if;
+
+ else
+ Conn_Err := 0;
+ end if;
+
-- Reset the socket to blocking I/O
Req := (Name => Non_Blocking_IO, Enabled => False);
Control_Socket (Socket, Request => Req);
+
+ -- Report error condition if any
+
+ if Conn_Err /= 0 then
+ Raise_Socket_Error (Conn_Err);
+ end if;
end Connect_Socket;
--------------------
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index ba5148abd..60637c9bb 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -172,7 +172,7 @@ endif
# Strip -Werror during linking for the LTO bootstrap
GCC_LINKERFLAGS = $(filter-out -Werror, $(ALL_LINKERFLAGS))
-GCC_LINK=$(LINKER) $(GCC_LINKERFLAGS) -static-libgcc $(LDFLAGS)
+GCC_LINK=$(LINKER) $(GCC_LINKERFLAGS) -static-libgcc -static-libstdc++ $(LDFLAGS)
# Lists of files for various purposes.
@@ -1257,29 +1257,33 @@ ada/checks.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/csets.ads ada/debug.ads ada/einfo.ads ada/einfo.adb ada/elists.ads \
ada/elists.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
ada/eval_fat.ads ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads \
- ada/exp_ch4.ads ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_dist.ads \
- ada/exp_pakd.ads ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb \
- ada/fname.ads ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads \
- ada/gnat.ads ada/g-hesorg.ads ada/g-htable.ads ada/gnatvsn.ads \
- ada/hostparm.ads ada/inline.ads ada/itypes.ads ada/lib.ads ada/lib.adb \
- ada/lib-list.adb ada/lib-load.ads ada/lib-sort.adb ada/namet.ads \
- ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
- ada/opt.adb ada/output.ads ada/restrict.ads ada/restrict.adb \
- ada/rident.ads ada/rtsfind.ads ada/rtsfind.adb ada/sem.ads \
+ ada/exp_ch4.ads ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_disp.ads \
+ ada/exp_dist.ads ada/exp_pakd.ads ada/exp_tss.ads ada/exp_util.ads \
+ ada/exp_util.adb ada/expander.ads ada/fname.ads ada/fname-uf.ads \
+ ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-hesorg.ads \
+ ada/g-htable.ads ada/gnatvsn.ads ada/hostparm.ads ada/inline.ads \
+ ada/itypes.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
+ ada/lib-load.ads ada/lib-sort.adb ada/lib-util.ads ada/lib-xref.ads \
+ ada/namet.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb \
+ ada/opt.ads ada/opt.adb ada/output.ads ada/put_alfa.ads \
+ ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \
+ ada/rtsfind.adb ada/scans.ads ada/sem.ads ada/sem_attr.ads \
ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch3.ads ada/sem_ch6.ads \
- ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_dist.ads ada/sem_eval.ads \
- ada/sem_eval.adb ada/sem_prag.ads ada/sem_res.ads ada/sem_type.ads \
- ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \
- ada/sinput.ads ada/snames.ads ada/sprint.ads ada/stand.ads \
- ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \
- ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \
- ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \
- ada/urealp.ads ada/urealp.adb ada/validsw.ads ada/widechar.ads
+ ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads \
+ ada/sem_eval.ads ada/sem_eval.adb ada/sem_prag.ads ada/sem_res.ads \
+ ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \
+ ada/sprint.ads ada/stand.ads ada/stringt.ads ada/style.ads \
+ ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \
+ ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
+ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \
+ ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/urealp.adb \
+ ada/validsw.ads ada/widechar.ads
ada/comperr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -1464,9 +1468,9 @@ ada/exp_alfa.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_alfa.ads ada/exp_alfa.adb ada/exp_attr.ads ada/exp_ch4.ads \
ada/exp_ch6.ads ada/exp_dbug.ads ada/exp_tss.ads ada/exp_util.ads \
ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \
- ada/nmake.ads ada/opt.ads ada/output.ads ada/rtsfind.ads \
- ada/sem_aux.ads ada/sem_aux.adb ada/sem_res.ads ada/sem_util.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/opt.ads ada/output.ads ada/rtsfind.ads ada/sem_aux.ads \
+ ada/sem_aux.adb ada/sem_res.ads ada/sem_util.ads ada/sinfo.ads \
+ ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
ada/s-os_lib.ads ada/s-parame.ads ada/s-soflin.ads ada/s-stache.ads \
ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
@@ -1538,7 +1542,7 @@ ada/exp_cg.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/elists.ads ada/elists.adb ada/exp_cg.ads ada/exp_cg.adb \
ada/exp_dbug.ads ada/exp_disp.ads ada/exp_tss.ads ada/gnat.ads \
ada/g-htable.ads ada/hostparm.ads ada/lib.ads ada/namet.ads \
- ada/nlists.ads ada/nmake.ads ada/opt.ads ada/output.ads ada/sem_aux.ads \
+ ada/nlists.ads ada/opt.ads ada/output.ads ada/sem_aux.ads \
ada/sem_aux.adb ada/sem_disp.ads ada/sem_type.ads ada/sem_util.ads \
ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
@@ -1638,28 +1642,28 @@ ada/exp_ch3.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_ch4.ads ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_ch9.ads \
ada/exp_dbug.ads ada/exp_disp.ads ada/exp_disp.adb ada/exp_dist.ads \
ada/exp_pakd.ads ada/exp_smem.ads ada/exp_strm.ads ada/exp_tss.ads \
- ada/exp_tss.adb ada/exp_util.ads ada/exp_util.adb ada/fname.ads \
- ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
- ada/g-htable.ads ada/hostparm.ads ada/inline.ads ada/itypes.ads \
- ada/layout.ads ada/lib.ads ada/lib-load.ads ada/namet.ads \
- ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
- ada/output.ads ada/restrict.ads ada/restrict.adb ada/rident.ads \
- ada/rtsfind.ads ada/rtsfind.adb ada/scil_ll.ads ada/sem.ads \
- ada/sem_attr.ads ada/sem_aux.ads ada/sem_aux.adb ada/sem_cat.ads \
- ada/sem_ch3.ads ada/sem_ch6.ads ada/sem_ch7.ads ada/sem_ch8.ads \
- ada/sem_disp.ads ada/sem_dist.ads ada/sem_eval.ads ada/sem_mech.ads \
- ada/sem_prag.ads ada/sem_res.ads ada/sem_scil.ads ada/sem_type.ads \
- ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb \
- ada/sinput.ads ada/snames.ads ada/sprint.ads ada/stand.ads \
- ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \
- ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \
- ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \
- ada/urealp.ads ada/validsw.ads
+ ada/exp_tss.adb ada/exp_util.ads ada/exp_util.adb ada/expander.ads \
+ ada/fname.ads ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads \
+ ada/gnat.ads ada/g-htable.ads ada/hostparm.ads ada/inline.ads \
+ ada/itypes.ads ada/layout.ads ada/lib.ads ada/lib-load.ads \
+ ada/namet.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb \
+ ada/opt.ads ada/output.ads ada/restrict.ads ada/restrict.adb \
+ ada/rident.ads ada/rtsfind.ads ada/rtsfind.adb ada/scil_ll.ads \
+ ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads ada/sem_aux.adb \
+ ada/sem_cat.ads ada/sem_ch3.ads ada/sem_ch6.ads ada/sem_ch7.ads \
+ ada/sem_ch8.ads ada/sem_disp.ads ada/sem_dist.ads ada/sem_eval.ads \
+ ada/sem_mech.ads ada/sem_prag.ads ada/sem_res.ads ada/sem_scil.ads \
+ ada/sem_type.ads ada/sem_util.ads ada/sem_warn.ads ada/sinfo.ads \
+ ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \
+ ada/stand.ads ada/stringt.ads ada/system.ads ada/s-exctab.ads \
+ ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
+ ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \
+ ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/targparm.ads ada/tbuild.ads \
+ ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads ada/types.ads \
+ ada/uintp.ads ada/uintp.adb ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/validsw.ads
ada/exp_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -1670,10 +1674,10 @@ ada/exp_ch4.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_ch2.ads ada/exp_ch3.ads ada/exp_ch4.ads ada/exp_ch4.adb \
ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_ch9.ads ada/exp_disp.ads \
ada/exp_fixd.ads ada/exp_intr.ads ada/exp_pakd.ads ada/exp_tss.ads \
- ada/exp_util.ads ada/exp_util.adb ada/exp_vfpt.ads ada/fname.ads \
- ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
- ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads ada/inline.ads \
- ada/itypes.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
+ ada/exp_util.ads ada/exp_util.adb ada/exp_vfpt.ads ada/expander.ads \
+ ada/fname.ads ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads \
+ ada/gnat.ads ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads \
+ ada/inline.ads ada/itypes.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
ada/lib-sort.adb ada/lib-util.ads ada/lib-xref.ads ada/namet.ads \
ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
ada/output.ads ada/par_sco.ads ada/put_alfa.ads ada/restrict.ads \
@@ -1704,28 +1708,28 @@ ada/exp_ch5.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch4.ads \
ada/exp_ch5.ads ada/exp_ch5.adb ada/exp_ch6.ads ada/exp_ch7.ads \
ada/exp_dbug.ads ada/exp_disp.ads ada/exp_pakd.ads ada/exp_tss.ads \
- ada/exp_util.ads ada/exp_util.adb ada/fname.ads ada/fname-uf.ads \
- ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
- ada/hostparm.ads ada/inline.ads ada/itypes.ads ada/lib.ads \
- ada/lib-util.ads ada/lib-xref.ads ada/namet.ads ada/nlists.ads \
- ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
- ada/put_alfa.ads ada/restrict.ads ada/restrict.adb ada/rident.ads \
- ada/rtsfind.ads ada/scans.ads ada/sem.ads ada/sem_attr.ads \
- ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch13.ads ada/sem_ch3.ads \
- ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_eval.ads \
- ada/sem_eval.adb ada/sem_prag.ads ada/sem_res.ads ada/sem_type.ads \
- ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/sprint.ads \
- ada/stand.ads ada/stringt.ads ada/stringt.adb ada/style.ads \
- ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \
- ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \
- ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
- ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
- ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \
- ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads ada/validsw.ads
+ ada/exp_util.ads ada/exp_util.adb ada/expander.ads ada/fname.ads \
+ ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
+ ada/g-htable.ads ada/hostparm.ads ada/inline.ads ada/itypes.ads \
+ ada/lib.ads ada/lib-util.ads ada/lib-xref.ads ada/namet.ads \
+ ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
+ ada/output.ads ada/put_alfa.ads ada/restrict.ads ada/restrict.adb \
+ ada/rident.ads ada/rtsfind.ads ada/scans.ads ada/sem.ads \
+ ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch13.ads \
+ ada/sem_ch3.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads \
+ ada/sem_eval.ads ada/sem_eval.adb ada/sem_prag.ads ada/sem_res.ads \
+ ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \
+ ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \
+ ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \
+ ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
+ ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
+ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
+ ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \
+ ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uname.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads
ada/exp_ch6.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -2040,10 +2044,10 @@ ada/exp_pakd.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_aggr.ads ada/exp_ch11.ads ada/exp_ch2.ads ada/exp_ch4.ads \
ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_dbug.ads ada/exp_pakd.ads \
ada/exp_pakd.adb ada/exp_tss.ads ada/exp_util.ads ada/exp_util.adb \
- ada/freeze.ads ada/get_targ.ads ada/gnat.ads ada/g-htable.ads \
- ada/hostparm.ads ada/inline.ads ada/itypes.ads ada/layout.ads \
- ada/lib.ads ada/namet.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads \
- ada/nmake.adb ada/opt.ads ada/output.ads ada/restrict.ads \
+ ada/expander.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
+ ada/g-htable.ads ada/hostparm.ads ada/inline.ads ada/itypes.ads \
+ ada/layout.ads ada/lib.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \
+ ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads ada/restrict.ads \
ada/rident.ads ada/rtsfind.ads ada/sem.ads ada/sem_aux.ads \
ada/sem_ch13.ads ada/sem_ch3.ads ada/sem_ch8.ads ada/sem_eval.ads \
ada/sem_prag.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \
@@ -2135,17 +2139,17 @@ ada/exp_tss.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_util.ads ada/fname.ads ada/fname-uf.ads ada/gnat.ads \
ada/g-hesorg.ads ada/hostparm.ads ada/interfac.ads ada/lib.ads \
ada/lib.adb ada/lib-list.adb ada/lib-sort.adb ada/namet.ads \
- ada/namet.adb ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/opt.ads \
- ada/output.ads ada/restrict.ads ada/restrict.adb ada/rident.ads \
- ada/rtsfind.ads ada/sem_aux.ads ada/sem_util.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
- ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-imenne.ads \
- ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
- ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
- ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
- ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/namet.adb ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
+ ada/restrict.ads ada/restrict.adb ada/rident.ads ada/rtsfind.ads \
+ ada/sem_aux.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \
+ ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \
+ ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \
+ ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/exp_util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -2204,7 +2208,7 @@ ada/expander.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_ch6.ads ada/exp_ch7.ads ada/exp_ch8.ads ada/exp_ch9.ads \
ada/exp_prag.ads ada/exp_tss.ads ada/expander.ads ada/expander.adb \
ada/fname.ads ada/hostparm.ads ada/inline.ads ada/lib.ads \
- ada/lib-load.ads ada/namet.ads ada/nlists.ads ada/nmake.ads ada/opt.ads \
+ ada/lib-load.ads ada/namet.ads ada/nlists.ads ada/opt.ads \
ada/output.ads ada/restrict.ads ada/rident.ads ada/rtsfind.ads \
ada/sem.ads ada/sem.adb ada/sem_attr.ads ada/sem_aux.ads \
ada/sem_ch10.ads ada/sem_ch11.ads ada/sem_ch12.ads ada/sem_ch13.ads \
@@ -2422,16 +2426,15 @@ ada/inline.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/fname.ads ada/fname-uf.ads ada/gnat.ads ada/g-hesorg.ads \
ada/hostparm.ads ada/inline.ads ada/inline.adb ada/lib.ads ada/lib.adb \
ada/lib-list.adb ada/lib-sort.adb ada/namet.ads ada/nlists.ads \
- ada/nlists.adb ada/nmake.ads ada/opt.ads ada/output.ads ada/sem.ads \
- ada/sem_aux.ads ada/sem_ch10.ads ada/sem_ch12.ads ada/sem_ch8.ads \
- ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
- ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
- ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
- ada/s-parame.ads ada/s-secsta.ads ada/s-stalib.ads ada/s-stoele.ads \
- ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-wchcon.ads ada/table.ads ada/table.adb ada/tree_io.ads \
- ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/nlists.adb ada/opt.ads ada/output.ads ada/sem.ads ada/sem_aux.ads \
+ ada/sem_ch10.ads ada/sem_ch12.ads ada/sem_ch8.ads ada/sem_util.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads \
+ ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
+ ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
+ ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/interfac.o : ada/interfac.ads ada/system.ads
@@ -2439,16 +2442,15 @@ ada/itypes.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
ada/exp_tss.ads ada/gnat.ads ada/g-htable.ads ada/hostparm.ads \
- ada/itypes.ads ada/itypes.adb ada/namet.ads ada/nlists.ads \
- ada/nmake.ads ada/opt.ads ada/output.ads ada/rident.ads ada/sem.ads \
- ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
- ada/snames.ads ada/stand.ads ada/system.ads ada/s-exctab.ads \
- ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
- ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/targparm.ads ada/tree_io.ads ada/types.ads \
- ada/uintp.ads ada/uintp.adb ada/unchconv.ads ada/unchdeal.ads \
- ada/urealp.ads
+ ada/itypes.ads ada/itypes.adb ada/namet.ads ada/nlists.ads ada/opt.ads \
+ ada/output.ads ada/rident.ads ada/sem.ads ada/sem_util.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
+ ada/s-stalib.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
+ ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uintp.adb \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads
ada/krunch.o : ada/ada.ads ada/a-unccon.ads ada/hostparm.ads \
ada/krunch.ads ada/krunch.adb ada/system.ads ada/s-exctab.ads \
@@ -2486,22 +2488,23 @@ ada/lib-load.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
ada/einfo.adb ada/elists.ads ada/err_vars.ads ada/errout.ads \
ada/erroutc.ads ada/fname.ads ada/fname-uf.ads ada/gnat.ads \
- ada/g-hesorg.ads ada/hostparm.ads ada/interfac.ads ada/lib.ads \
- ada/lib.adb ada/lib-list.adb ada/lib-load.ads ada/lib-load.adb \
- ada/lib-sort.adb ada/namet.ads ada/nlists.ads ada/nmake.ads \
- ada/nmake.adb ada/opt.ads ada/osint.ads ada/osint-c.ads ada/output.ads \
- ada/par.ads ada/restrict.ads ada/rident.ads ada/scans.ads ada/scn.ads \
- ada/scng.ads ada/scng.adb ada/sem_aux.ads ada/sinfo.ads ada/sinfo.adb \
- ada/sinput.ads ada/sinput-l.ads ada/snames.ads ada/stand.ads \
- ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \
- ada/stylesw.ads ada/system.ads ada/s-crc32.ads ada/s-exctab.ads \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads \
- ada/table.ads ada/table.adb ada/tbuild.ads ada/tbuild.adb \
- ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/g-byorma.ads ada/g-hesorg.ads ada/hostparm.ads ada/interfac.ads \
+ ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-load.ads \
+ ada/lib-load.adb ada/lib-sort.adb ada/namet.ads ada/nlists.ads \
+ ada/nmake.ads ada/nmake.adb ada/opt.ads ada/osint.ads ada/osint-c.ads \
+ ada/output.ads ada/par.ads ada/restrict.ads ada/rident.ads \
+ ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sem_aux.ads \
+ ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
+ ada/sinput-l.ads ada/snames.ads ada/stand.ads ada/stringt.ads \
+ ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \
+ ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
+ ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
+ ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \
+ ada/table.adb ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \
+ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/lib-util.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/hostparm.ads \
@@ -2592,14 +2595,14 @@ ada/live.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/einfo.adb ada/exp_tss.ads ada/fname.ads ada/gnat.ads \
ada/g-hesorg.ads ada/hostparm.ads ada/lib.ads ada/lib.adb \
ada/lib-list.adb ada/lib-sort.adb ada/live.ads ada/live.adb \
- ada/namet.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/opt.ads \
- ada/output.ads ada/sem_aux.ads ada/sem_util.ads ada/sinfo.ads \
- ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
- ada/stringt.ads ada/system.ads ada/s-exctab.ads ada/s-imenne.ads \
- ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
+ ada/namet.ads ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
+ ada/sem_aux.ads ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb \
+ ada/sinput.ads ada/snames.ads ada/stand.ads ada/stringt.ads \
+ ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads ada/s-stalib.ads \
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
+ ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
+ ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/namet-sp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
@@ -3084,8 +3087,8 @@ ada/sem.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads \
ada/exp_tss.ads ada/expander.ads ada/fname.ads ada/gnat.ads \
ada/g-hesorg.ads ada/hostparm.ads ada/inline.ads ada/lib.ads \
ada/lib.adb ada/lib-list.adb ada/lib-load.ads ada/lib-sort.adb \
- ada/namet.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/opt.ads \
- ada/output.ads ada/restrict.ads ada/rident.ads ada/sem.ads ada/sem.adb \
+ ada/namet.ads ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads \
+ ada/restrict.ads ada/rident.ads ada/sem.ads ada/sem.adb \
ada/sem_attr.ads ada/sem_aux.ads ada/sem_ch10.ads ada/sem_ch11.ads \
ada/sem_ch12.ads ada/sem_ch13.ads ada/sem_ch2.ads ada/sem_ch2.adb \
ada/sem_ch3.ads ada/sem_ch4.ads ada/sem_ch5.ads ada/sem_ch6.ads \
@@ -3116,21 +3119,21 @@ ada/sem_aggr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/put_alfa.ads ada/restrict.ads ada/rident.ads ada/rtsfind.ads \
ada/scans.ads ada/sem.ads ada/sem_aggr.ads ada/sem_aggr.adb \
ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch13.ads \
- ada/sem_ch3.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_disp.ads \
- ada/sem_eval.ads ada/sem_eval.adb ada/sem_prag.ads ada/sem_res.ads \
- ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb ada/sem_warn.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads \
- ada/sprint.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \
- ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \
- ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads \
- ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
- ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
- ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
- ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/targparm.ads ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads \
- ada/ttypes.ads ada/types.ads ada/uintp.ads ada/uintp.adb ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/validsw.ads \
- ada/widechar.ads
+ ada/sem_ch3.ads ada/sem_ch6.ads ada/sem_ch8.ads ada/sem_dim.ads \
+ ada/sem_disp.ads ada/sem_eval.ads ada/sem_eval.adb ada/sem_prag.ads \
+ ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads ada/sem_util.adb \
+ ada/sem_warn.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/sprint.ads ada/stand.ads ada/stringt.ads \
+ ada/stringt.adb ada/style.ads ada/styleg.ads ada/styleg.adb \
+ ada/stylesw.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
+ ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
+ ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
+ ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
+ ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
+ ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \
+ ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \
+ ada/uintp.adb ada/uname.ads ada/unchconv.ads ada/unchdeal.ads \
+ ada/urealp.ads ada/validsw.ads ada/widechar.ads
ada/sem_attr.o : ada/ada.ads ada/a-charac.ads ada/a-chlat1.ads \
ada/a-except.ads ada/a-unccon.ads ada/a-uncdea.ads ada/alloc.ads \
@@ -3611,26 +3614,32 @@ ada/sem_ch9.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/sem_dim.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
- ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/einfo.adb ada/elists.ads ada/err_vars.ads ada/errout.ads \
- ada/erroutc.ads ada/exp_dist.ads ada/exp_tss.ads ada/fname.ads \
- ada/fname-uf.ads ada/gnat.ads ada/g-hesorg.ads ada/g-htable.ads \
- ada/hostparm.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
- ada/lib-load.ads ada/lib-sort.adb ada/namet.ads ada/nlists.ads \
- ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads ada/output.ads \
- ada/restrict.ads ada/rident.ads ada/rtsfind.ads ada/rtsfind.adb \
- ada/sem.ads ada/sem_aux.ads ada/sem_ch7.ads ada/sem_dim.ads \
- ada/sem_dim.adb ada/sem_dist.ads ada/sem_eval.ads ada/sem_res.ads \
- ada/sem_util.ads ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
- ada/snames.ads ada/stand.ads ada/stringt.ads ada/stringt.adb \
- ada/system.ads ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-strhas.ads \
- ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
- ada/table.ads ada/table.adb ada/tbuild.ads ada/tbuild.adb \
- ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
- ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/atree.adb ada/casing.ads ada/checks.ads ada/csets.ads ada/debug.ads \
+ ada/einfo.ads ada/einfo.adb ada/elists.ads ada/err_vars.ads \
+ ada/errout.ads ada/erroutc.ads ada/exp_ch11.ads ada/exp_disp.ads \
+ ada/exp_dist.ads ada/exp_tss.ads ada/exp_util.ads ada/fname.ads \
+ ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads ada/gnat.ads \
+ ada/g-byorma.ads ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads \
+ ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-load.ads \
+ ada/lib-sort.adb ada/lib-util.ads ada/lib-xref.ads ada/namet.ads \
+ ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
+ ada/output.ads ada/put_alfa.ads ada/restrict.ads ada/rident.ads \
+ ada/rtsfind.ads ada/rtsfind.adb ada/scans.ads ada/sem.ads \
+ ada/sem_attr.ads ada/sem_aux.ads ada/sem_ch7.ads ada/sem_ch8.ads \
+ ada/sem_dim.ads ada/sem_dim.adb ada/sem_disp.ads ada/sem_dist.ads \
+ ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \
+ ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/sinput.adb ada/snames.ads ada/stand.ads ada/stringt.ads \
+ ada/stringt.adb ada/style.ads ada/styleg.ads ada/styleg.adb \
+ ada/stylesw.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
+ ada/s-htable.adb ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads \
+ ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads \
+ ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-strhas.ads ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
+ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \
+ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/sem_disp.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -3685,27 +3694,26 @@ ada/sem_elab.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_ch11.ads \
ada/exp_disp.ads ada/exp_tss.ads ada/exp_util.ads ada/expander.ads \
ada/fname.ads ada/fname-uf.ads ada/freeze.ads ada/get_targ.ads \
- ada/gnat.ads ada/g-byorma.ads ada/g-hesorg.ads ada/g-htable.ads \
- ada/hostparm.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
- ada/lib-load.ads ada/lib-sort.adb ada/lib-util.ads ada/lib-xref.ads \
- ada/namet.ads ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb \
- ada/opt.ads ada/output.ads ada/put_alfa.ads ada/restrict.ads \
- ada/restrict.adb ada/rident.ads ada/rtsfind.ads ada/scans.ads \
- ada/sem.ads ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads \
- ada/sem_ch7.ads ada/sem_ch8.ads ada/sem_disp.ads ada/sem_elab.ads \
- ada/sem_elab.adb ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads \
- ada/sem_util.ads ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb \
- ada/sinput.ads ada/sinput.adb ada/snames.ads ada/stand.ads \
- ada/stringt.ads ada/style.ads ada/styleg.ads ada/styleg.adb \
- ada/stylesw.ads ada/system.ads ada/s-exctab.ads ada/s-htable.ads \
- ada/s-imenne.ads ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads \
- ada/s-rident.ads ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/targparm.ads ada/tbuild.ads ada/tbuild.adb \
- ada/tree_io.ads ada/ttypes.ads ada/types.ads ada/uintp.ads \
- ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \
- ada/widechar.ads
+ ada/gnat.ads ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads \
+ ada/lib.ads ada/lib.adb ada/lib-list.adb ada/lib-load.ads \
+ ada/lib-sort.adb ada/lib-util.ads ada/lib-xref.ads ada/namet.ads \
+ ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/nmake.adb ada/opt.ads \
+ ada/output.ads ada/put_alfa.ads ada/restrict.ads ada/restrict.adb \
+ ada/rident.ads ada/rtsfind.ads ada/scans.ads ada/sem.ads \
+ ada/sem_attr.ads ada/sem_aux.ads ada/sem_cat.ads ada/sem_ch7.ads \
+ ada/sem_ch8.ads ada/sem_disp.ads ada/sem_elab.ads ada/sem_elab.adb \
+ ada/sem_eval.ads ada/sem_res.ads ada/sem_type.ads ada/sem_util.ads \
+ ada/sem_util.adb ada/sinfo.ads ada/sinfo.adb ada/sinput.ads \
+ ada/snames.ads ada/stand.ads ada/stringt.ads ada/style.ads \
+ ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \
+ ada/s-exctab.ads ada/s-htable.ads ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \
+ ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
+ ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
+ ada/s-wchcon.ads ada/table.ads ada/table.adb ada/targparm.ads \
+ ada/tbuild.ads ada/tbuild.adb ada/tree_io.ads ada/ttypes.ads \
+ ada/types.ads ada/uintp.ads ada/uname.ads ada/unchconv.ads \
+ ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/sem_elim.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -3714,18 +3722,17 @@ ada/sem_elim.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/exp_tss.ads ada/fname.ads ada/gnat.ads ada/g-byorma.ads \
ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads ada/lib.ads \
ada/lib.adb ada/lib-list.adb ada/lib-sort.adb ada/namet.ads \
- ada/nlists.ads ada/nlists.adb ada/nmake.ads ada/opt.ads ada/output.ads \
- ada/scans.ads ada/sem.ads ada/sem_aux.ads ada/sem_aux.adb \
- ada/sem_elim.ads ada/sem_elim.adb ada/sem_prag.ads ada/sem_util.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
- ada/snames.ads ada/stand.ads ada/stringt.ads ada/system.ads \
- ada/s-exctab.ads ada/s-htable.ads ada/s-htable.adb ada/s-imenne.ads \
- ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-strhas.ads \
- ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
- ada/table.ads ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
- ada/uname.ads ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads \
- ada/widechar.ads
+ ada/nlists.ads ada/nlists.adb ada/opt.ads ada/output.ads ada/scans.ads \
+ ada/sem.ads ada/sem_aux.ads ada/sem_aux.adb ada/sem_elim.ads \
+ ada/sem_elim.adb ada/sem_prag.ads ada/sem_util.ads ada/sinfo.ads \
+ ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/snames.ads \
+ ada/stand.ads ada/stringt.ads ada/system.ads ada/s-exctab.ads \
+ ada/s-htable.ads ada/s-htable.adb ada/s-imenne.ads ada/s-memory.ads \
+ ada/s-os_lib.ads ada/s-parame.ads ada/s-secsta.ads ada/s-stalib.ads \
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-strhas.ads ada/s-string.ads \
+ ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
+ ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads ada/uname.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/sem_eval.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -3764,7 +3771,7 @@ ada/sem_intr.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/einfo.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
ada/exp_tss.ads ada/fname.ads ada/gnat.ads ada/g-hesorg.ads \
ada/hostparm.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
- ada/lib-sort.adb ada/namet.ads ada/nlists.ads ada/nmake.ads ada/opt.ads \
+ ada/lib-sort.adb ada/namet.ads ada/nlists.ads ada/opt.ads \
ada/output.ads ada/rident.ads ada/sem_aux.ads ada/sem_aux.adb \
ada/sem_eval.ads ada/sem_intr.ads ada/sem_intr.adb ada/sem_util.ads \
ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
@@ -3781,9 +3788,9 @@ ada/sem_mech.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/atree.adb ada/casing.ads ada/debug.ads ada/einfo.ads ada/einfo.adb \
ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/exp_tss.ads \
ada/hostparm.ads ada/namet.ads ada/nlists.ads ada/nlists.adb \
- ada/nmake.ads ada/opt.ads ada/output.ads ada/rident.ads ada/sem.ads \
- ada/sem_aux.ads ada/sem_mech.ads ada/sem_mech.adb ada/sem_util.ads \
- ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
+ ada/opt.ads ada/output.ads ada/rident.ads ada/sem.ads ada/sem_aux.ads \
+ ada/sem_mech.ads ada/sem_mech.adb ada/sem_util.ads ada/sinfo.ads \
+ ada/sinfo.adb ada/sinput.ads ada/snames.ads ada/stand.ads \
ada/system.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-stalib.ads \
ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
@@ -4054,22 +4061,23 @@ ada/sinput-d.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/sinput-l.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
ada/atree.adb ada/casing.ads ada/csets.ads ada/debug.ads ada/einfo.ads \
- ada/err_vars.ads ada/errout.ads ada/erroutc.ads ada/fname.ads \
- ada/gnat.ads ada/g-byorma.ads ada/g-dyntab.ads ada/g-dyntab.adb \
- ada/g-hesorg.ads ada/hostparm.ads ada/interfac.ads ada/lib.ads \
- ada/namet.ads ada/nlists.ads ada/opt.ads ada/osint.ads ada/output.ads \
- ada/prep.ads ada/prepcomp.ads ada/restrict.ads ada/rident.ads \
- ada/scans.ads ada/scn.ads ada/scng.ads ada/scng.adb ada/sinfo.ads \
+ ada/einfo.adb ada/err_vars.ads ada/errout.ads ada/erroutc.ads \
+ ada/exp_tss.ads ada/fname.ads ada/gnat.ads ada/g-byorma.ads \
+ ada/g-dyntab.ads ada/g-dyntab.adb ada/g-hesorg.ads ada/hostparm.ads \
+ ada/interfac.ads ada/lib.ads ada/namet.ads ada/nlists.ads ada/opt.ads \
+ ada/osint.ads ada/output.ads ada/prep.ads ada/prepcomp.ads \
+ ada/restrict.ads ada/rident.ads ada/scans.ads ada/scn.ads ada/scng.ads \
+ ada/scng.adb ada/sem_aux.ads ada/sem_util.ads ada/sinfo.ads \
ada/sinfo.adb ada/sinput.ads ada/sinput.adb ada/sinput-l.ads \
- ada/sinput-l.adb ada/snames.ads ada/stringt.ads ada/style.ads \
- ada/styleg.ads ada/styleg.adb ada/stylesw.ads ada/system.ads \
- ada/s-crc32.ads ada/s-exctab.ads ada/s-imenne.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads ada/s-secsta.ads \
- ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads \
- ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads \
- ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads ada/table.adb \
- ada/tree_io.ads ada/types.ads ada/uintp.ads ada/unchconv.ads \
- ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
+ ada/sinput-l.adb ada/snames.ads ada/stand.ads ada/stringt.ads \
+ ada/style.ads ada/styleg.ads ada/styleg.adb ada/stylesw.ads \
+ ada/system.ads ada/s-crc32.ads ada/s-exctab.ads ada/s-imenne.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-rident.ads \
+ ada/s-secsta.ads ada/s-soflin.ads ada/s-stache.ads ada/s-stalib.ads \
+ ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads ada/s-traent.ads \
+ ada/s-unstyp.ads ada/s-utf_32.ads ada/s-wchcon.ads ada/table.ads \
+ ada/table.adb ada/tree_io.ads ada/types.ads ada/uintp.ads \
+ ada/unchconv.ads ada/unchdeal.ads ada/urealp.ads ada/widechar.ads
ada/sinput.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/aspects.ads ada/atree.ads \
@@ -4101,7 +4109,7 @@ ada/sprint.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/g-byorma.ads ada/g-hesorg.ads ada/g-htable.ads ada/hostparm.ads \
ada/interfac.ads ada/lib.ads ada/lib.adb ada/lib-list.adb \
ada/lib-sort.adb ada/namet.ads ada/namet.adb ada/nlists.ads \
- ada/nlists.adb ada/nmake.ads ada/opt.ads ada/output.ads ada/output.adb \
+ ada/nlists.adb ada/opt.ads ada/output.ads ada/output.adb \
ada/rtsfind.ads ada/scans.ads ada/sem_eval.ads ada/sem_util.ads \
ada/sinfo.ads ada/sinfo.adb ada/sinput.ads ada/sinput.adb \
ada/sinput-d.ads ada/snames.ads ada/sprint.ads ada/sprint.adb \
@@ -4171,15 +4179,16 @@ ada/switch-b.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/types.ads ada/unchconv.ads ada/unchdeal.ads
ada/switch-c.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
- ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/gnatvsn.ads \
- ada/hostparm.ads ada/lib.ads ada/namet.ads ada/opt.ads ada/osint.ads \
- ada/output.ads ada/stylesw.ads ada/switch.ads ada/switch-c.ads \
- ada/switch-c.adb ada/system.ads ada/s-exctab.ads ada/s-memory.ads \
- ada/s-os_lib.ads ada/s-parame.ads ada/s-soflin.ads ada/s-stache.ads \
- ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb ada/s-string.ads \
- ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads ada/table.ads \
- ada/table.adb ada/tree_io.ads ada/types.ads ada/unchconv.ads \
- ada/unchdeal.ads ada/validsw.ads ada/warnsw.ads
+ ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/get_targ.ads \
+ ada/gnatvsn.ads ada/hostparm.ads ada/lib.ads ada/namet.ads ada/opt.ads \
+ ada/osint.ads ada/output.ads ada/stylesw.ads ada/switch.ads \
+ ada/switch-c.ads ada/switch-c.adb ada/system.ads ada/s-exctab.ads \
+ ada/s-memory.ads ada/s-os_lib.ads ada/s-parame.ads ada/s-soflin.ads \
+ ada/s-stache.ads ada/s-stalib.ads ada/s-stoele.ads ada/s-stoele.adb \
+ ada/s-string.ads ada/s-traent.ads ada/s-unstyp.ads ada/s-wchcon.ads \
+ ada/table.ads ada/table.adb ada/tree_io.ads ada/ttypes.ads \
+ ada/types.ads ada/unchconv.ads ada/unchdeal.ads ada/validsw.ads \
+ ada/warnsw.ads
ada/switch.o : ada/ada.ads ada/a-except.ads ada/a-unccon.ads \
ada/a-uncdea.ads ada/alloc.ads ada/debug.ads ada/gnatvsn.ads \
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 9e14d8af1..3935bb33e 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -6165,6 +6165,7 @@ elaborate_expression_1 (tree gnu_expr, Entity_Id gnat_entity, tree gnu_name,
use_variable = expr_variable_p
&& (expr_global_p
|| (!optimize
+ && definition
&& Is_Itype (gnat_entity)
&& Nkind (Associated_Node_For_Itype (gnat_entity))
== N_Loop_Parameter_Specification));
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index 6edead04b..d4a81762f 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -228,7 +228,8 @@ extern const char *ref_filename;
struct File_Info_Type
{
File_Name_Type File_Name;
- Nat Num_Source_Lines;
+ Instance_Id Instance;
+ Nat Num_Source_Lines;
};
#ifdef __cplusplus
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 4d8dac90a..aac483caf 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -293,6 +293,9 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
tree int64_type = gnat_type_for_size (64, 0);
struct elab_info *info;
int i;
+#ifdef ORDINARY_MAP_INSTANCE
+ struct line_map *map;
+#endif
max_gnat_nodes = max_gnat_node;
@@ -326,6 +329,11 @@ gigi (Node_Id gnat_root, int max_gnat_node, int number_name ATTRIBUTE_UNUSED,
/* We create the line map for a source file at once, with a fixed number
of columns chosen to avoid jumping over the next power of 2. */
linemap_add (line_table, LC_ENTER, 0, filename, 1);
+#ifdef ORDINARY_MAP_INSTANCE
+ map = LINEMAPS_ORDINARY_MAP_AT (line_table, i);
+ if (flag_debug_instances)
+ ORDINARY_MAP_INSTANCE (map) = file_info_ptr[i].Instance;
+#endif
linemap_line_start (line_table, file_info_ptr[i].Num_Source_Lines, 252);
linemap_position_for_column (line_table, 252 - 1);
linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
@@ -3150,6 +3158,7 @@ build_return_expr (tree ret_obj, tree ret_val)
if (optimize
&& AGGREGATE_TYPE_P (operation_type)
&& !TYPE_IS_FAT_POINTER_P (operation_type)
+ && TYPE_MODE (operation_type) == BLKmode
&& aggregate_value_p (operation_type, current_function_decl))
{
/* Recognize the temporary created for a return value with variable
@@ -5969,7 +5978,7 @@ gnat_to_gnu (Node_Id gnat_node)
}
break;
- case N_Conditional_Expression:
+ case N_If_Expression:
{
tree gnu_cond = gnat_to_gnu (First (Expressions (gnat_node)));
tree gnu_true = gnat_to_gnu (Next (First (Expressions (gnat_node))));
@@ -6232,7 +6241,7 @@ gnat_to_gnu (Node_Id gnat_node)
: VEC_last (loop_info, gnu_loop_stack)->label));
break;
- case N_Return_Statement:
+ case N_Simple_Return_Statement:
{
tree gnu_ret_obj, gnu_ret_val;
diff --git a/gcc/ada/get_scos.adb b/gcc/ada/get_scos.adb
index ce662ce7e..4fb001029 100644
--- a/gcc/ada/get_scos.adb
+++ b/gcc/ada/get_scos.adb
@@ -225,7 +225,7 @@ begin
case C is
- -- Header entry
+ -- Header or instance table entry
when ' ' =>
@@ -236,26 +236,71 @@ begin
SCO_Table.Last;
end if;
- -- Scan out dependency number and file name
-
Skip_Spaces;
- Dnum := Get_Int;
- Skip_Spaces;
+ case Nextc is
- N := 0;
- while Nextc > ' ' loop
- N := N + 1;
- Buf (N) := Getc;
- end loop;
+ -- Instance table entry
+
+ when 'i' =>
+ declare
+ Inum : SCO_Instance_Index;
+ begin
+ Skipc;
+ Skip_Spaces;
+
+ Inum := SCO_Instance_Index (Get_Int);
+ SCO_Instance_Table.Increment_Last;
+ pragma Assert (SCO_Instance_Table.Last = Inum);
+
+ Skip_Spaces;
+ declare
+ SIE : SCO_Instance_Table_Entry
+ renames SCO_Instance_Table.Table (Inum);
+ begin
+ SIE.Inst_Dep_Num := Get_Int;
+ C := Getc;
+ pragma Assert (C = '|');
+ Get_Source_Location (SIE.Inst_Loc);
+
+ if not At_EOL then
+ Skip_Spaces;
+ SIE.Enclosing_Instance :=
+ SCO_Instance_Index (Get_Int);
+ pragma Assert (SIE.Enclosing_Instance in
+ SCO_Instance_Table.First
+ .. SCO_Instance_Table.Last);
+ end if;
+ end;
+ end;
- -- Make new unit table entry (will fill in To later)
+ -- Unit header
+
+ when '0' .. '9' =>
+ -- Scan out dependency number and file name
+
+ Dnum := Get_Int;
+
+ Skip_Spaces;
+
+ N := 0;
+ while Nextc > ' ' loop
+ N := N + 1;
+ Buf (N) := Getc;
+ end loop;
+
+ -- Make new unit table entry (will fill in To later)
+
+ SCO_Unit_Table.Append (
+ (File_Name => new String'(Buf (1 .. N)),
+ Dep_Num => Dnum,
+ From => SCO_Table.Last + 1,
+ To => 0));
+
+ when others =>
+ raise Program_Error;
- SCO_Unit_Table.Append (
- (File_Name => new String'(Buf (1 .. N)),
- Dep_Num => Dnum,
- From => SCO_Table.Last + 1,
- To => 0));
+ end case;
-- Statement entry
diff --git a/gcc/ada/gnat1drv.adb b/gcc/ada/gnat1drv.adb
index b2f371f39..a4d01c9f8 100644
--- a/gcc/ada/gnat1drv.adb
+++ b/gcc/ada/gnat1drv.adb
@@ -197,12 +197,10 @@ procedure Gnat1drv is
Alignment_Check => True,
Division_Check => True,
Elaboration_Check => True,
- Overflow_Check => True,
others => False),
- Overflow_Checks_General => Suppress,
- Overflow_Checks_Assertions => Suppress);
+ Overflow_Checks_General => Suppressed,
+ Overflow_Checks_Assertions => Suppressed);
- Enable_Overflow_Checks := False;
Dynamic_Elaboration_Checks := False;
-- Kill debug of generated code, since it messes up sloc values
@@ -330,23 +328,42 @@ procedure Gnat1drv is
Exception_Mechanism := Back_End_Exceptions;
end if;
- -- Set proper status for overflow checks. We turn on overflow checks if
- -- -gnatp was not specified, and either -gnato is set or the back-end
- -- takes care of overflow checks. Otherwise we suppress overflow checks
- -- by default (since front end checks are expensive).
-
- if not Opt.Suppress_Checks
- and then (Opt.Enable_Overflow_Checks
- or else
- (Targparm.Backend_Divide_Checks_On_Target
- and
- Targparm.Backend_Overflow_Checks_On_Target))
+ -- Set proper status for overflow checks
+
+ -- If already set (by - gnato or -gnatp) then we have nothing to do
+
+ if Opt.Suppress_Options.Overflow_Checks_General /= Not_Set then
+ null;
+
+ -- Otherwise set appropriate default mode. Note: at present we set
+ -- SUPPRESSED in all three of the following cases. They are separated
+ -- because in the future we may make different choices.
+
+ -- By default suppress overflow checks in -gnatg mode
+
+ elsif GNAT_Mode then
+ Suppress_Options.Overflow_Checks_General := Suppressed;
+ Suppress_Options.Overflow_Checks_Assertions := Suppressed;
+
+ -- If we have backend divide and overflow checks, then by default
+ -- overflow checks are suppressed. Historically this code used to
+ -- activate overflow checks, although no target currently has these
+ -- flags set, so this was dead code anyway.
+
+ elsif Targparm.Backend_Divide_Checks_On_Target
+ and
+ Targparm.Backend_Overflow_Checks_On_Target
then
- Suppress_Options.Suppress (Overflow_Check) := False;
+ Suppress_Options.Overflow_Checks_General := Suppressed;
+ Suppress_Options.Overflow_Checks_Assertions := Suppressed;
+
+ -- Otherwise for now, default is checks are suppressed. This is subject
+ -- to change in the future, but for now this is the compatible behavior
+ -- with previous versions of GNAT.
+
else
- Suppress_Options.Suppress (Overflow_Check) := True;
- Suppress_Options.Overflow_Checks_General := Check_All;
- Suppress_Options.Overflow_Checks_Assertions := Check_All;
+ Suppress_Options.Overflow_Checks_General := Suppressed;
+ Suppress_Options.Overflow_Checks_Assertions := Suppressed;
end if;
-- Set default for atomic synchronization. As this synchronization
@@ -377,7 +394,7 @@ procedure Gnat1drv is
-- Set switch indicating if back end can handle limited types, and
-- guarantee that no incorrect copies are made (e.g. in the context
- -- of a conditional expression).
+ -- of an if or case expression).
-- Debug flag -gnatd.L decisively sets usage on
@@ -437,8 +454,7 @@ procedure Gnat1drv is
-- Turn off alignment checks.
-- Turn off validity checking.
- Suppress_Options := Suppress_All;
- Enable_Overflow_Checks := False;
+ Suppress_Options := Suppress_All;
Dynamic_Elaboration_Checks := False;
Reset_Validity_Check_Options;
@@ -517,6 +533,12 @@ procedure Gnat1drv is
Inline_Level := 2;
end if;
end if;
+
+ -- Finally capture adjusted value of Suppress_Options as the initial
+ -- value for Scope_Suppress, which will be modified as we move from
+ -- scope to scope (by Suppress/Unsuppress/Overflow_Checks pragmas).
+
+ Sem.Scope_Suppress := Opt.Suppress_Options;
end Adjust_Global_Switches;
--------------------
diff --git a/gcc/ada/gnat_rm.texi b/gcc/ada/gnat_rm.texi
index eb0b4219c..9e875bc9c 100644
--- a/gcc/ada/gnat_rm.texi
+++ b/gcc/ada/gnat_rm.texi
@@ -179,6 +179,7 @@ Implementation Defined Pragmas
* Pragma Obsolescent::
* Pragma Optimize_Alignment::
* Pragma Ordered::
+* Pragma Overflow_Checks::
* Pragma Passive::
* Pragma Persistent_BSS::
* Pragma Polling::
@@ -916,6 +917,7 @@ consideration, the use of these pragmas should be minimized.
* Pragma Obsolescent::
* Pragma Optimize_Alignment::
* Pragma Ordered::
+* Pragma Overflow_Checks::
* Pragma Passive::
* Pragma Persistent_BSS::
* Pragma Polling::
@@ -1919,7 +1921,7 @@ where @var{T} is a limited record type imported from C++ with pragma
The first two forms import the default constructor, used when an object
of type @var{T} is created on the Ada side with no explicit constructor.
The latter two forms cover all the non-default constructors of the type.
-See the GNAT users guide for details.
+See the @value{EDITION} User's Guide for details.
If no constructors are imported, it is impossible to create any objects
on the Ada side and the type is implicitly declared abstract.
@@ -3099,8 +3101,8 @@ initialize with invalid values (similar to Normalize_Scalars, though for
Initialize_Scalars it is not always possible to determine the invalid
values in complex cases like signed component fields with non-standard
sizes). You can also initialize with high or
-low values, or with a specified bit pattern. See the users guide for binder
-options for specifying these cases.
+low values, or with a specified bit pattern. See the @value{EDITION}
+User's Guide for binder options for specifying these cases.
This means that you can compile a program, and then without having to
recompile the program, you can run it with different values being used
@@ -3111,13 +3113,14 @@ uninitialized value.
It is even possible to change the value at execution time eliminating even
the need to rebind with a different switch using an environment variable.
-See the GNAT users guide for details.
+See the @value{EDITION} User's Guide for details.
Note that pragma @code{Initialize_Scalars} is particularly useful in
conjunction with the enhanced validity checking that is now provided
in GNAT, which checks for invalid values under more conditions.
Using this feature (see description of the @option{-gnatV} flag in the
-users guide) in conjunction with pragma @code{Initialize_Scalars}
+@value{EDITION} User's Guide) in conjunction with
+pragma @code{Initialize_Scalars}
provides a powerful new tool to assist in the detection of problems
caused by uninitialized variables.
@@ -3125,8 +3128,8 @@ Note: the use of @code{Initialize_Scalars} has a fairly extensive
effect on the generated code. This may cause your code to be
substantially larger. It may also cause an increase in the amount
of stack required, so it is probably a good idea to turn on stack
-checking (see description of stack checking in the GNAT users guide)
-when using this pragma.
+checking (see description of stack checking in the @value{EDITION}
+User's Guide) when using this pragma.
@node Pragma Inline_Always
@unnumberedsec Pragma Inline_Always
@@ -4127,6 +4130,61 @@ as unordered, and will generate warnings for inappropriate uses.
For additional information please refer to the description of the
@option{-gnatw.u} switch in the @value{EDITION} User's Guide.
+@node Pragma Overflow_Checks
+@unnumberedsec Pragma Overflow_Checks
+@findex Overflow checks
+@findex pragma @code{Overflow_Checks}
+@noindent
+Syntax:
+
+@smallexample @c ada
+pragma Overflow_Checks
+ ( [General =>] MODE
+ [,[Assertions =>] MODE]);
+
+MODE ::= SUPPRESSED | CHECKED | MINIMIZED | ELIMINATED
+@end smallexample
+
+@noindent
+This pragma sets the current overflow mode to the given mode. For details
+of the meaning of these modes, please refer to the
+``Overflow Check Handling in GNAT'' appendix in the
+@value{EDITION} User's Guide. If only the @code{General} parameter is present,
+the given mode applies to all expressions. If both parameters are present,
+the @code{General} mode applies to expressions outside assertions, and
+the @code{Eliminated} mode applies to expressions within assertions.
+
+The case of the @code{MODE} parameter is ignored,
+so @code{MINIMIZED}, @code{Minimized} and
+@code{minimized} all have the same effect.
+
+The @code{Overflow_Checks} pragma has the same scoping and placement
+rules as pragma @code{Suppress}, so it can occur either as a
+configuration pragma, specifying a default for the whole
+program, or in a declarative scope, where it applies to the
+remaining declarations and statements in that scope.
+
+The pragma @code{Suppress (Overflow_Check)} sets mode
+
+@smallexample @c ada
+ General => Suppressed
+@end smallexample
+
+@noindent
+suppressing all overflow checking within and outside
+assertions.
+
+The pragam @code{Unsuppress (Overflow_Check)} sets mode
+
+@smallexample @c ada
+ General => Checked
+@end smallexample
+
+@noindent
+which causes overflow checking of all intermediate overflows.
+This applies both inside and outside assertions.
+
+
@node Pragma Passive
@unnumberedsec Pragma Passive
@findex Passive
@@ -5738,8 +5796,8 @@ activated. The validity checks are first set to include only the default
reference manual settings, and then a string of letters in the string
specifies the exact set of options required. The form of this string
is exactly as described for the @option{-gnatVx} compiler switch (see the
-GNAT users guide for details). For example the following two methods
-can be used to enable validity checking for mode @code{in} and
+@value{EDITION} User's Guide for details). For example the following two
+methods can be used to enable validity checking for mode @code{in} and
@code{in out} subprogram parameters:
@itemize @bullet
diff --git a/gcc/ada/gnat_ugn.texi b/gcc/ada/gnat_ugn.texi
index e440ed517..b94f035ba 100644
--- a/gcc/ada/gnat_ugn.texi
+++ b/gcc/ada/gnat_ugn.texi
@@ -208,6 +208,7 @@ AdaCore@*
* Platform-Specific Information for the Run-Time Libraries::
* Example of Binder Output File::
* Elaboration Order Handling in GNAT::
+* Overflow Check Handling in GNAT::
* Conditional Compilation::
* Inline Assembler::
* Compatibility and Porting Guide::
@@ -611,6 +612,13 @@ Elaboration Order Handling in GNAT
* Summary of Procedures for Elaboration Control::
* Other Elaboration Order Considerations::
+Overflow Check Handling in GNAT
+* Background::
+* Overflow Checking Modes in GNAT::
+* Specifying the Desired Mode::
+* Default Settings::
+* Implementation Notes::
+
Conditional Compilation
* Use of Boolean Constants::
* Debugging - A Special Case::
@@ -891,6 +899,10 @@ output file for a sample program.
you deal with elaboration order issues.
@item
+@ref{Overflow Check Handling in GNAT}, describes how GNAT helps
+you deal with arithmetic overflow issues.
+
+@item
@ref{Conditional Compilation}, describes how to model conditional compilation,
both with Ada in general and with GNAT facilities in particular.
@@ -4325,12 +4337,38 @@ of GNAT other than the JGNAT, .NET or GNAAMP versions), then the use of
Historically front end inlining was more extensive than the gcc back end
inlining, but that is no longer the case.
-@item -gnato
-@cindex @option{-gnato} (@command{gcc})
-Enable numeric overflow checking (which is not normally enabled by
-default). Note that division by zero is a separate check that is not
+@item -gnato??
+@cindex @option{-gnato??} (@command{gcc})
+Set default overflow checking mode. Here `@code{??}' is two digits, a
+single digit, or nothing. Each digit is one of the digits `@code{0}'
+through `@code{3}':
+
+@itemize @bullet
+@item @code{0}:
+suppress overflow checks (@code{SUPPRESSED})
+@item @code{1}:
+all intermediate overflows checked (@code{CHECKED})
+@item @code{2}:
+minimize intermediate overflows (@code{MINIMIZED})
+@item @code{3}:
+eliminate intermediate overflows (@code{ELIMINATED})
+@end itemize
+
+If only one digit appears then it applies to all
+cases; if two digits are given, then the first applies outside
+assertions, and the second within assertions.
+
+If no digits follow the @option{-gnato}, then it is equivalent to
+@option{-gnato11},
+causing all intermediate overflows to be checked.
+
+The default if no option @option{-gnato} is given is that overflows are not
+checked, which is equivalent to @option{-gnato00}.
+Note that division by zero is a separate check that is not
controlled by this switch (division by zero checking is on by default).
+See also @ref{Specifying the Desired Mode}.
+
@item -gnatp
@cindex @option{-gnatp} (@command{gcc})
Suppress all checks. See @ref{Run-Time Checks} for details. This switch
@@ -6713,6 +6751,10 @@ A unary plus or minus may not be followed by a space.
A vertical bar must be surrounded by spaces.
@end itemize
+@item
+Exactly one blank (and no other white space) must appear between
+a @code{not} token and a following @code{in} token.
+
@item ^u^UNNECESSARY_BLANK_LINES^
@emph{Check unnecessary blank lines.}
Unnecessary blank lines are not allowed. A blank line is considered
@@ -6860,78 +6902,103 @@ The @option{-gnatp} switch has no effect if a subsequent
@findex Suppress
This switch cancels the effect of a previous @option{gnatp} switch.
-@item -gnato
-@cindex @option{-gnato} (@command{gcc})
+@item -gnato??
+@cindex @option{-gnato??} (@command{gcc})
@cindex Overflow checks
@cindex Check, overflow
-Enables overflow checking for integer operations.
-This causes GNAT to generate slower and larger executable
-programs by adding code to check for overflow (resulting in raising
-@code{Constraint_Error} as required by standard Ada
-semantics). These overflow checks correspond to situations in which
-the true value of the result of an operation may be outside the base
-range of the result type. The following example shows the distinction:
+In @code{CHECKED} and @code{MINIMIZED} modes (@option{-gnato1} and
+@option{-gnato2}), it enables overflow checking for integer operations.
+In @code{ELIMINATED} mode (@option{-gnato3}), it enables arbitrary
+precision arithmetic for integer operations. In all these modes, this
+causes @value{EDITION} to generate slower and larger executable programs
+by adding code to either check for overflow (resulting in raising
+@code{Constraint_Error} as required by standard Ada semantics) or avoid
+overflows. In mode @code{CHECKED}, overflow checks correspond to
+situations in which the true value of the result of an operation may be
+outside the base range of the result type. In mode @code{MINIMIZED},
+overflow checks correspond to situations in which the true value of the
+result of an operation may be outside the largest available machine
+integer type (@code{Long_Long_Integer}). The following example shows the
+distinction:
@smallexample @c ada
-X1 : Integer := "Integer'Last";
-X2 : Integer range 1 .. 5 := "5";
-X3 : Integer := "Integer'Last";
-X4 : Integer range 1 .. 5 := "5";
-F : Float := "2.0E+20";
-@dots{}
-X1 := X1 + 1;
-X2 := X2 + 1;
-X3 := Integer (F);
-X4 := Integer (F);
-@end smallexample
-
-@noindent
-Note that if explicit values are assigned at compile time, the
-compiler may be able to detect overflow at compile time, in which case
-no actual run-time checking code is required, and Constraint_Error
-will be raised unconditionally, with or without
-@option{-gnato}. That's why the assigned values in the above fragment
-are in quotes, the meaning is "assign a value not known to the
-compiler that happens to be equal to ...". The remaining discussion
-assumes that the compiler cannot detect the values at compile time.
-
-Here the first addition results in a value that is outside the base range
-of Integer, and hence requires an overflow check for detection of the
-constraint error. Thus the first assignment to @code{X1} raises a
-@code{Constraint_Error} exception only if @option{-gnato} is set.
-
-The second increment operation results in a violation of the explicit
-range constraint; such range checks are performed by default, and are
-unaffected by @option{-gnato}.
-
-The two conversions of @code{F} both result in values that are outside
-the base range of type @code{Integer} and thus will raise
-@code{Constraint_Error} exceptions only if @option{-gnato} is used.
-The fact that the result of the second conversion is assigned to
-variable @code{X4} with a restricted range is irrelevant, since the problem
-is in the conversion, not the assignment.
-
-Basically the rule is that in the default mode (@option{-gnato} not
-used), the generated code assures that all integer variables stay
-within their declared ranges, or within the base range if there is
-no declared range. This prevents any serious problems like indexes
-out of range for array operations.
-
-What is not checked in default mode is an overflow that results in
-an in-range, but incorrect value. In the above example, the assignments
-to @code{X1}, @code{X2}, @code{X3} all give results that are within the
-range of the target variable, but the result is wrong in the sense that
-it is too large to be represented correctly. Typically the assignment
-to @code{X1} will result in wrap around to the largest negative number.
-The conversions of @code{F} will result in some @code{Integer} value
-and if that integer value is out of the @code{X4} range then the
-subsequent assignment would generate an exception.
+procedure Add_And_Subtract (X : in out Integer; Y, Z : in Integer) is
+begin
+ X := X + Y - Z;
+end Add_And_Subtract;
+
+X1 : Integer := Integer'Last;
+X2 : Integer range 1 .. 5 := 5;
+
+Add_And_Subtract (X1, 1, 0); -- first addition and subtraction
+Add_And_Subtract (X1, 1, 1); -- second addition and subtraction
+Add_And_Subtract (X2, 1, 0); -- third addition and subtraction
+Add_And_Subtract (X2, 1, 1); -- fourth addition and subtraction
+@end smallexample
+
+@noindent
+Note that if explicit values are assigned at compile time, the compiler
+may be able to detect overflow at compile time, in which case no actual
+run-time checking code is required, and @code{Constraint_Error} will be
+raised unconditionally, with or without @option{-gnato}.
+
+The first addition results in a value that is outside the base range of
+@code{Integer}. In mode @code{CHECKED}, this raises
+@code{Constraint_Error} at run time. In mode @code{MINIMIZED}, the
+addition and subtraction are performed in type @code{Long_Long_Integer},
+which is 64 bits for most machines. The compiler detects that no
+overflow check is needed on these operations. The program still raises
+@code{Constraint_Error} at run time because the resulting value is too
+large to be assigned to @code{X}. The assignment results in a violation
+of the explicit range constraint; such range checks are performed by
+default, and are unaffected by @option{-gnato??}. In mode
+@code{ELIMINATED}, the compiler uses type @code{Long_Long_Integer} for
+intermediate computations, as this type is sufficient here to avoid all
+overflows. When it is not sufficient, the compiler uses instead a
+library for multiple-precision arithmetic, which may cause a significant
+run-time overhead. The program still raises @code{Constraint_Error} at
+run time when assigning to @code{X}.
+
+The second addition results in a value that is outside the base range of
+@code{Integer}. In mode @code{CHECKED}, this raises
+@code{Constraint_Error} at run time, like in the previous case. In mode
+@code{MINIMIZED}, the addition and subtraction are performed in type
+@code{Long_Long_Integer}, resulting in a final value that fits in an
+@code{Integer}. Thus, no @code{Constraint_Error} is raised. In mode
+@code{ELIMINATED}, the compiler generates the same code as in mode
+@code{MINIMIZED}, which avoids all overflows.
+
+The third addition and subtraction result in an intermediate value and a
+result well in the base range of @code{Integer}, so no
+@code{Constraint_Error} exception is raised at run time in any
+mode. However, the copy to @code{X2} when returning from the call to
+@code{Add_And_Subtract} fails the range check for the type of
+@code{X2}. Hence, a @code{Constraint_Error} exception is raised at run
+time in all modes.
+
+The fourth addition and subtraction result in an intermediate value and
+a result well in the base range of @code{Integer}, and in a final value
+that fits in the type of @code{X2}. Hence, no exception is raised at run
+time in any mode.
+
+Basically the rule is that in the default mode (@option{-gnato??} not
+used), the generated code assures that all integer variables stay within
+their declared ranges, or within the base range if there is no declared
+range. This prevents any serious problems like indexes out of range for
+array operations.
+
+What is not checked in default mode is an overflow that results in an
+in-range, but incorrect value. In the above example, the first
+assignment to @code{X1} gives a result that is within the range of the
+target variable, but the result is wrong in the sense that it is too
+large to be represented correctly. Typically the assignment to @code{X1}
+will result in wrap around to the largest negative number.
@findex Machine_Overflows
-Note that the @option{-gnato} switch does not affect the code generated
+Note that the @option{-gnato??} switch does not affect the code generated
for any floating-point operations; it applies only to integer
-semantics).
-For floating-point, GNAT has the @code{Machine_Overflows}
+semantics.
+For floating-point, @value{EDITION} has the @code{Machine_Overflows}
attribute set to @code{False} and the normal mode of operation is to
generate IEEE NaN and infinite values on overflow or invalid operations
(such as dividing 0.0 by 0.0).
@@ -6944,12 +7011,12 @@ subscript), or a wild jump (from an out of range case value). Overflow
checking is also quite expensive in time and space, since in general it
requires the use of double length arithmetic.
-Note again that @option{-gnato} is off by default, so overflow checking is
+Note again that the default is @option{-gnato00}, so overflow checking is
not performed in default mode. This means that out of the box, with the
-default settings, GNAT does not do all the checks expected from the
+default settings, @value{EDITION} does not do all the checks expected from the
language description in the Ada Reference Manual. If you want all constraint
checks to be performed, as described in this Manual, then you must
-explicitly use the -gnato switch either on the @command{gnatmake} or
+explicitly use the @option{-gnato??} switch either on the @command{gnatmake} or
@command{gcc} command.
@item -gnatE
@@ -18876,6 +18943,9 @@ and will attempt to generate corresponding Ada comments.
If you want to generate a single Ada file and not the transitive closure, you
can use instead the @option{-fdump-ada-spec-slim} switch.
+You can optionally specify a parent unit, of which all generated units will
+be children, using @code{-fada-spec-parent=}@var{unit}.
+
Note that we recommend when possible to use the @command{g++} driver to
generate bindings, even for most C headers, since this will in general
generate better Ada specs. For generating bindings for C++ headers, it is
@@ -19059,6 +19129,11 @@ all header files that these headers depend upon).
Generate Ada spec files for the header files specified on the command line
only.
+@item -fada-spec-parent=@var{unit}
+@cindex -fada-spec-parent (@command{gcc})
+Specifies that all files generated by @option{-fdump-ada-spec-slim} are
+to be child units of the specified parent unit.
+
@item -C
@cindex @option{-C} (@command{gcc})
Extract comments from headers and generate Ada comments in the Ada spec files.
@@ -25451,6 +25526,420 @@ and figuring out which is correct, and then adding the necessary
@code{Elaborate} or @code{Elaborate_All} pragmas to ensure the desired order.
+@c **********************************
+@node Overflow Check Handling in GNAT
+@appendix Overflow Check Handling in GNAT
+@cindex Overflow checks
+@cindex Checks (overflow)
+@c **********************************
+
+@menu
+* Background::
+* Overflow Checking Modes in GNAT::
+* Specifying the Desired Mode::
+* Default Settings::
+* Implementation Notes::
+@end menu
+
+
+@node Background
+@section Background
+
+@noindent
+Overflow checks are checks that the compiler may make to ensure
+that intermediate results are not out of range. For example:
+
+@smallexample @c ada
+ A : Integer;
+ ...
+ A := A + 1;
+@end smallexample
+
+@noindent
+if @code{A} has the value @code{Integer'Last}, then the addition may cause
+overflow since the result is out of range of the type @code{Integer}.
+In this case @code{Constraint_Error} will be raised if checks are
+enabled.
+
+A trickier situation arises in examples like the following:
+
+@smallexample @c ada
+ A, C : Integer;
+ ...
+ A := (A + 1) + C;
+@end smallexample
+
+@noindent
+where @code{A} is @code{Integer'Last} and @code{C} is @code{-1}.
+Now the final result of the expression on the right hand side is
+@code{Integer'Last} which is in range, but the question arises whether the
+intermediate addition of @code{(A + 1)} raises an overflow error.
+
+The (perhaps surprising) answer is that the Ada language
+definition does not answer this question. Instead it leaves
+it up to the implementation to do one of two things:
+
+@itemize @bullet
+@item
+raise an exception (@code{Constraint_Error}), or
+
+@item
+yield the correct mathematical result which is then used in
+subsequent operations.
+@end itemize
+
+@noindent
+If the compiler chooses the first approach, then the assignment of this
+example will indeed raise @code{Constraint_Error}. But if the compiler
+chooses the second approach, then it can perform both additions yielding
+the correct mathematical result, which is in range, so no exception
+will be raised.
+
+Note that in the first example an
+exception will be raised in either case, since if the compiler
+gives the correct mathematical result for the addition, it will
+be out of range of the target type of the assignment, and thus
+fails the range check.
+
+This lack of specified behavior in the handling of overflow for
+intermediate results is a source of non-portability, and can thus
+be problematic when programs are ported. Most typically this arises
+in a situation where the original compiler did not raise an exception,
+and then the application is moved to a compiler where the check is
+performed on the intermediate result and an unexpected exception is
+raised.
+
+Furthermore, when using Ada 2012's preconditions and other
+assertion forms, another issue arises. Consider:
+
+@smallexample @c ada
+ procedure P (A, B : Integer) with
+ Pre => A + B <= Integer'Last;
+@end smallexample
+
+@noindent
+One often wants to regard arithmetic in a context like this from
+a mathematical point of view. So for example, if the two actual parameters
+for a call to @code{P} are both @code{Integer'Last}, then
+the precondition should be regarded as False. If we are executing
+in a mode with run-time checks enabled for preconditions, then we would
+like this precondition to fail, rather than raising an exception
+because of the intermediate overflow.
+
+However, the language definition leaves the specification of
+whether the above condition fails (raising @code{Assert_Error}) or
+causes an intermediate overflow (raising @code{Constraint_Error})
+up to the implementation.
+
+The situation is worse in a case such as the following:
+
+@smallexample @c ada
+ procedure Q (A, B, C : Integer) with
+ Pre => A + B + C <= Integer'Last;
+@end smallexample
+
+@noindent
+Consider the call
+
+@smallexample @c ada
+ Q (A => Integer'Last, B => 1, C => -1);
+@end smallexample
+
+@noindent
+From a mathematical point of view the precondition
+is True, but at run time we may (but are not guaranteed to) get an
+exception raised because of the intermediate overflow (and we really
+would prefer this precondition to be considered True at run time).
+
+@node Overflow Checking Modes in GNAT
+@section Overflow Checking Modes in GNAT
+
+@noindent
+To deal with the portability issue, and with the problem of
+mathematical versus run-time intepretation of the expressions in
+assertions, GNAT provides comprehensive control over the handling
+of intermediate overflow. GNAT can operate in four modes, and
+furthemore, 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.
+
+The four modes are:
+
+@itemize @bullet
+@item @i{Checks suppressed} (@code{SUPPRESSED})
+
+ This is the normal defined language mode, as specified by a pragma
+ @code{Suppress (Overflow_Check)}. If any intermediate overflow occurs,
+ then the program execution is erroneous, which means that anything
+ could happen. Note in particular, that the result of evaluating
+ a precondition may be plain wrong if there is an intermediate
+ overflow, as in our examples above.
+
+@item @i{All intermediate overflows checked} (@code{CHECKED})
+
+ In this mode, all intermediate results for predefined arithmetic
+ operators must be in range of the base type. If this is not the
+ case a constraint error is raised. This is the normal default mode
+ specified by use of the pragma @code{Unsuppress (Overflow_Check)}.
+
+@item @i{Most intermediate overflows avoided} (@code{MINIMIZED})
+
+ In this mode, the compiler attempts to avoid intermediate overflows by
+ using @code{Long_Long_Integer} as the type in which arithmetic is
+ performed for predefined arithmetic operators. This is slightly more
+ expensive at
+ run time (compared to suppressing intermediate overflow checks), though
+ the cost is minimal on modern 64-bit machines. For the examples given
+ earlier, no intermediate overflows would have resulted in exceptions,
+ since the intermediate results are all in the range of
+ @code{Long_Long_Integer} (typically 64-bits on nearly all implementations
+ of GNAT).
+
+ However, there are cases where @code{Long_Long_Integer} is not large
+ enough, consider the following example:
+
+@smallexample @c ada
+ procedure R (A, B, C, D : Integer) with
+ Pre => (A**2 * B**2) / (C**2 * D**2) <= 10;
+@end smallexample
+
+ where @code{A} = @code{B} = @code{C} = @code{D} = @code{Integer'Last}.
+ Now the intermediate results are
+ out of the range of @code{Long_Long_Integer} even though the final result
+ is in range and the precondition is True (from a mathematical point
+ of view). In such a case, operating in this mode, an exception will
+ be raised for the intermediate overflow (which is why this mode
+ says @i{most} intermediate overflows are avoided).
+
+@item @i{All intermediate overflows avoided} (@code{ELIMINATED})
+
+ In this mode, the compiler avoids all intermediate overflows
+ by using arbitrary precision arithmetic as required. In this
+ mode, the above example with @code{A**2 * B**2} would
+ not cause intermediate overflow, because the intermediate result
+ would be evaluated using sufficient precision, and the result
+ of evaluating the precondition would be True.
+
+ This mode has the advantage of avoiding any intermediate
+ overflows, but at the expense of significant run-time overhead,
+ including the use of a library (included automatically in this
+ mode) for multiple-precision arithmetic.
+
+ This mode provides cleaner semantics for assertions, since now
+ the run-time behavior emulates true arithmetic behavior for the
+ predefined arithmetic operators, meaning that there is never a
+ conflict between the mathematical view of the assertion, and its
+ run-time behavior.
+@end itemize
+
+@noindent
+ Note that these modes apply only to the evaluation of predefined
+ arithmetic, membership, and comparison operators for signed integer
+ aritmetic.
+
+ For fixed-point arithmetic, checks can be suppressed. But if checks
+ are enabled (any of the three non-suppress modes will enable checks),
+ then fixed-point values are always checked for overflow against the
+ base type for intermediate expressions.
+
+ For floating-point, on nearly all architectures, @code{Machine_Overflows}
+ is False, and IEEE infinities are generated, so overflow exceptions
+ are never raised. If you want to avoid infinities, and check that
+ final results of expressions are in range, then you can declare a
+ constrained floating-point type, and range checks will be carried
+ out in the normal manner (with infinite values always failing all
+ range checks).
+
+
+@c -------------------------
+@node Specifying the Desired Mode
+@section Specifying the Desired Mode
+
+@noindent
+The desired mode of overflow checking can be specified using
+either the @code{Overflow_Checks} pragma or an equivalent compiler switch.
+The pragma has the form
+@cindex pragma @code{Overflow_Checks}
+
+@smallexample @c ada
+ pragma Overflow_Checks ([General =>] MODE [, [Assertions =>] MODE]);
+@end smallexample
+
+@noindent
+where @code{MODE} is one of
+
+@itemize @bullet
+@item @code{SUPPRESSED}: suppress overflow checks
+@item @code{CHECKED}: all intermediate overflows checked
+@item @code{MINIMIZED}: minimize intermediate overflows
+@item @code{ELIMINATED}: eliminate intermediate overflows
+@end itemize
+
+@noindent
+The case is ignored, so @code{MINIMIZED}, @code{Minimized} and
+@code{minimized} all have the same effect.
+
+If only the @code{General} parameter is present, then the given @code{MODE}
+applies
+to expressions both within and outside assertions. If both arguments
+are present, then @code{General} applies to expressions outside assertions,
+and @code{Assertions} applies to expressions within assertions. For example:
+
+@smallexample @c ada
+ pragma Overflow_Checks
+ (General => Minimized, Assertions => Eliminated);
+@end smallexample
+
+@noindent
+specifies that general expressions outside assertions be evaluated
+in ``minimize intermediate overflows'' mode, and expressions within
+assertions be evaluated in ``eliminate intermediate overflows'' mode.
+This is often a reasonable choice, avoiding excessive overhead
+outside assertions, but assuring a high degree of portability
+when importing code from another compiler, while incurring
+the extra overhead for assertion expressions to ensure that
+the behavior at run time matches the expected mathematical
+behavior.
+
+The @code{Overflow_Checks} pragma has the same scoping and placement
+rules as pragma @code{Suppress}, so it can occur either as a
+configuration pragma, specifying a default for the whole
+program, or in a declarative scope, where it applies to the
+remaining declarations and statements in that scope.
+
+Additionally, a compiler switch @option{-gnato?} or @option{-gnato??}
+can be used to control the checking mode default (which can be subsequently
+overridden using the pragma form).
+@cindex @option{-gnato?} (gcc)
+@cindex @option{-gnato??} (gcc)
+
+Here `@code{?}' is one of the digits `@code{0}' through `@code{3}':
+
+@itemize @bullet
+@item @code{0}:
+suppress overflow checks (@code{SUPPRESSED})
+@item @code{1}:
+all intermediate overflows checked (@code{CHECKED})
+@item @code{2}:
+minimize intermediate overflows (@code{MINIMIZED})
+@item @code{3}:
+eliminate intermediate overflows (@code{ELIMINATED})
+@end itemize
+
+@noindent
+As with the pragma, if only one digit appears then it applies to all
+cases; if two digits are given, then the first applies outside
+assertions, and the second within assertions. Thus the equivalent
+of the example pragma above would be @option{-gnato23}.
+
+If no digits follow the @option{-gnato}, then it is equivalent to
+@option{-gnato11},
+causing all intermediate overflows to be checked.
+
+
+@c -------------------------
+@node Default Settings
+@section Default Settings
+
+The default mode for overflow checks is
+
+@smallexample
+ General => Suppressed
+@end smallexample
+
+@noindent
+which suppresses checks inside and outside assertions,
+This retains compatibility with previous versions of
+GNAT which suppressed overflow checks by default.
+
+The switch @option{-gnato} (with no digits following) is equivalent to
+@cindex @option{-gnato} (gcc)
+
+@smallexample
+ General => Checked
+@end smallexample
+
+@noindent
+which causes overflow checking of all intermediate overflows
+both inside and outside assertions. This provides compatibility
+with this switch as implemented in previous versions of GNAT.
+
+The pragma @code{Suppress (Overflow_Check)} sets mode
+
+@smallexample
+ General => Suppressed
+@end smallexample
+
+@noindent
+suppressing all overflow checking within and outside
+assertions.
+@cindex @code{Overflow_Check} (argument to pragma Suppress)
+
+The pragam @code{Unsuppress (Overflow_Check)} sets mode
+
+@smallexample
+ General => Checked
+@end smallexample
+
+@noindent
+which causes overflow checking of all intermediate overflows.
+This applies both inside and outside assertions.
+@cindex @code{Overflow_Check} (argument to pragma Unsuppress)
+
+
+@c -------------------------
+@node Implementation Notes
+@section Implementation Notes
+
+In practice on typical 64-bit machines, the @code{MINIMIZED} mode is
+reasonably efficient, and can be generally used. It also helps
+to ensure compatibility with code imported from some other
+compiler to GNAT.
+
+Setting all intermediate overflows checking (@code{CHECKED} mode)
+makes sense if you want to
+make sure that your code is compatible with any other possible
+Ada implementation. This may be useful in ensuring portability
+for code that is to be exported to some other compiler than GNAT.
+It is also appropriate if you intend to turn off checks for
+the final delivered software, since in @code{SUPPRESSED} mode, the
+assumption is that all intermediate results are in range. In
+this situation, it is likely that you are also suppressing
+assertions in the final executable, so in that case it does not
+matter which mode is selected for assertions during development.
+
+The Ada standard allows the reassociation of expressions at
+the same precedence level if no parentheses are present. For
+example, @w{@code{A+B+C}} parses as though it were @w{@code{(A+B)+C}}, but
+the compiler can reintepret this as @w{@code{A+(B+C)}}, possibly
+introducing or eliminating an overflow exception. The GNAT
+compiler never takes advantage of this freedom, and the
+expression @w{@code{A+B+C}} will be evaluated as @w{@code{(A+B)+C}}.
+If you need the other order, you can write the parentheses
+explicitly @w{@code{A+(B+C)}} and GNAT will respect this order.
+
+The use of @code{ELIMINATED} mode will cause the compiler to
+automatically include an appropriate arbitrary precision
+integer arithmetic package. The compiler will make calls
+to this package, though only in cases where it cannot be
+sure that @code{Long_Long_Integer} is sufficient to guard against
+intermediate overflows. This package does not use dynamic
+alllocation, but it does use the secondary stack, so an
+appropriate secondary stack package must be present (this
+is always true for standard full Ada, but may require
+specific steps for restricted run times such as ZFP).
+
+Although @code{ELIMINATED} mode causes expressions to use arbitrary
+precision arithmetic, avoiding overflow, the final result
+must be in an appropriate range. This is true even if the
+final result is of type @code{[Long_[Long_]]Integer'Base}, which
+still has the same bounds as its associated constrained
+type at run-time.
+
+Currently, the @code{ELIMINATED} mode is only available on target
+platforms for which @code{Long_Long_Integer} is 64-bits (nearly all GNAT
+platforms).
@c *******************************
@node Conditional Compilation
@@ -27723,10 +28212,16 @@ success. It should be possible to use @code{GetLastError} and
features are not used, but it is not guaranteed to work.
@item
-It is not possible to link against Microsoft libraries except for
+It is not possible to link against Microsoft C++ libraries except for
import libraries. Interfacing must be done by the mean of DLLs.
@item
+It is possible to link against Microsoft C libraries. Yet the preferred
+solution is to use C/C++ compiler that comes with @value{EDITION}, since it
+doesn't require having two different development environments and makes the
+inter-language debugging experience smoother.
+
+@item
When the compilation environment is located on FAT32 drives, users may
experience recompilations of the source files that have not changed if
Daylight Saving Time (DST) state has changed since the last time files
@@ -27813,14 +28308,14 @@ application that contains a mix of Ada and C/C++, the choice of your
Windows C/C++ development environment conditions your overall
interoperability strategy.
-If you use @command{gcc} to compile the non-Ada part of your application,
-there are no Windows-specific restrictions that affect the overall
-interoperability with your Ada code. If you do want to use the
-Microsoft tools for your non-Ada code, you have two choices:
+If you use @command{gcc} or Microsoft C to compile the non-Ada part of
+your application, there are no Windows-specific restrictions that
+affect the overall interoperability with your Ada code. If you do want
+to use the Microsoft tools for your C++ code, you have two choices:
@enumerate
@item
-Encapsulate your non-Ada code in a DLL to be linked with your Ada
+Encapsulate your C++ code in a DLL to be linked with your Ada
application. In this case, use the Microsoft or whatever environment to
build the DLL and use GNAT to build your executable
(@pxref{Using DLLs with GNAT}).
diff --git a/gcc/ada/gnatcmd.adb b/gcc/ada/gnatcmd.adb
index 82e3f4593..1919f9a00 100644
--- a/gcc/ada/gnatcmd.adb
+++ b/gcc/ada/gnatcmd.adb
@@ -848,6 +848,9 @@ procedure GNATCmd is
Unit : Unit_Index;
Path : Path_Name_Type;
+ Files_File : Ada.Text_IO.File_Type;
+ Temp_File_Name : Path_Name_Type;
+
begin
if GN_Path = null then
Put_Line (Standard_Error, "could not locate " & GN_Name);
@@ -856,7 +859,7 @@ procedure GNATCmd is
-- Create the temp file
- Tempdir.Create_Temp_File (FD, Name);
+ Prj.Env.Create_Temp_File (Project_Tree.Shared, FD, Name, "files");
-- And close it, because on VMS Spawn with a file descriptor created
-- with Create_Temp_File does not redirect output.
@@ -904,8 +907,19 @@ procedure GNATCmd is
raise Error_Exit;
else
- -- Get each file name in the file, find its path and add it the
- -- list of arguments.
+ -- Create a temporary file to put the list of files in the closure
+
+ Tempdir.Create_Temp_File (FD, Temp_File_Name);
+ Last_Switches.Increment_Last;
+ Last_Switches.Table (Last_Switches.Last) :=
+ new String'("-files=" & Get_Name_String (Temp_File_Name));
+
+ Close (FD);
+
+ Open (Files_File, Out_File, Get_Name_String (Temp_File_Name));
+
+ -- Get each file name in the file, find its path and add it the list
+ -- of arguments.
while not End_Of_File (File) loop
Get_Line (File, Line, Last);
@@ -933,18 +947,16 @@ procedure GNATCmd is
Unit := Units_Htable.Get_Next (Project_Tree.Units_HT);
end loop;
- Last_Switches.Increment_Last;
-
if Path /= No_Path then
- Last_Switches.Table (Last_Switches.Last) :=
- new String'(Get_Name_String (Path));
+ Put_Line (Files_File, Get_Name_String (Path));
else
- Last_Switches.Table (Last_Switches.Last) :=
- new String'(Line (1 .. Last));
+ Put_Line (Files_File, Line (1 .. Last));
end if;
end loop;
+ Close (Files_File);
+
begin
if not Keep_Temporary_Files then
Delete (File);
@@ -1769,19 +1781,29 @@ begin
-- -vPx Specify verbosity while parsing project files
- elsif Argv'Length = 4
- and then Argv (Argv'First + 1 .. Argv'First + 2) = "vP"
+ elsif Argv'Length >= 3
+ and then Argv (Argv'First + 1 .. Argv'First + 2) = "vP"
then
- case Argv (Argv'Last) is
- when '0' =>
- Current_Verbosity := Prj.Default;
- when '1' =>
- Current_Verbosity := Prj.Medium;
- when '2' =>
- Current_Verbosity := Prj.High;
- when others =>
- Fail ("Invalid switch: " & Argv.all);
- end case;
+ if Argv'Length = 4
+ and then Argv (Argv'Last) in '0' .. '2'
+ then
+ case Argv (Argv'Last) is
+ when '0' =>
+ Current_Verbosity := Prj.Default;
+ when '1' =>
+ Current_Verbosity := Prj.Medium;
+ when '2' =>
+ Current_Verbosity := Prj.High;
+ when others =>
+
+ -- Cannot happen
+
+ raise Program_Error;
+ end case;
+ else
+ Fail ("invalid verbosity level: "
+ & Argv (Argv'First + 3 .. Argv'Last));
+ end if;
Remove_Switch (Arg_Num);
@@ -2047,6 +2069,11 @@ begin
or else The_Command = Link
or else The_Command = Elim
then
+ if Project.Object_Directory.Name = No_Path then
+ Fail ("project " & Get_Name_String (Project.Display_Name) &
+ " has no object directory");
+ end if;
+
Change_Dir (Get_Name_String (Project.Object_Directory.Name));
end if;
@@ -2284,10 +2311,15 @@ begin
(new String'("-gnatem=" & Get_Name_String (M_File)));
end if;
- -- For gnatcheck, also indicate a global configuration pragmas
- -- file and, if -U is not used, a local one.
+ -- For gnatcheck, gnatpp, gnatstub and gnatmetric, also
+ -- indicate a global configuration pragmas file and, if -U
+ -- is not used, a local one.
- if The_Command = Check then
+ if The_Command = Check or else
+ The_Command = Pretty or else
+ The_Command = Stub or else
+ The_Command = Metric
+ then
declare
Pkg : constant Prj.Package_Id :=
Prj.Util.Value_Of
@@ -2320,9 +2352,14 @@ begin
if Variable /= Nil_Variable_Value
and then Length_Of_Name (Variable.Value) /= 0
then
- Add_To_Carg_Switches
- (new String'
- ("-gnatec=" & Get_Name_String (Variable.Value)));
+ declare
+ Path : constant String :=
+ Absolute_Path
+ (Path_Name_Type (Variable.Value), Project);
+ begin
+ Add_To_Carg_Switches
+ (new String'("-gnatec=" & Path));
+ end;
end if;
end;
@@ -2360,10 +2397,14 @@ begin
if Variable /= Nil_Variable_Value
and then Length_Of_Name (Variable.Value) /= 0
then
- Add_To_Carg_Switches
- (new String'
- ("-gnatec=" &
- Get_Name_String (Variable.Value)));
+ declare
+ Path : constant String :=
+ Absolute_Path
+ (Path_Name_Type (Variable.Value), Project);
+ begin
+ Add_To_Carg_Switches
+ (new String'("-gnatec=" & Path));
+ end;
end if;
end;
end if;
diff --git a/gcc/ada/gprep.adb b/gcc/ada/gprep.adb
index f6ce3acf0..0fad22bf7 100644
--- a/gcc/ada/gprep.adb
+++ b/gcc/ada/gprep.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2012, 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- --
@@ -720,7 +720,7 @@ package body GPrep is
loop
begin
- Switch := GNAT.Command_Line.Getopt ("D: b c C r s T u v");
+ Switch := GNAT.Command_Line.Getopt ("D: a b c C r s T u v");
case Switch is
@@ -731,6 +731,10 @@ package body GPrep is
Process_Command_Line_Symbol_Definition
(S => GNAT.Command_Line.Parameter);
+ when 'a' =>
+ Opt.No_Deletion := True;
+ Opt.Undefined_Symbols_Are_False := True;
+
when 'b' =>
Opt.Blank_Deleted_Lines := True;
diff --git a/gcc/ada/impunit.adb b/gcc/ada/impunit.adb
index 99d0c2714..712a6885b 100644
--- a/gcc/ada/impunit.adb
+++ b/gcc/ada/impunit.adb
@@ -564,6 +564,7 @@ package body Impunit is
("a-cbprqu", T), -- Ada.Containers.Bounded_Priority_Queues
("a-extiin", T), -- Ada.Execution_Time.Interrupts
("a-iteint", T), -- Ada.Iterator_Interfaces
+ ("a-locale", T), -- Ada.Locales
("a-synbar", T), -- Ada.Synchronous_Barriers
("a-undesu", T), -- Ada.Unchecked_Deallocate_Subpool
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 8a27a6016..ad00e148f 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -103,12 +103,14 @@ char *__gl_interrupt_states = 0;
int __gl_num_interrupt_states = 0;
int __gl_unreserve_all_interrupts = 0;
int __gl_exception_tracebacks = 0;
-int __gl_zero_cost_exceptions = 0;
int __gl_detect_blocking = 0;
int __gl_default_stack_size = -1;
int __gl_leap_seconds_support = 0;
int __gl_canonical_streams = 0;
+/* This value is not used anymore, but kept for bootstrapping purpose. */
+int __gl_zero_cost_exceptions = 0;
+
/* Indication of whether synchronous signal handler has already been
installed by a previous call to adainit. */
int __gnat_handler_installed = 0;
diff --git a/gcc/ada/layout.adb b/gcc/ada/layout.adb
index 60a44a90f..1f44196bd 100644
--- a/gcc/ada/layout.adb
+++ b/gcc/ada/layout.adb
@@ -1964,11 +1964,11 @@ package body Layout is
pragma Warnings (Off, SO_Ref);
RM_Siz_Expr : Node_Id := Empty;
- -- Expression for the evolving RM_Siz value. This is typically a
- -- conditional expression which involves tests of discriminant values
- -- that are formed as references to the entity V. At the end of
- -- scanning all the components, a suitable function is constructed
- -- in which V is the parameter.
+ -- Expression for the evolving RM_Siz value. This is typically an if
+ -- expression which involves tests of discriminant values that are
+ -- formed as references to the entity V. At the end of scanning all
+ -- the components, a suitable function is constructed in which V is
+ -- the parameter.
-----------------------
-- Local Subprograms --
@@ -2212,7 +2212,7 @@ package body Layout is
end if;
RM_Siz_Expr :=
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions =>
New_List
(Dtest, Bits_To_SU (RM_SizV), RM_Siz_Expr));
@@ -2448,6 +2448,7 @@ package body Layout is
and then
Nkind (Type_Definition (Parent (Desig_Type)))
= N_Unconstrained_Array_Definition
+ and then not Debug_Flag_6
then
Init_Size (E, 2 * System_Address_Size);
diff --git a/gcc/ada/lib-xref.adb b/gcc/ada/lib-xref.adb
index bbf1a3db4..aa9031f83 100644
--- a/gcc/ada/lib-xref.adb
+++ b/gcc/ada/lib-xref.adb
@@ -945,6 +945,13 @@ package body Lib.Xref is
then
Ent := E;
+ -- Ditto for the formals of such a subprogram
+
+ elsif Is_Overloadable (Scope (E))
+ and then Is_Child_Unit (Scope (E))
+ then
+ Ent := E;
+
-- Record components of discriminated subtypes or derived types must
-- be treated as references to the original component.
diff --git a/gcc/ada/make.adb b/gcc/ada/make.adb
index d45ee140b..28674251b 100644
--- a/gcc/ada/make.adb
+++ b/gcc/ada/make.adb
@@ -410,7 +410,7 @@ package body Make is
-- Delete all temp files created by Gnatmake and call Osint.Fail, with the
-- parameter S (see osint.ads). This is called from the Prj hierarchy and
-- the MLib hierarchy. This subprogram also prints current error messages
- -- on stdout (ie finalizes errout)
+ -- (i.e. finalizes Errutil).
--------------------------
-- Obsolete Executables --
@@ -3790,44 +3790,6 @@ package body Make is
Result : Argument_List (1 .. 3);
Last : Natural := 0;
- function Absolute_Path
- (Path : Path_Name_Type;
- Project : Project_Id) return String;
- -- Returns an absolute path for a configuration pragmas file
-
- -------------------
- -- Absolute_Path --
- -------------------
-
- function Absolute_Path
- (Path : Path_Name_Type;
- Project : Project_Id) return String
- is
- begin
- Get_Name_String (Path);
-
- declare
- Path_Name : constant String := Name_Buffer (1 .. Name_Len);
-
- begin
- if Is_Absolute_Path (Path_Name) then
- return Path_Name;
-
- else
- declare
- Parent_Directory : constant String :=
- Get_Name_String
- (Project.Directory.Display_Name);
-
- begin
- return Parent_Directory & Path_Name;
- end;
- end if;
- end;
- end Absolute_Path;
-
- -- Start of processing for Configuration_Pragmas_Switch
-
begin
Prj.Env.Create_Config_Pragmas_File
(For_Project, Project_Tree);
@@ -7825,11 +7787,12 @@ package body Make is
-- -vPx (verbosity of the parsing of the project files)
- elsif Argv'Last = 4
- and then Argv (2 .. 3) = "vP"
- and then Argv (4) in '0' .. '2'
- then
- if And_Save then
+ elsif Argv'Length >= 3 and then Argv (2 .. 3) = "vP" then
+ if Argv'Last /= 4 or else Argv (4) not in '0' .. '2' then
+ Make_Failed
+ ("invalid verbosity level " & Argv (4 .. Argv'Last));
+
+ elsif And_Save then
case Argv (4) is
when '0' =>
Current_Verbosity := Prj.Default;
diff --git a/gcc/ada/makeutl.adb b/gcc/ada/makeutl.adb
index cdbe1aa13..a2ea43526 100644
--- a/gcc/ada/makeutl.adb
+++ b/gcc/ada/makeutl.adb
@@ -139,6 +139,37 @@ package body Makeutl is
end if;
end Add_Linker_Option;
+ -------------------
+ -- Absolute_Path --
+ -------------------
+
+ function Absolute_Path
+ (Path : Path_Name_Type;
+ Project : Project_Id) return String
+ is
+ begin
+ Get_Name_String (Path);
+
+ declare
+ Path_Name : constant String := Name_Buffer (1 .. Name_Len);
+
+ begin
+ if Is_Absolute_Path (Path_Name) then
+ return Path_Name;
+
+ else
+ declare
+ Parent_Directory : constant String :=
+ Get_Name_String
+ (Project.Directory.Display_Name);
+
+ begin
+ return Parent_Directory & Path_Name;
+ end;
+ end if;
+ end;
+ end Absolute_Path;
+
-------------------------
-- Base_Name_Index_For --
-------------------------
diff --git a/gcc/ada/makeutl.ads b/gcc/ada/makeutl.ads
index 1b899c1bb..7848ed093 100644
--- a/gcc/ada/makeutl.ads
+++ b/gcc/ada/makeutl.ads
@@ -87,6 +87,11 @@ package Makeutl is
Last : in out Natural);
-- Add a string to a list of strings
+ function Absolute_Path
+ (Path : Path_Name_Type;
+ Project : Project_Id) return String;
+ -- Returns an absolute path for a configuration pragmas file
+
function Create_Binder_Mapping_File
(Project_Tree : Project_Tree_Ref) return Path_Name_Type;
-- Create a binder mapping file and returns its path name
diff --git a/gcc/ada/namet.ads b/gcc/ada/namet.ads
index c4155b4ba..e8978f8b5 100644
--- a/gcc/ada/namet.ads
+++ b/gcc/ada/namet.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -47,11 +47,11 @@ package Namet is
-- The forms of the entries are as follows:
--- Identifiers Stored with upper case letters folded to lower case. Upper
--- half (16#80# bit set) and wide characters are stored
--- in an encoded form (Uhh for upper half char, Whhhh
--- for wide characters, WWhhhhhhhh as provided by the
--- routine Store_Encoded_Character, where hh are hex
+-- Identifiers Stored with upper case letters folded to lower case.
+-- Upper half (16#80# bit set) and wide characters are
+-- stored in an encoded form (Uhh for upper half char,
+-- Whhhh for wide characters, WWhhhhhhhh as provided by
+-- the routine Store_Encoded_Character, where hh are hex
-- digits for the character code using lower case a-f).
-- Normally the use of U or W in other internal names is
-- avoided, but these letters may be used in internal
diff --git a/gcc/ada/namet.h b/gcc/ada/namet.h
index ec2b488a5..0bc841ac8 100644
--- a/gcc/ada/namet.h
+++ b/gcc/ada/namet.h
@@ -6,7 +6,7 @@
* *
* C Header File *
* *
- * Copyright (C) 1992-2011, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2012, 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- *
@@ -24,7 +24,8 @@
****************************************************************************/
/* This is the C file that corresponds to the Ada package specification
- Namet. It was created manually from files namet.ads and namet.adb. */
+ Namet. It was created manually from files namet.ads and namet.adb.
+ Some subprograms from Sinput are also made acessable here. */
#ifdef __cplusplus
extern "C" {
@@ -111,7 +112,8 @@ extern char *Spec_Filename, *Body_Filename;
#define Is_Non_Ada_Error exp_ch11__is_non_ada_error
extern Boolean Is_Non_Ada_Error (Entity_Id);
-/* Here are some functions in sinput.adb we call from a-trans.c. */
+/* Here are some functions in sinput.adb we call from trans.c. */
+
typedef Nat Source_File_Index;
typedef Int Logical_Line_Number;
typedef Int Column_Number;
diff --git a/gcc/ada/opt.adb b/gcc/ada/opt.adb
index 809816d24..a6c15538c 100644
--- a/gcc/ada/opt.adb
+++ b/gcc/ada/opt.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -259,7 +259,6 @@ package body Opt is
Tree_Read_Bool (Debug_Pragmas_Disabled);
Tree_Read_Bool (Debug_Pragmas_Enabled);
Tree_Read_Int (Int (Default_Pool));
- Tree_Read_Bool (Enable_Overflow_Checks);
Tree_Read_Bool (Full_List);
Ada_Version_Config :=
@@ -326,7 +325,6 @@ package body Opt is
Tree_Write_Bool (Debug_Pragmas_Disabled);
Tree_Write_Bool (Debug_Pragmas_Enabled);
Tree_Write_Int (Int (Default_Pool));
- Tree_Write_Bool (Enable_Overflow_Checks);
Tree_Write_Bool (Full_List);
Tree_Write_Int (Int (Version_String'Length));
Tree_Write_Data (Version_String'Address, Version_String'Length);
diff --git a/gcc/ada/opt.ads b/gcc/ada/opt.ads
index a6c0cf3df..88194b302 100644
--- a/gcc/ada/opt.ads
+++ b/gcc/ada/opt.ads
@@ -230,11 +230,12 @@ package Opt is
Back_End_Handles_Limited_Types : Boolean;
-- This flag is set true if the back end can properly handle limited or
-- other by reference types, and avoid copies. If this flag is False, then
- -- the front end does special expansion for conditional expressions to make
+ -- the front end does special expansion for if/case expressions to make
-- sure that no copy occurs. If the flag is True, then the expansion for
- -- conditional expressions relies on the back end properly handling things.
+ -- if and case expressions relies on the back end properly handling things.
-- Currently the default is False for all cases (set in gnat1drv). The
- -- default can be modified using -gnatd.L (sets the flag True).
+ -- default can be modified using -gnatd.L (sets the flag True). This is
+ -- used to test the possibility of having the backend handle this.
Bind_Alternate_Main_Name : Boolean := False;
-- GNATBIND
@@ -270,6 +271,11 @@ package Opt is
-- Set to True to build, bind and link all the sources of a project file
-- (switch -B)
+ Check_Aliasing_Of_Parameters : Boolean := False;
+ -- GNAT
+ -- Set to True to detect whether subprogram parameters and function results
+ -- alias the same object(s).
+
Check_Object_Consistency : Boolean := False;
-- GNATBIND, GNATMAKE
-- Set to True to check whether every object file is consistent with
@@ -315,9 +321,14 @@ package Opt is
Check_Unreferenced_Formals : Boolean := False;
-- GNAT
- -- Set True to check for unreferenced formals. This is turned on by
+ -- 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. Turned on by??? turned off by???
+
Check_Withs : Boolean := False;
-- GNAT
-- Set to True to enable checking for unused withs, and also the case
@@ -486,11 +497,6 @@ package Opt is
-- GNAT
-- Set to True to generate full elaboration warnings (-gnatwl)
- Enable_Overflow_Checks : Boolean := False;
- -- GNAT
- -- Set to True if -gnato (enable overflow checks) switch is set,
- -- but not -gnatp.
-
Error_Msg_Line_Length : Nat := 0;
-- GNAT
-- Records the error message line length limit. If this is set to zero,
@@ -643,9 +649,14 @@ package Opt is
Generate_SCO : Boolean := False;
-- GNAT
- -- True when switch -gnateS is used. When True, Source Coverage Obligation
- -- (SCO) information is generated and output in the ALI file. See unit
- -- Par_SCO for full details.
+ -- True when switch -fdump-scos (or -gnateS) is used. When True, Source
+ -- Coverage Obligation (SCO) information is generated and output in the ALI
+ -- file. See unit Par_SCO for full details.
+
+ Generate_SCO_Instance_Table : Boolean := False;
+ -- GNAT
+ -- True when switch -fdebug-instances is used. When True, a table of
+ -- instances is included in SCOs.
Generating_Code : Boolean := False;
-- GNAT
@@ -957,6 +968,12 @@ package Opt is
-- in this variable (e.g. 2 = select second unit in file). A value of
-- zero indicates that we are in normal (one unit per file) mode.
+ No_Deletion : Boolean := False;
+ -- GNATPREP
+ -- Set by preprocessor switch -a. Do not eliminate any source text. Implies
+ -- Undefined_Symbols_Are_False. Useful to perform a syntax check on all
+ -- branches of #if constructs.
+
No_Main_Subprogram : Boolean := False;
-- GNATMAKE, GNATBIND
-- Set to True if compilation/binding of a program without main
@@ -1068,12 +1085,6 @@ package Opt is
-- True if output of list of objects is requested (-O switch set). List is
-- output under the given filename, or standard output if not specified.
- Overflow_Checks_Unsuppressed : Boolean := False;
- -- GNAT
- -- This flag is True if there has been at least one pragma with the
- -- effect of unsuppressing overflow checks, meaning that a more careful
- -- check of the current mode is required.
-
Persistent_BSS_Mode : Boolean := False;
-- GNAT
-- True if a Persistent_BSS configuration pragma is in effect, causing
@@ -1252,10 +1263,10 @@ package Opt is
Suppress_Options : Suppress_Record;
-- GNAT
- -- Flags set True to suppress corresponding check, i.e. add an implicit
- -- pragma Suppress at the outer level of each unit compiled. Note that
- -- these suppress actions can be overridden by the use of the Unsuppress
- -- pragma. This variable is initialized by Osint.Initialize.
+ -- Indicates outer level setting of check suppression. This initializes
+ -- the settings of the outer scope level in any unit compiled. This is
+ -- initialized by Osint.Initialize, and further initialized by the
+ -- Adjust_Global_Switches flag in Gnat1drv.
Suppress_Back_Annotation : Boolean := False;
-- GNAT
diff --git a/gcc/ada/osint.adb b/gcc/ada/osint.adb
index 3e452b5d6..8765b4cb6 100644
--- a/gcc/ada/osint.adb
+++ b/gcc/ada/osint.adb
@@ -1655,11 +1655,12 @@ package body Osint is
Src_Search_Directories.Init;
Lib_Search_Directories.Init;
- -- Start off by setting all suppress options to False, these will
- -- be reset later (turning some on if -gnato is not specified, and
- -- turning all of them on if -gnatp is specified).
+ -- Start off by setting all suppress options, to False. The special
+ -- overflow fields are set to Not_Set (they will be set by -gnatp, or
+ -- by -gnato, or, if neither of these appear, in Adjust_Global_Switches
+ -- in Gnat1drv).
- Suppress_Options := ((others => False), Check_All, Check_All);
+ Suppress_Options := ((others => False), Not_Set, Not_Set);
-- Reserve the first slot in the search paths table. This is the
-- directory of the main source file or main library file and is filled
diff --git a/gcc/ada/par-ch4.adb b/gcc/ada/par-ch4.adb
index 79aa85fad..df13d0058 100644
--- a/gcc/ada/par-ch4.adb
+++ b/gcc/ada/par-ch4.adb
@@ -553,7 +553,7 @@ package body Ch4 is
-- case of a name which can be extended in the normal manner.
-- This case is handled by LP_State_Name or LP_State_Expr.
- -- Note: conditional expressions (without an extra level of
+ -- Note: if and case expressions (without an extra level of
-- parentheses) are permitted in this context).
-- (..., identifier => expression , ...)
@@ -1233,21 +1233,21 @@ package body Ch4 is
Lparen_Sloc := Token_Ptr;
T_Left_Paren;
- -- Conditional expression case
+ -- If expression
if Token = Tok_If then
- Expr_Node := P_Conditional_Expression;
+ Expr_Node := P_If_Expression;
T_Right_Paren;
return Expr_Node;
- -- Case expression case
+ -- Case expression
elsif Token = Tok_Case then
Expr_Node := P_Case_Expression;
T_Right_Paren;
return Expr_Node;
- -- Quantified expression case
+ -- Quantified expression
elsif Token = Tok_For then
Expr_Node := P_Quantified_Expression;
@@ -1258,12 +1258,12 @@ package body Ch4 is
-- is distinctly unpleasant, but it saves a lot of fiddling in scanning
-- out the discrete choice list.
- -- Deal with expression and extension aggregate cases first
+ -- Deal with expression and extension aggregates first
elsif Token /= Tok_Others then
Save_Scan_State (Scan_State); -- at start of expression
- -- Deal with (NULL RECORD) case
+ -- Deal with (NULL RECORD)
if Token = Tok_Null then
Scan; -- past NULL
@@ -1287,7 +1287,7 @@ package body Ch4 is
Expr_Node := P_Expression_Or_Range_Attribute_If_OK;
end if;
- -- Extension aggregate case
+ -- Extension aggregate
if Token = Tok_With then
if Nkind (Expr_Node) = N_Attribute_Reference
@@ -1329,7 +1329,7 @@ package body Ch4 is
Expr_Node := Empty;
end if;
- -- Expression case
+ -- Expression
elsif Token = Tok_Right_Paren or else Token in Token_Class_Eterm then
if Nkind (Expr_Node) = N_Attribute_Reference
@@ -1350,13 +1350,13 @@ package body Ch4 is
T_Right_Paren; -- past right paren (error message if none)
return Expr_Node;
- -- Normal aggregate case
+ -- Normal aggregate
else
Aggregate_Node := New_Node (N_Aggregate, Lparen_Sloc);
end if;
- -- Others case
+ -- Others
else
Aggregate_Node := New_Node (N_Aggregate, Lparen_Sloc);
@@ -2454,7 +2454,7 @@ package body Ch4 is
when Tok_Pragma =>
P_Pragmas_Misplaced;
- -- Deal with IF (possible unparenthesized conditional expression)
+ -- Deal with IF (possible unparenthesized if expression)
when Tok_If =>
@@ -2462,7 +2462,7 @@ package body Ch4 is
-- the start of a new line, then we consider we have a missing
-- operand. If in Ada 2012 and the IF is not properly indented
-- for a statement, we prefer to issue a message about an ill-
- -- parenthesized conditional expression.
+ -- parenthesized if expression.
if Token_Is_At_Start_Of_Line
and then not
@@ -2473,13 +2473,12 @@ package body Ch4 is
Error_Msg_AP ("missing operand");
return Error;
- -- If this looks like a conditional expression, then treat it
- -- that way with an error message.
+ -- If this looks like an if expression, then treat it that way
+ -- with an error message.
elsif Ada_Version >= Ada_2012 then
- Error_Msg_SC
- ("conditional expression must be parenthesized");
- return P_Conditional_Expression;
+ Error_Msg_SC ("if expression must be parenthesized");
+ return P_If_Expression;
-- Otherwise treat as misused identifier
@@ -2706,7 +2705,16 @@ package body Ch4 is
Scan; -- past operator token
+ -- Deal with NOT IN, if previous token was NOT, we must have IN now
+
if Prev_Token = Tok_Not then
+
+ -- Style check, for NOT IN, we require one space between NOT and IN
+
+ if Style_Check and then Token = Tok_In then
+ Style.Check_Not_In;
+ end if;
+
T_In;
end if;
@@ -2965,21 +2973,21 @@ package body Ch4 is
return Case_Alt_Node;
end P_Case_Expression_Alternative;
- ------------------------------
- -- P_Conditional_Expression --
- ------------------------------
+ ---------------------
+ -- P_If_Expression --
+ ---------------------
- function P_Conditional_Expression return Node_Id is
+ function P_If_Expression return Node_Id is
Exprs : constant List_Id := New_List;
Loc : constant Source_Ptr := Token_Ptr;
Expr : Node_Id;
State : Saved_Scan_State;
begin
- Inside_Conditional_Expression := Inside_Conditional_Expression + 1;
+ Inside_If_Expression := Inside_If_Expression + 1;
if Token = Tok_If and then Ada_Version < Ada_2012 then
- Error_Msg_SC ("|conditional expression is an Ada 2012 feature");
+ Error_Msg_SC ("|if expression is an Ada 2012 feature");
Error_Msg_SC ("\|unit must be compiled with -gnat2012 switch");
end if;
@@ -3008,7 +3016,7 @@ package body Ch4 is
-- Scan out ELSIF sequence if present
if Token = Tok_Elsif then
- Expr := P_Conditional_Expression;
+ Expr := P_If_Expression;
Set_Is_Elsif (Expr);
Append_To (Exprs, Expr);
@@ -3030,8 +3038,7 @@ package body Ch4 is
-- If we have an END IF, diagnose as not needed
if Token = Tok_End then
- Error_Msg_SC
- ("`END IF` not allowed at end of conditional expression");
+ Error_Msg_SC ("`END IF` not allowed at end of if expression");
Scan; -- past END
if Token = Tok_If then
@@ -3039,14 +3046,14 @@ package body Ch4 is
end if;
end if;
- Inside_Conditional_Expression := Inside_Conditional_Expression - 1;
+ Inside_If_Expression := Inside_If_Expression - 1;
- -- Return the Conditional_Expression node
+ -- Return the If_Expression node
return
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => Exprs);
- end P_Conditional_Expression;
+ end P_If_Expression;
-----------------------
-- P_Membership_Test --
@@ -3104,18 +3111,16 @@ package body Ch4 is
Result := P_Case_Expression;
if not (Lparen and then Token = Tok_Right_Paren) then
- Error_Msg_N
- ("case expression must be parenthesized!", Result);
+ Error_Msg_N ("case expression must be parenthesized!", Result);
end if;
- -- Conditional expression
+ -- If expression
elsif Token = Tok_If then
- Result := P_Conditional_Expression;
+ Result := P_If_Expression;
if not (Lparen and then Token = Tok_Right_Paren) then
- Error_Msg_N
- ("conditional expression must be parenthesized!", Result);
+ Error_Msg_N ("if expression must be parenthesized!", Result);
end if;
-- Quantified expression
diff --git a/gcc/ada/par-prag.adb b/gcc/ada/par-prag.adb
index e08347648..8b0714245 100644
--- a/gcc/ada/par-prag.adb
+++ b/gcc/ada/par-prag.adb
@@ -1199,6 +1199,7 @@ begin
Pragma_Ordered |
Pragma_Optimize |
Pragma_Optimize_Alignment |
+ Pragma_Overflow_Checks |
Pragma_Pack |
Pragma_Passive |
Pragma_Preelaborable_Initialization |
diff --git a/gcc/ada/par.adb b/gcc/ada/par.adb
index 892aac86b..486c0f3da 100644
--- a/gcc/ada/par.adb
+++ b/gcc/ada/par.adb
@@ -694,17 +694,12 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is
-- keyword, and returns pointing to the terminating right parent,
-- semicolon, or comma, but does not consume this terminating token.
- function P_Conditional_Expression return Node_Id;
- -- Scans out a conditional expression. Called with Token pointing to
- -- the IF keyword, and returns pointing to the terminating right paren,
- -- semicolon or comma, but does not consume this terminating token.
-
function P_Expression_If_OK return Node_Id;
-- Scans out an expression allowing an unparenthesized case expression,
- -- conditional expression, or quantified expression to appear without
- -- enclosing parentheses. However, if such an expression is not preceded
- -- by a left paren, and followed by a right paren, an error message will
- -- be output noting that parenthesization is required.
+ -- if expression, or quantified expression to appear without enclosing
+ -- parentheses. However, if such an expression is not preceded by a left
+ -- paren, and followed by a right paren, an error message will be output
+ -- noting that parenthesization is required.
function P_Expression_No_Right_Paren return Node_Id;
-- Scans out an expression in contexts where the expression cannot be
@@ -718,6 +713,11 @@ function Par (Configuration_Pragmas : Boolean) return List_Id is
-- followed by a right paren, an error message will be output noting
-- that parenthesization is required.
+ function P_If_Expression return Node_Id;
+ -- Scans out an if expression. Called with Token pointing to the
+ -- IF keyword, and returns pointing to the terminating right paren,
+ -- semicolon or comma, but does not consume this terminating token.
+
function P_Qualified_Expression (Subtype_Mark : Node_Id) return Node_Id;
-- This routine scans out a qualified expression when the caller has
-- already scanned out the name and apostrophe of the construct.
diff --git a/gcc/ada/par_sco.adb b/gcc/ada/par_sco.adb
index 78ff71bfd..be258bfb8 100644
--- a/gcc/ada/par_sco.adb
+++ b/gcc/ada/par_sco.adb
@@ -102,6 +102,9 @@ package body Par_SCO is
-- excluding OR and AND) and returns True if so, False otherwise, it does
-- no other processing.
+ function To_Source_Location (S : Source_Ptr) return Source_Location;
+ -- Converts Source_Ptr value to Source_Location (line/col) format
+
procedure Process_Decisions
(N : Node_Id;
T : Character;
@@ -109,9 +112,9 @@ package body Par_SCO is
-- If N is Empty, has no effect. Otherwise scans the tree for the node N,
-- to output any decisions it contains. T is one of IEGPWX (for context of
-- expression: if/exit when/entry guard/pragma/while/expression). If T is
- -- other than X, the node N is the conditional expression involved, and a
- -- decision is always present (at the very least a simple decision is
- -- present at the top level).
+ -- other than X, the node N is the if expression involved, and a decision
+ -- is always present (at the very least a simple decision is present at the
+ -- top level).
procedure Process_Decisions
(L : List_Id;
@@ -138,6 +141,9 @@ package body Par_SCO is
end record;
No_Dominant : constant Dominant_Info := (' ', Empty);
+ procedure Record_Instance (Id : Instance_Id; Inst_Sloc : Source_Ptr);
+ -- Add one entry from the instance table to the corresponding SCO table
+
procedure Traverse_Declarations_Or_Statements
(L : List_Id;
D : Dominant_Info := No_Dominant;
@@ -608,12 +614,15 @@ package body Par_SCO is
-- Case expression
+ -- Really hard to believe this is correct given the special
+ -- handling for if expressions below ???
+
when N_Case_Expression =>
return OK; -- ???
- -- Conditional expression, processed like an if statement
+ -- If expression, processed like an if statement
- when N_Conditional_Expression =>
+ when N_If_Expression =>
declare
Cond : constant Node_Id := First (Expressions (N));
Thnx : constant Node_Id := Next (Cond);
@@ -696,16 +705,37 @@ package body Par_SCO is
Debug_Put_SCOs;
end pscos;
+ ---------------------
+ -- Record_Instance --
+ ---------------------
+
+ procedure Record_Instance (Id : Instance_Id; Inst_Sloc : Source_Ptr) is
+ Inst_Src : constant Source_File_Index :=
+ Get_Source_File_Index (Inst_Sloc);
+ begin
+ SCO_Instance_Table.Append
+ ((Inst_Dep_Num => Dependency_Num (Unit (Inst_Src)),
+ Inst_Loc => To_Source_Location (Inst_Sloc),
+ Enclosing_Instance => SCO_Instance_Index (Instance (Inst_Src))));
+ pragma Assert
+ (SCO_Instance_Table.Last = SCO_Instance_Index (Id));
+ end Record_Instance;
+
----------------
-- SCO_Output --
----------------
procedure SCO_Output is
+ procedure Populate_SCO_Instance_Table is
+ new Sinput.Iterate_On_Instances (Record_Instance);
+
begin
if Debug_Flag_Dot_OO then
dsco;
end if;
+ Populate_SCO_Instance_Table;
+
-- Sort the unit tables based on dependency numbers
Unit_Table_Sort : declare
@@ -949,26 +979,6 @@ package body Par_SCO is
Pragma_Sloc : Source_Ptr := No_Location;
Pragma_Name : Pragma_Id := Unknown_Pragma)
is
- function To_Source_Location (S : Source_Ptr) return Source_Location;
- -- Converts Source_Ptr value to Source_Location (line/col) format
-
- ------------------------
- -- To_Source_Location --
- ------------------------
-
- function To_Source_Location (S : Source_Ptr) return Source_Location is
- begin
- if S = No_Location then
- return No_Source_Location;
- else
- return
- (Line => Get_Logical_Line_Number (S),
- Col => Get_Column_Number (S));
- end if;
- end To_Source_Location;
-
- -- Start of processing for Set_Table_Entry
-
begin
SCO_Table.Append
((C1 => C1,
@@ -980,6 +990,21 @@ package body Par_SCO is
Pragma_Name => Pragma_Name));
end Set_Table_Entry;
+ ------------------------
+ -- To_Source_Location --
+ ------------------------
+
+ function To_Source_Location (S : Source_Ptr) return Source_Location is
+ begin
+ if S = No_Location then
+ return No_Source_Location;
+ else
+ return
+ (Line => Get_Logical_Line_Number (S),
+ Col => Get_Column_Number (S));
+ end if;
+ end To_Source_Location;
+
-----------------------------------------
-- Traverse_Declarations_Or_Statements --
-----------------------------------------
diff --git a/gcc/ada/par_sco.ads b/gcc/ada/par_sco.ads
index a57f5c5b9..62a7467f6 100644
--- a/gcc/ada/par_sco.ads
+++ b/gcc/ada/par_sco.ads
@@ -61,9 +61,9 @@ package Par_SCO is
-- True if Loc is the source location of a disabled pragma
procedure SCO_Output;
- -- Outputs SCO lines for all units, with appropriate section headers, for
- -- unit U in the ALI file, as recorded by previous calls to SCO_Record,
- -- possibly modified by calls to Set_SCO_Condition.
+ -- Outputs SCO lines for all units, with appropriate section headers, as
+ -- recorded by previous calls to SCO_Record, possibly modified by calls to
+ -- Set_SCO_Condition.
procedure dsco;
-- Debug routine to dump internal SCO table. This is a raw format dump
diff --git a/gcc/ada/prep.adb b/gcc/ada/prep.adb
index 2b0e1378b..3ec208792 100644
--- a/gcc/ada/prep.adb
+++ b/gcc/ada/prep.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2002-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 2002-2012, 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- --
@@ -292,8 +292,8 @@ package body Prep is
Result.Value := End_String;
end if;
- -- Now, check the syntax of the symbol (we don't allow accented and
- -- wide characters)
+ -- Now, check the syntax of the symbol (we don't allow accented or
+ -- wide characters).
if Name_Buffer (1) not in 'a' .. 'z'
and then Name_Buffer (1) not in 'A' .. 'Z'
@@ -356,7 +356,7 @@ package body Prep is
begin
-- Always return False when not inside an #if statement
- if Pp_States.Last = Ground then
+ if Opt.No_Deletion or else Pp_States.Last = Ground then
return False;
else
return Pp_States.Table (Pp_States.Last).Deleting;
diff --git a/gcc/ada/prepcomp.adb b/gcc/ada/prepcomp.adb
index 2da21df3c..dd64bcb71 100644
--- a/gcc/ada/prepcomp.adb
+++ b/gcc/ada/prepcomp.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2003-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 2003-2012, 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- --
@@ -60,6 +60,7 @@ package body Prepcomp is
Undef_False : Boolean := False;
Always_Blank : Boolean := False;
Comments : Boolean := False;
+ No_Deletion : Boolean := False;
List_Symbols : Boolean := False;
Processed : Boolean := False;
end record;
@@ -73,6 +74,7 @@ package body Prepcomp is
Undef_False => False,
Always_Blank => False,
Comments => False,
+ No_Deletion => False,
List_Symbols => False,
Processed => False);
@@ -330,6 +332,16 @@ package body Prepcomp is
-- significant.
case Sinput.Source (Token_Ptr) is
+ when 'a' =>
+
+ -- All source text preserved (also implies -u)
+
+ if Name_Len = 1 then
+ Current_Data.No_Deletion := True;
+ Current_Data.Undef_False := True;
+ OK := True;
+ end if;
+
when 'u' =>
-- Undefined symbol are False
@@ -581,15 +593,15 @@ package body Prepcomp is
-- Set the preprocessing flags according to the preprocessing data
- if Current_Data.Comments and then not Current_Data.Always_Blank then
+ if Current_Data.Comments and not Current_Data.Always_Blank then
Comment_Deleted_Lines := True;
Blank_Deleted_Lines := False;
-
else
Comment_Deleted_Lines := False;
Blank_Deleted_Lines := True;
end if;
+ No_Deletion := Current_Data.No_Deletion;
Undefined_Symbols_Are_False := Current_Data.Undef_False;
List_Preprocessing_Symbols := Current_Data.List_Symbols;
diff --git a/gcc/ada/prj-env.adb b/gcc/ada/prj-env.adb
index dac6512ee..ddff02fcb 100644
--- a/gcc/ada/prj-env.adb
+++ b/gcc/ada/prj-env.adb
@@ -2043,8 +2043,7 @@ package body Prj.Env is
-- $prefix/$target/lib/gnat
Add_Str_To_Name_Buffer
- (Path_Separator & Prefix.all &
- Target_Name);
+ (Path_Separator & Prefix.all & Target_Name);
-- Note: Target_Name has a trailing / when it comes from
-- Sdefault.
diff --git a/gcc/ada/prj-part.adb b/gcc/ada/prj-part.adb
index f3650f0b0..f1166afbb 100644
--- a/gcc/ada/prj-part.adb
+++ b/gcc/ada/prj-part.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2012, 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- --
@@ -216,6 +216,7 @@ package body Prj.Part is
procedure Post_Parse_Context_Clause
(Context_Clause : With_Id;
In_Tree : Project_Node_Tree_Ref;
+ In_Limited : Boolean;
Limited_Withs : Boolean;
Imported_Projects : in out Project_Node_Id;
Project_Directory : Path_Name_Type;
@@ -227,10 +228,12 @@ package body Prj.Part is
Env : in out Environment);
-- Parse the imported projects that have been stored in table Withs, if
-- any. From_Extended is used for the call to Parse_Single_Project below.
+ --
-- When In_Limited is True, the importing path includes at least one
-- "limited with". When Limited_Withs is False, only non limited withed
-- projects are parsed. When Limited_Withs is True, only limited withed
-- projects are parsed.
+ --
-- Is_Config_File should be set to True if the project represents a config
-- file (.cgpr) since some specific checks apply.
@@ -636,9 +639,7 @@ package body Prj.Part is
-- Now, check the projects directly imported by the main project.
-- Remove from the potentially virtual any project extended by one
- -- of these imported projects. For non extending imported projects,
- -- check that they do not belong to the project tree of the project
- -- being "extended-all" by the main project.
+ -- of these imported projects.
declare
With_Clause : Project_Node_Id;
@@ -829,6 +830,7 @@ package body Prj.Part is
procedure Post_Parse_Context_Clause
(Context_Clause : With_Id;
In_Tree : Project_Node_Tree_Ref;
+ In_Limited : Boolean;
Limited_Withs : Boolean;
Imported_Projects : in out Project_Node_Id;
Project_Directory : Path_Name_Type;
@@ -943,7 +945,9 @@ package body Prj.Part is
-- If we have one, get the project id of the limited
-- imported project file, and do not parse it.
- if Limited_Withs and then Project_Stack.Last > 1 then
+ if (In_Limited or Limited_Withs)
+ and then Project_Stack.Last > 1
+ then
declare
Canonical_Path_Name : Path_Name_Type;
@@ -967,7 +971,7 @@ package body Prj.Part is
end;
end if;
- -- Parse the imported project, if its project id is unknown
+ -- Parse the imported project if its project id is unknown
if No (Withed_Project) then
Parse_Single_Project
@@ -977,7 +981,7 @@ package body Prj.Part is
Path_Name_Id => Imported_Path_Name_Id,
Extended => False,
From_Extended => From_Extended,
- In_Limited => Limited_Withs,
+ In_Limited => In_Limited or Limited_Withs,
Packages_To_Check => Packages_To_Check,
Depth => Depth,
Current_Dir => Current_Dir,
@@ -1579,6 +1583,7 @@ package body Prj.Part is
Post_Parse_Context_Clause
(In_Tree => In_Tree,
Context_Clause => First_With,
+ In_Limited => In_Limited,
Limited_Withs => False,
Imported_Projects => Imported_Projects,
Project_Directory => Project_Directory,
@@ -1938,6 +1943,7 @@ package body Prj.Part is
Post_Parse_Context_Clause
(In_Tree => In_Tree,
Context_Clause => First_With,
+ In_Limited => In_Limited,
Limited_Withs => True,
Imported_Projects => Imported_Projects,
Project_Directory => Project_Directory,
diff --git a/gcc/ada/prj-proc.adb b/gcc/ada/prj-proc.adb
index 1d5c7738e..cb9d533c7 100644
--- a/gcc/ada/prj-proc.adb
+++ b/gcc/ada/prj-proc.adb
@@ -1588,7 +1588,7 @@ package body Prj.Proc is
Add_Attributes
(Project,
Project.Name,
- Name_Id (Project.Directory.Name),
+ Name_Id (Project.Directory.Display_Name),
Shared,
Shared.Packages.Table (New_Pkg).Decl,
First_Attribute_Of
@@ -2850,7 +2850,7 @@ package body Prj.Proc is
Add_Attributes
(Project,
Name,
- Name_Id (Project.Directory.Name),
+ Name_Id (Project.Directory.Display_Name),
In_Tree.Shared,
Project.Decl,
Prj.Attr.Attribute_First,
diff --git a/gcc/ada/prj-util.adb b/gcc/ada/prj-util.adb
index 1ad1aff58..2c70d1fee 100644
--- a/gcc/ada/prj-util.adb
+++ b/gcc/ada/prj-util.adb
@@ -439,7 +439,7 @@ package body Prj.Util is
-- Local declarations
- Iter : Source_Iterator := For_Each_Source (Tree, Project);
+ Iter : Source_Iterator;
Sid : Source_Id;
ALI : ALI_Id;
@@ -451,6 +451,12 @@ package body Prj.Util is
-- Start of processing for For_Interface_Sources
begin
+ if Project.Qualifier = Aggregate_Library then
+ Iter := For_Each_Source (Tree);
+ else
+ Iter := For_Each_Source (Tree, Project);
+ end if;
+
-- First look at each spec, check if the body is needed
loop
diff --git a/gcc/ada/projects.texi b/gcc/ada/projects.texi
index 2fff4eb1f..fafb1d125 100644
--- a/gcc/ada/projects.texi
+++ b/gcc/ada/projects.texi
@@ -1033,7 +1033,7 @@ names in lower case)
After building an application or a library it is often required to
install it into the development environment. This installation is
required if the library is to be used by another application for
-example. The @code{gprinstall} tool provide an easy way to install
+example. The @command{gprinstall} tool provide an easy way to install
libraries, executable or object code generated durting the build. The
@b{Install} package can be used to change the default locations.
@@ -1963,11 +1963,10 @@ included in the library.
@c ---------------------------------------------
@noindent
-When using project files, library installation is part of the library build
-process. Thus no further action is needed in order to make use of the
-libraries that are built as part of the general application build. A usable
-version of the library is installed in the directory specified by the
-@code{Library_Dir} attribute of the library project file.
+When using project files, a usable version of the library is created in the
+directory specified by the @code{Library_Dir} attribute of the library
+project file. Thus no further action is needed in order to make use of
+the libraries that are built as part of the general application build.
You may want to install a library in a context different from where the library
is built. This situation arises with third party suppliers, who may want
@@ -1976,6 +1975,12 @@ able to recompile the library. The simplest option in this case is to provide
a project file slightly different from the one used to build the library, by
using the @code{externally_built} attribute. @ref{Using Library Projects}
+Another option is to use @command{gprinstall} to install the library in a
+different context than the build location. A project to use this library is
+generated automatically by @command{gprinstall} which also copy, in the install
+location, the minimum set of sources needed to use the library.
+@ref{Installation}
+
@c ---------------------------------------------
@node Project Extension
@section Project Extension
@@ -2243,8 +2248,8 @@ Very often, modules will build their own executables (for testing
purposes for instance), or libraries (for easier reuse in various
contexts).
-However, if you build your project through gnatmake or gprbuild, using
-a syntax similar to
+However, if you build your project through @command{gnatmake} or
+@command{gprbuild}, using a syntax similar to
@smallexample
gprbuild -PA.gpr
@@ -2252,9 +2257,9 @@ a syntax similar to
this will only rebuild the main programs of project A, not those of the
imported projects B and C. Therefore you have to spawn several
-gnatmake commands, one per project, to build all executables.
+@command{gnatmake} commands, one per project, to build all executables.
This is a little inconvenient, but more importantly is inefficient
-because gnatmake needs to do duplicate work to ensure that sources are
+because @command{gnatmake} needs to do duplicate work to ensure that sources are
up-to-date, and cannot easily compile things in parallel when using
the -j switch.
@@ -2295,14 +2300,14 @@ that are built independently from each other (but can be built in
parallel). For instance, you have a project tree rooted at A, and
another one (which might share some subprojects) rooted at B.
-Using only gprbuild, you could do
+Using only @command{gprbuild}, you could do
@smallexample
gprbuild -PA.gpr
gprbuild -PB.gpr
@end smallexample
-to build both. But again, gprbuild has to do some duplicate work for
+to build both. But again, @command{gprbuild} has to do some duplicate work for
those files that are shared between the two, and cannot truly build
things in parallel efficiently.
@@ -2316,7 +2321,7 @@ sources.
This scenario is particularly useful in environments like VxWorks 653
where the applications running in the multiple partitions can be built
-in parallel through a single gprbuild command. This also works nicely
+in parallel through a single @command{gprbuild} command. This also works nicely
with Annex E.
@c ---------------------------------------------
@@ -2324,9 +2329,9 @@ with Annex E.
@subsection Define a build environment
@c ---------------------------------------------
-The environment variables at the time you launch gprbuild or gprbuild
-will influence the view these tools have of the project (PATH to find
-the compiler, ADA_PROJECT_PATH or GPR_PROJECT_PATH to find the
+The environment variables at the time you launch @command{gprbuild} or
+@command{gnatmake} will influence the view these tools have of the project
+(PATH to find the compiler, ADA_PROJECT_PATH or GPR_PROJECT_PATH to find the
projects, environment variables that are referenced in project files
through the "external" statement,...). Several command line switches
can be used to override those (-X or -aP), but on some systems and
@@ -2382,19 +2387,19 @@ end MyProject;
@subsection Performance improvements in builder
@c --------------------------------------------
-The loading of aggregate projects is optimized in gprbuild and
-gnatmake, so that all files are searched for only once on the disk
+The loading of aggregate projects is optimized in @command{gprbuild} and
+@command{gnatmake}, so that all files are searched for only once on the disk
(thus reducing the number of system calls and contributing to faster
compilation times especially on systems with sources on remote
-servers). As part of the loading, gprbuild and gnatmake compute how
-and where a source file should be compiled, and even if it is found
+servers). As part of the loading, @command{gprbuild} and @command{gnatmake}
+compute how and where a source file should be compiled, and even if it is found
several times in the aggregated projects it will be compiled only
once.
Since there is no ambiguity as to which switches should be used, files
can be compiled in parallel (through the usual -j switch) and this can
be done while maximizing the use of CPUs (compared to launching
-multiple gprbuild and gnatmake commands in parallel).
+multiple @command{gprbuild} and @command{gnatmake} commands in parallel).
@c -------------------------------------
@node Syntax of aggregate projects
@@ -2577,15 +2582,15 @@ These override the value given by the attribute, so that
users can override the value set in the (presumably shared
with others in his team) aggregate project.
-@item The -X command line switch to gprbuild and gnatmake
+@item The -X command line switch to @command{gprbuild} and @command{gnatmake}
This always takes precedence.
@end itemize
This attribute is only taken into account in the main aggregate
-project (i.e. the one specified on the command line to gprbuild or
-natmake), and ignored in other aggregate projects. It is invalid
+project (i.e. the one specified on the command line to @command{gprbuild} or
+@command{gnatmake}), and ignored in other aggregate projects. It is invalid
in standard projects.
The goal is to have a consistent value in all
projects that are built through the aggregate, which would not
@@ -2610,8 +2615,8 @@ are valid:
@item @b{Switches}:
@cindex @code{Switches}
This attribute gives the list of switches to use for the builder
-(gprbuild or gnatmake), depending on the language of the main file.
-For instance,
+(@command{gprbuild} or @command{gnatmake}), depending on the language of the
+main file. For instance,
@smallexample @c projectfile
for Switches ("Ada") use ("-d", "-p");
@@ -2995,7 +3000,7 @@ from other project or library project files.
@item @b{library}: a library project must declare both attributes
@code{Library_Name} and @code{Library_Dir}.
@item @b{configuration}: a configuration project cannot be in a project tree.
- It describes compilers and other tools to @code{gprbuild}.
+ It describes compilers and other tools to @command{gprbuild}.
@end table
@c ---------------------------------------------
@@ -3263,7 +3268,7 @@ Here are some specific examples:
@noindent
An external value is an expression whose value is obtained from the command
that invoked the processing of the current project file (typically a
-gnatmake or gprbuild command).
+@command{gnatmake} or @command{gprbuild} command).
There are two kinds of external values, one that returns a single string, and
one that returns a string list.
@@ -3878,11 +3883,12 @@ Follow all symbolic links when processing project files.
@item ^--subdirs^/SUBDIRS^=<subdir>
@cindex @option{^--subdirs^/SUBDIRS^=} (gnatmake and gnatclean)
-This switch is recognized by gnatmake and gnatclean. It indicate that the real
-directories (except the source directories) are the subdirectories <subdir>
-of the directories specified in the project files. This applies in particular
-to object directories, library directories and exec directories. If the
-subdirectories do not exist, they are created automatically.
+This switch is recognized by @command{gnatmake} and @command{gnatclean}. It
+indicate that the real directories (except the source directories) are the
+subdirectories <subdir> of the directories specified in the project files.
+This applies in particular to object directories, library directories and
+exec directories. If the subdirectories do not exist, they are created
+automatically.
@end table
@@ -4592,7 +4598,7 @@ e.g.@: @code{"wtx"} or @code{"vxworks"}.
This is an associative array attribute, whose domain is a language name. Its
value is string that denotes the command to be used to invoke the compiler.
The value of @code{Compiler_Command ("Ada")} is expected to be compatible with
-gnatmake, in particular in the handling of switches.
+@command{gnatmake}, in particular in the handling of switches.
@item Debugger_Command
This is simple attribute, Its value is a string that specifies the name of
diff --git a/gcc/ada/put_scos.adb b/gcc/ada/put_scos.adb
index 39fd04fcc..05184d7a9 100644
--- a/gcc/ada/put_scos.adb
+++ b/gcc/ada/put_scos.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Opt; use Opt;
with Par_SCO; use Par_SCO;
with SCOs; use SCOs;
with Snames; use Snames;
@@ -34,6 +35,9 @@ procedure Put_SCOs is
procedure Write_SCO_Initiate (SU : SCO_Unit_Index);
-- Start SCO line for unit SU, also emitting SCO unit header if necessary
+ procedure Write_Instance_Table;
+ -- Output the SCO table of instances
+
procedure Output_Range (T : SCO_Table_Entry);
-- Outputs T.From and T.To in line:col-line:col format
@@ -76,6 +80,33 @@ procedure Put_SCOs is
end loop;
end Output_String;
+ --------------------------
+ -- Write_Instance_Table --
+ --------------------------
+
+ procedure Write_Instance_Table is
+ begin
+ for J in 1 .. SCO_Instance_Table.Last loop
+ declare
+ SIE : SCO_Instance_Table_Entry
+ renames SCO_Instance_Table.Table (J);
+ begin
+ Output_String ("C i ");
+ Write_Info_Nat (Nat (J));
+ Write_Info_Char (' ');
+ Write_Info_Nat (SIE.Inst_Dep_Num);
+ Write_Info_Char ('|');
+ Output_Source_Location (SIE.Inst_Loc);
+
+ if SIE.Enclosing_Instance > 0 then
+ Write_Info_Char (' ');
+ Write_Info_Nat (Nat (SIE.Enclosing_Instance));
+ end if;
+ Write_Info_Terminate;
+ end;
+ end loop;
+ end Write_Instance_Table;
+
------------------------
-- Write_SCO_Initiate --
------------------------
@@ -270,4 +301,8 @@ begin
end loop;
end;
end loop;
+
+ if Opt.Generate_SCO_Instance_Table then
+ Write_Instance_Table;
+ end if;
end Put_SCOs;
diff --git a/gcc/ada/rtsfind.ads b/gcc/ada/rtsfind.ads
index 05983814a..ee9919a5f 100644
--- a/gcc/ada/rtsfind.ads
+++ b/gcc/ada/rtsfind.ads
@@ -213,6 +213,7 @@ package Rtsfind is
System_Assertions,
System_Atomic_Primitives,
System_Aux_DEC,
+ System_Bignums,
System_Bit_Ops,
System_Boolean_Array_Operations,
System_Byte_Swapping,
@@ -759,6 +760,28 @@ package Rtsfind is
RE_Type_Class_Task, -- System.Aux_DEC
RE_Type_Class_Address, -- System.Aux_DEC
+ RE_Big_Abs, -- System.Bignums
+ RE_Big_Add, -- System.Bignums
+ RE_Big_Div, -- System.Bignums
+ RE_Big_Exp, -- System.Bignums
+ RE_Big_Mod, -- System.Bignums
+ RE_Big_Mul, -- System.Bignums
+ RE_Big_Neg, -- System.Bignums
+ RE_Big_Rem, -- System.Bignums
+ RE_Big_Sub, -- System.Bignums
+
+ RE_Big_EQ, -- System.Bignums
+ RE_Big_GE, -- System.Bignums
+ RE_Big_GT, -- System.Bignums
+ RE_Big_LE, -- System.Bignums
+ RE_Big_LT, -- System.Bignums
+ RE_Big_NE, -- System.Bignums
+
+ RE_Bignum, -- System.Bignums
+ RE_Bignum_In_LLI_Range, -- System.Bignums
+ RE_To_Bignum, -- System.Bignums
+ RE_From_Bignum, -- System.Bignums
+
RE_Bit_And, -- System.Bit_Ops
RE_Bit_Eq, -- System.Bit_Ops
RE_Bit_Not, -- System.Bit_Ops
@@ -783,18 +806,14 @@ package Rtsfind is
RE_Compare_Array_S8_Unaligned, -- System.Compare_Array_Signed_8
RE_Compare_Array_S16, -- System.Compare_Array_Signed_16
-
RE_Compare_Array_S32, -- System.Compare_Array_Signed_16
-
RE_Compare_Array_S64, -- System.Compare_Array_Signed_16
RE_Compare_Array_U8, -- System.Compare_Array_Unsigned_8
RE_Compare_Array_U8_Unaligned, -- System.Compare_Array_Unsigned_8
RE_Compare_Array_U16, -- System.Compare_Array_Unsigned_16
-
RE_Compare_Array_U32, -- System.Compare_Array_Unsigned_16
-
RE_Compare_Array_U64, -- System.Compare_Array_Unsigned_16
RE_Str_Concat_2, -- System.Concat_2
@@ -1985,6 +2004,28 @@ package Rtsfind is
RE_Type_Class_Task => System_Aux_DEC,
RE_Type_Class_Address => System_Aux_DEC,
+ RE_Big_Abs => System_Bignums,
+ RE_Big_Add => System_Bignums,
+ RE_Big_Div => System_Bignums,
+ RE_Big_Exp => System_Bignums,
+ RE_Big_Mod => System_Bignums,
+ RE_Big_Mul => System_Bignums,
+ RE_Big_Neg => System_Bignums,
+ RE_Big_Rem => System_Bignums,
+ RE_Big_Sub => System_Bignums,
+
+ RE_Big_EQ => System_Bignums,
+ RE_Big_GE => System_Bignums,
+ RE_Big_GT => System_Bignums,
+ RE_Big_LE => System_Bignums,
+ RE_Big_LT => System_Bignums,
+ RE_Big_NE => System_Bignums,
+
+ RE_Bignum => System_Bignums,
+ RE_Bignum_In_LLI_Range => System_Bignums,
+ RE_To_Bignum => System_Bignums,
+ RE_From_Bignum => System_Bignums,
+
RE_Bit_And => System_Bit_Ops,
RE_Bit_Eq => System_Bit_Ops,
RE_Bit_Not => System_Bit_Ops,
diff --git a/gcc/ada/s-bignum.adb b/gcc/ada/s-bignum.adb
new file mode 100644
index 000000000..b3af47961
--- /dev/null
+++ b/gcc/ada/s-bignum.adb
@@ -0,0 +1,1067 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . B I G N U M S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 2012, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides arbitrary precision signed integer arithmetic for
+-- use in computing intermediate values in expressions for the case where
+-- pragma Overflow_Check (Eliminate) is in effect.
+
+with System; use System;
+with System.Secondary_Stack; use System.Secondary_Stack;
+with System.Storage_Elements; use System.Storage_Elements;
+
+package body System.Bignums is
+
+ use Interfaces;
+ -- So that operations on Unsigned_32 are available
+
+ type DD is mod Base ** 2;
+ -- Double length digit used for intermediate computations
+
+ function MSD (X : DD) return SD is (SD (X / Base));
+ function LSD (X : DD) return SD is (SD (X mod Base));
+ -- Most significant and least significant digit of double digit value
+
+ function "&" (X, Y : SD) return DD is (DD (X) * Base + DD (Y));
+ -- Compose double digit value from two single digit values
+
+ subtype LLI is Long_Long_Integer;
+
+ One_Data : constant Digit_Vector (1 .. 1) := (1 => 1);
+ -- Constant one
+
+ Zero_Data : constant Digit_Vector (1 .. 0) := (1 .. 0 => 0);
+ -- Constant zero
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ function Add (X, Y : Digit_Vector; X_Neg, Y_Neg : Boolean) return Bignum
+ with Pre => X'First = 1 and then Y'First = 1;
+ -- This procedure adds two signed numbers returning the Sum, it is used
+ -- for both addition and subtraction. The value computed is X + Y, with
+ -- X_Neg and Y_Neg giving the signs of the operands.
+
+ function Allocate_Bignum (Len : Length) return Bignum
+ with Post => Allocate_Bignum'Result.Len = Len;
+ -- Allocate Bignum value of indicated length on secondary stack. On return
+ -- the Neg and D fields are left uninitialized.
+
+ type Compare_Result is (LT, EQ, GT);
+ -- Indicates result of comparison in following call
+
+ function Compare
+ (X, Y : Digit_Vector;
+ X_Neg, Y_Neg : Boolean) return Compare_Result
+ with Pre => X'First = 1 and then Y'First = 1;
+ -- Compare (X with sign X_Neg) with (Y with sign Y_Neg), and return the
+ -- result of the signed comparison.
+
+ procedure Div_Rem
+ (X, Y : Bignum;
+ Quotient : out Bignum;
+ Remainder : out Bignum;
+ Discard_Quotient : Boolean := False;
+ Discard_Remainder : Boolean := False);
+ -- Returns the Quotient and Remainder from dividing abs (X) by abs (Y). The
+ -- values of X and Y are not modified. If Discard_Quotient is True, then
+ -- Quotient is undefined on return, and if Discard_Remainder is True, then
+ -- Remainder is undefined on return. Service routine for Big_Div/Rem/Mod.
+
+ procedure Free_Bignum (X : Bignum) is null;
+ -- Called to free a Bignum value used in intermediate computations. In
+ -- this implementation using the secondary stack, it does nothing at all,
+ -- because we rely on Mark/Release, but it may be of use for some
+ -- alternative implementation.
+
+ function Normalize
+ (X : Digit_Vector;
+ Neg : Boolean := False) return Bignum;
+ -- Given a digit vector and sign, allocate and construct a Bignum value.
+ -- Note that X may have leading zeroes which must be removed, and if the
+ -- result is zero, the sign is forced positive.
+
+ ---------
+ -- Add --
+ ---------
+
+ function Add (X, Y : Digit_Vector; X_Neg, Y_Neg : Boolean) return Bignum is
+ begin
+ -- If signs are the same, we are doing an addition, it is convenient to
+ -- ensure that the first operand is the longer of the two.
+
+ if X_Neg = Y_Neg then
+ if X'Last < Y'Last then
+ return Add (X => Y, Y => X, X_Neg => Y_Neg, Y_Neg => X_Neg);
+
+ -- Here signs are the same, and the first operand is the longer
+
+ else
+ pragma Assert (X_Neg = Y_Neg and then X'Last >= Y'Last);
+
+ -- Do addition, putting result in Sum (allowing for carry)
+
+ declare
+ Sum : Digit_Vector (0 .. X'Last);
+ RD : DD;
+
+ begin
+ RD := 0;
+ for J in reverse 1 .. X'Last loop
+ RD := RD + DD (X (J));
+
+ if J >= 1 + (X'Last - Y'Last) then
+ RD := RD + DD (Y (J - (X'Last - Y'Last)));
+ end if;
+
+ Sum (J) := LSD (RD);
+ RD := RD / Base;
+ end loop;
+
+ Sum (0) := SD (RD);
+ return Normalize (Sum, X_Neg);
+ end;
+ end if;
+
+ -- Signs are different so really this is a subtraction, we want to make
+ -- sure that the largest magnitude operand is the first one, and then
+ -- the result will have the sign of the first operand.
+
+ else
+ declare
+ CR : constant Compare_Result := Compare (X, Y, False, False);
+
+ begin
+ if CR = EQ then
+ return Normalize (Zero_Data);
+
+ elsif CR = LT then
+ return Add (X => Y, Y => X, X_Neg => Y_Neg, Y_Neg => X_Neg);
+
+ else
+ pragma Assert (X_Neg /= Y_Neg and then CR = GT);
+
+ -- Do subtraction, putting result in Diff
+
+ declare
+ Diff : Digit_Vector (1 .. X'Length);
+ RD : DD;
+
+ begin
+ RD := 0;
+ for J in reverse 1 .. X'Last loop
+ RD := RD + DD (X (J));
+
+ if J >= 1 + (X'Last - Y'Last) then
+ RD := RD - DD (Y (J - (X'Last - Y'Last)));
+ end if;
+
+ Diff (J) := LSD (RD);
+ RD := (if RD < Base then 0 else -1);
+ end loop;
+
+ return Normalize (Diff, X_Neg);
+ end;
+ end if;
+ end;
+ end if;
+ end Add;
+
+ ---------------------
+ -- Allocate_Bignum --
+ ---------------------
+
+ function Allocate_Bignum (Len : Length) return Bignum is
+ Addr : Address;
+
+ begin
+ -- Change the if False here to if True to get allocation on the heap
+ -- instead of the secondary stack, which is convenient for debugging
+ -- System.Bignum itself.
+
+ if False then
+ declare
+ B : Bignum;
+ begin
+ B := new Bignum_Data'(Len, False, (others => 0));
+ return B;
+ end;
+
+ -- Normal case of allocation on the secondary stack
+
+ else
+ -- Note: The approach used here is designed to avoid strict aliasing
+ -- warnings that appeared previously using unchecked conversion.
+
+ SS_Allocate (Addr, Storage_Offset (4 + 4 * Len));
+
+ declare
+ B : Bignum;
+ for B'Address use Addr'Address;
+ pragma Import (Ada, B);
+
+ BD : Bignum_Data (Len);
+ for BD'Address use Addr;
+ pragma Import (Ada, BD);
+
+ -- Expose a writable view of discriminant BD.Len so that we can
+ -- initialize it.
+
+ BL : Length;
+ for BL'Address use BD.Len'Address;
+ pragma Import (Ada, BL);
+
+ begin
+ BL := Len;
+ return B;
+ end;
+ end if;
+ end Allocate_Bignum;
+
+ -------------
+ -- Big_Abs --
+ -------------
+
+ function Big_Abs (X : Bignum) return Bignum is
+ begin
+ return Normalize (X.D);
+ end Big_Abs;
+
+ -------------
+ -- Big_Add --
+ -------------
+
+ function Big_Add (X, Y : Bignum) return Bignum is
+ begin
+ return Add (X.D, Y.D, X.Neg, Y.Neg);
+ end Big_Add;
+
+ -------------
+ -- Big_Div --
+ -------------
+
+ -- This table is excerpted from RM 4.5.5(28-30) and shows how the result
+ -- varies with the signs of the operands.
+
+ -- A B A/B A B A/B
+ --
+ -- 10 5 2 -10 5 -2
+ -- 11 5 2 -11 5 -2
+ -- 12 5 2 -12 5 -2
+ -- 13 5 2 -13 5 -2
+ -- 14 5 2 -14 5 -2
+ --
+ -- A B A/B A B A/B
+ --
+ -- 10 -5 -2 -10 -5 2
+ -- 11 -5 -2 -11 -5 2
+ -- 12 -5 -2 -12 -5 2
+ -- 13 -5 -2 -13 -5 2
+ -- 14 -5 -2 -14 -5 2
+
+ function Big_Div (X, Y : Bignum) return Bignum is
+ Q, R : Bignum;
+ begin
+ Div_Rem (X, Y, Q, R, Discard_Remainder => True);
+ Q.Neg := Q.Len > 0 and then (X.Neg xor Y.Neg);
+ return Q;
+ end Big_Div;
+
+ -------------
+ -- Big_Exp --
+ -------------
+
+ function Big_Exp (X, Y : Bignum) return Bignum is
+
+ function "**" (X : Bignum; Y : SD) return Bignum;
+ -- Internal routine where we know right operand is one word
+
+ ----------
+ -- "**" --
+ ----------
+
+ function "**" (X : Bignum; Y : SD) return Bignum is
+ begin
+ case Y is
+
+ -- X ** 0 is 1
+
+ when 0 =>
+ return Normalize (One_Data);
+
+ -- X ** 1 is X
+
+ when 1 =>
+ return Normalize (X.D);
+
+ -- X ** 2 is X * X
+
+ when 2 =>
+ return Big_Mul (X, X);
+
+ -- For X greater than 2, use the recursion
+
+ -- X even, X ** Y = (X ** (Y/2)) ** 2;
+ -- X odd, X ** Y = (X ** (Y/2)) ** 2 * X;
+
+ when others =>
+ declare
+ XY2 : constant Bignum := X ** (Y / 2);
+ XY2S : constant Bignum := Big_Mul (XY2, XY2);
+ Res : Bignum;
+
+ begin
+ Free_Bignum (XY2);
+
+ -- Raise storage error if intermediate value is getting too
+ -- large, which we arbitrarily define as 200 words for now!
+
+ if XY2S.Len > 200 then
+ Free_Bignum (XY2S);
+ raise Storage_Error with
+ "exponentiation result is too large";
+ end if;
+
+ -- Otherwise take care of even/odd cases
+
+ if (Y and 1) = 0 then
+ return XY2S;
+
+ else
+ Res := Big_Mul (XY2S, X);
+ Free_Bignum (XY2S);
+ return Res;
+ end if;
+ end;
+ end case;
+ end "**";
+
+ -- Start of processing for Big_Exp
+
+ begin
+ -- Error if right operand negative
+
+ if Y.Neg then
+ raise Constraint_Error with "exponentiation to negative power";
+
+ -- X ** 0 is always 1 (including 0 ** 0, so do this test first)
+
+ elsif Y.Len = 0 then
+ return Normalize (One_Data);
+
+ -- 0 ** X is always 0 (for X non-zero)
+
+ elsif X.Len = 0 then
+ return Normalize (Zero_Data);
+
+ -- (+1) ** Y = 1
+ -- (-1) ** Y = +/-1 depending on whether Y is even or odd
+
+ elsif X.Len = 1 and then X.D (1) = 1 then
+ return Normalize
+ (X.D, Neg => X.Neg and then ((Y.D (Y.Len) and 1) = 1));
+
+ -- If the absolute value of the base is greater than 1, then the
+ -- exponent must not be bigger than one word, otherwise the result
+ -- is ludicrously large, and we just signal Storage_Error right away.
+
+ elsif Y.Len > 1 then
+ raise Storage_Error with "exponentiation result is too large";
+
+ -- Special case (+/-)2 ** K, where K is 1 .. 31 using a shift
+
+ elsif X.Len = 1 and then X.D (1) = 2 and then Y.D (1) < 32 then
+ declare
+ D : constant Digit_Vector (1 .. 1) :=
+ (1 => Shift_Left (SD'(1), Natural (Y.D (1))));
+ begin
+ return Normalize (D, X.Neg);
+ end;
+
+ -- Remaining cases have right operand of one word
+
+ else
+ return X ** Y.D (1);
+ end if;
+ end Big_Exp;
+
+ ------------
+ -- Big_EQ --
+ ------------
+
+ function Big_EQ (X, Y : Bignum) return Boolean is
+ begin
+ return Compare (X.D, Y.D, X.Neg, Y.Neg) = EQ;
+ end Big_EQ;
+
+ ------------
+ -- Big_GE --
+ ------------
+
+ function Big_GE (X, Y : Bignum) return Boolean is
+ begin
+ return Compare (X.D, Y.D, X.Neg, Y.Neg) /= LT;
+ end Big_GE;
+
+ ------------
+ -- Big_GT --
+ ------------
+
+ function Big_GT (X, Y : Bignum) return Boolean is
+ begin
+ return Compare (X.D, Y.D, X.Neg, Y.Neg) = GT;
+ end Big_GT;
+
+ ------------
+ -- Big_LE --
+ ------------
+
+ function Big_LE (X, Y : Bignum) return Boolean is
+ begin
+ return Compare (X.D, Y.D, X.Neg, Y.Neg) /= GT;
+ end Big_LE;
+
+ ------------
+ -- Big_LT --
+ ------------
+
+ function Big_LT (X, Y : Bignum) return Boolean is
+ begin
+ return Compare (X.D, Y.D, X.Neg, Y.Neg) = LT;
+ end Big_LT;
+
+ -------------
+ -- Big_Mod --
+ -------------
+
+ -- This table is excerpted from RM 4.5.5(28-30) and shows how the result
+ -- of Rem and Mod vary with the signs of the operands.
+
+ -- A B A mod B A rem B A B A mod B A rem B
+
+ -- 10 5 0 0 -10 5 0 0
+ -- 11 5 1 1 -11 5 4 -1
+ -- 12 5 2 2 -12 5 3 -2
+ -- 13 5 3 3 -13 5 2 -3
+ -- 14 5 4 4 -14 5 1 -4
+
+ -- A B A mod B A rem B A B A mod B A rem B
+
+ -- 10 -5 0 0 -10 -5 0 0
+ -- 11 -5 -4 1 -11 -5 -1 -1
+ -- 12 -5 -3 2 -12 -5 -2 -2
+ -- 13 -5 -2 3 -13 -5 -3 -3
+ -- 14 -5 -1 4 -14 -5 -4 -4
+
+ function Big_Mod (X, Y : Bignum) return Bignum is
+ Q, R : Bignum;
+
+ begin
+ -- If signs are same, result is same as Rem
+
+ if X.Neg = Y.Neg then
+ return Big_Rem (X, Y);
+
+ -- Case where Mod is different
+
+ else
+ -- Do division
+
+ Div_Rem (X, Y, Q, R, Discard_Quotient => True);
+
+ -- Zero result is unchanged
+
+ if R.Len = 0 then
+ return R;
+
+ -- Otherwise adjust result
+
+ else
+ declare
+ T1 : constant Bignum := Big_Sub (Y, R);
+ begin
+ T1.Neg := Y.Neg;
+ Free_Bignum (R);
+ return T1;
+ end;
+ end if;
+ end if;
+ end Big_Mod;
+
+ -------------
+ -- Big_Mul --
+ -------------
+
+ function Big_Mul (X, Y : Bignum) return Bignum is
+ Result : Digit_Vector (1 .. X.Len + Y.Len) := (others => 0);
+ -- Accumulate result (max length of result is sum of operand lengths)
+
+ L : Length;
+ -- Current result digit
+
+ D : DD;
+ -- Result digit
+
+ begin
+ for J in 1 .. X.Len loop
+ for K in 1 .. Y.Len loop
+ L := Result'Last - (X.Len - J) - (Y.Len - K);
+ D := DD (X.D (J)) * DD (Y.D (K)) + DD (Result (L));
+ Result (L) := LSD (D);
+ D := D / Base;
+
+ -- D is carry which must be propagated
+
+ while D /= 0 and then L >= 1 loop
+ L := L - 1;
+ D := D + DD (Result (L));
+ Result (L) := LSD (D);
+ D := D / Base;
+ end loop;
+
+ -- Must not have a carry trying to extend max length
+
+ pragma Assert (D = 0);
+ end loop;
+ end loop;
+
+ -- Return result
+
+ return Normalize (Result, X.Neg xor Y.Neg);
+ end Big_Mul;
+
+ ------------
+ -- Big_NE --
+ ------------
+
+ function Big_NE (X, Y : Bignum) return Boolean is
+ begin
+ return Compare (X.D, Y.D, X.Neg, Y.Neg) /= EQ;
+ end Big_NE;
+
+ -------------
+ -- Big_Neg --
+ -------------
+
+ function Big_Neg (X : Bignum) return Bignum is
+ begin
+ return Normalize (X.D, not X.Neg);
+ end Big_Neg;
+
+ -------------
+ -- Big_Rem --
+ -------------
+
+ -- This table is excerpted from RM 4.5.5(28-30) and shows how the result
+ -- varies with the signs of the operands.
+
+ -- A B A rem B A B A rem B
+
+ -- 10 5 0 -10 5 0
+ -- 11 5 1 -11 5 -1
+ -- 12 5 2 -12 5 -2
+ -- 13 5 3 -13 5 -3
+ -- 14 5 4 -14 5 -4
+
+ -- A B A rem B A B A rem B
+
+ -- 10 -5 0 -10 -5 0
+ -- 11 -5 1 -11 -5 -1
+ -- 12 -5 2 -12 -5 -2
+ -- 13 -5 3 -13 -5 -3
+ -- 14 -5 4 -14 -5 -4
+
+ function Big_Rem (X, Y : Bignum) return Bignum is
+ Q, R : Bignum;
+ begin
+ Div_Rem (X, Y, Q, R, Discard_Quotient => True);
+ R.Neg := R.Len > 0 and then X.Neg;
+ return R;
+ end Big_Rem;
+
+ -------------
+ -- Big_Sub --
+ -------------
+
+ function Big_Sub (X, Y : Bignum) return Bignum is
+ begin
+ -- If right operand zero, return left operand (avoiding sharing)
+
+ if Y.Len = 0 then
+ return Normalize (X.D, X.Neg);
+
+ -- Otherwise add negative of right operand
+
+ else
+ return Add (X.D, Y.D, X.Neg, not Y.Neg);
+ end if;
+ end Big_Sub;
+
+ -------------
+ -- Compare --
+ -------------
+
+ function Compare
+ (X, Y : Digit_Vector;
+ X_Neg, Y_Neg : Boolean) return Compare_Result
+ is
+ begin
+ -- Signs are different, that's decisive, since 0 is always plus
+
+ if X_Neg /= Y_Neg then
+ return (if X_Neg then LT else GT);
+
+ -- Lengths are different, that's decisive since no leading zeroes
+
+ elsif X'Last /= Y'Last then
+ return (if (X'Last > Y'Last) xor X_Neg then GT else LT);
+
+ -- Need to compare data
+
+ else
+ for J in X'Range loop
+ if X (J) /= Y (J) then
+ return (if (X (J) > Y (J)) xor X_Neg then GT else LT);
+ end if;
+ end loop;
+
+ return EQ;
+ end if;
+ end Compare;
+
+ -------------
+ -- Div_Rem --
+ -------------
+
+ procedure Div_Rem
+ (X, Y : Bignum;
+ Quotient : out Bignum;
+ Remainder : out Bignum;
+ Discard_Quotient : Boolean := False;
+ Discard_Remainder : Boolean := False)
+ is
+ begin
+ -- Error if division by zero
+
+ if Y.Len = 0 then
+ raise Constraint_Error with "division by zero";
+ end if;
+
+ -- Handle simple cases with special tests
+
+ -- If X < Y then quotient is zero and remainder is X
+
+ if Compare (X.D, Y.D, False, False) = LT then
+ Remainder := Normalize (X.D);
+ Quotient := Normalize (Zero_Data);
+ return;
+
+ -- If both X and Y are less than 2**63-1, we can use Long_Long_Integer
+ -- arithmetic. Note it is good not to do an accurate range check against
+ -- Long_Long_Integer since -2**63 / -1 overflows!
+
+ elsif (X.Len <= 1 or else (X.Len = 2 and then X.D (1) < 2**31))
+ and then
+ (Y.Len <= 1 or else (Y.Len = 2 and then Y.D (1) < 2**31))
+ then
+ declare
+ A : constant LLI := abs (From_Bignum (X));
+ B : constant LLI := abs (From_Bignum (Y));
+ begin
+ Quotient := To_Bignum (A / B);
+ Remainder := To_Bignum (A rem B);
+ return;
+ end;
+
+ -- Easy case if divisor is one digit
+
+ elsif Y.Len = 1 then
+ declare
+ ND : DD;
+ Div : constant DD := DD (Y.D (1));
+
+ Result : Digit_Vector (1 .. X.Len);
+ Remdr : Digit_Vector (1 .. 1);
+
+ begin
+ ND := 0;
+ for J in 1 .. X.Len loop
+ ND := Base * ND + DD (X.D (J));
+ Result (J) := SD (ND / Div);
+ ND := ND rem Div;
+ end loop;
+
+ Quotient := Normalize (Result);
+ Remdr (1) := SD (ND);
+ Remainder := Normalize (Remdr);
+ return;
+ end;
+ end if;
+
+ -- The complex full multi-precision case. We will employ algorithm
+ -- D defined in the section "The Classical Algorithms" (sec. 4.3.1)
+ -- of Donald Knuth's "The Art of Computer Programming", Vol. 2. The
+ -- terminology is adjusted for this section to match that reference.
+
+ -- We are dividing X.Len digits of X (called u here) by Y.Len digits
+ -- of Y (called v here), developing the quotient and remainder. The
+ -- numbers are represented using Base, which was chosen so that we have
+ -- the operations of multiplying to single digits (SD) to form a double
+ -- digit (DD), and dividing a double digit (DD) by a single digit (SD)
+ -- to give a single digit quotient and a single digit remainder.
+
+ -- Algorithm D from Knuth
+
+ -- Comments here with square brackets are directly from Knuth
+
+ Algorithm_D : declare
+
+ -- The following lower case variables correspond exactly to the
+ -- terminology used in algorithm D.
+
+ m : constant Length := X.Len - Y.Len;
+ n : constant Length := Y.Len;
+ b : constant DD := Base;
+
+ u : Digit_Vector (0 .. m + n);
+ v : Digit_Vector (1 .. n);
+ q : Digit_Vector (0 .. m);
+ r : Digit_Vector (1 .. n);
+
+ u0 : SD renames u (0);
+ v1 : SD renames v (1);
+ v2 : SD renames v (2);
+
+ d : DD;
+ j : Length;
+ qhat : SD;
+
+ begin
+ -- Initialize data of left and right operands
+
+ for J in 1 .. m + n loop
+ u (J) := X.D (J);
+ end loop;
+
+ for J in 1 .. n loop
+ v (J) := Y.D (J);
+ end loop;
+
+ -- [Division of nonnegative integers]. Given nonnegative integers u
+ -- = (ul,u2..um+n) and v = (v1,v2..vn), where v1 /= 0 and n > 1, we
+ -- form the quotient u / v = (q0,ql..qm) and the remainder u mod v =
+ -- (r1,r2..rn).
+
+ pragma Assert (v (1) /= 0);
+ pragma Assert (n > 1);
+
+ -- Dl. [Normalize.] Set d = b/(vl + 1). Then set (u0,u1,u2..um+n)
+ -- equal to (u1,u2..um+n) times d, and set (v1,v2..vn) equal to
+ -- (v1,v2..vn) times d. Note the introduction of a new digit position
+ -- u0 at the left of u1; if d = 1 all we need to do in this step is
+ -- to set u0 = 0.
+
+ d := b / DD (v1 + 1);
+
+ if d = 1 then
+ u0 := 0;
+
+ else
+ declare
+ Carry : DD;
+ Tmp : DD;
+
+ begin
+ -- Multiply Dividend (u) by d
+
+ Carry := 0;
+ for J in reverse 1 .. m + n loop
+ Tmp := DD (u (J)) * d + Carry;
+ u (J) := LSD (Tmp);
+ Carry := Tmp / Base;
+ end loop;
+
+ u0 := SD (Carry);
+
+ -- Multiply Divisor (v) by d
+
+ Carry := 0;
+ for J in reverse 1 .. n loop
+ Tmp := DD (v (J)) * d + Carry;
+ v (J) := LSD (Tmp);
+ Carry := Tmp / Base;
+ end loop;
+
+ pragma Assert (Carry = 0);
+ end;
+ end if;
+
+ -- D2. [Initialize j.] Set j = 0. The loop on j, steps D2 through D7,
+ -- will be essentially a division of (uj, uj+1..uj+n) by (v1,v2..vn)
+ -- to get a single quotient digit qj;
+
+ j := 0;
+
+ -- Loop through digits
+
+ loop
+ -- D3. [Calculate qhat] If uj = v1, set qhat to b-l; otherwise set
+ -- qhat to (uj,uj+1)/v1.
+
+ if u (j) = v1 then
+ qhat := -1;
+ else
+ qhat := SD ((u (j) & u (j + 1)) / DD (v1));
+ end if;
+
+ -- D3 (continued). Now test if v2 * qhat is greater than (uj*b +
+ -- uj+1 - qhat*v1)*b + uj+2. If so, decrease qhat by 1 and repeat
+ -- this test, which determines at high speed most of the cases in
+ -- which the trial value qhat is one too large, and it eliminates
+ -- all cases where qhat is two too large.
+
+ while DD (v2) * DD (qhat) >
+ ((u (j) & u (j + 1)) -
+ DD (qhat) * DD (v1)) * b + DD (u (j + 2))
+ loop
+ qhat := qhat - 1;
+ end loop;
+
+ -- D4. [Multiply and subtract.] Replace (uj,uj+1..uj+n) by
+ -- (uj,uj+1..uj+n) minus qhat times (v1,v2..vn). This step
+ -- consists of a simple multiplication by a one-place number,
+ -- combined with a subtraction.
+
+ -- The digits (uj,uj+1..uj+n) are always kept positive; if the
+ -- result of this step is actually negative then (uj,uj+1..uj+n)
+ -- is left as the true value plus b**(n+1), i.e. as the b's
+ -- complement of the true value, and a "borrow" to the left is
+ -- remembered.
+
+ declare
+ Borrow : SD;
+ Carry : DD;
+ Temp : DD;
+
+ Negative : Boolean;
+ -- Records if subtraction causes a negative result, requiring
+ -- an add back (case where qhat turned out to be 1 too large).
+
+ begin
+ Borrow := 0;
+ for K in reverse 1 .. n loop
+ Temp := DD (qhat) * DD (v (K)) + DD (Borrow);
+ Borrow := MSD (Temp);
+
+ if LSD (Temp) > u (j + K) then
+ Borrow := Borrow + 1;
+ end if;
+
+ u (j + K) := u (j + K) - LSD (Temp);
+ end loop;
+
+ Negative := u (j) < Borrow;
+ u (j) := u (j) - Borrow;
+
+ -- D5. [Test remainder.] Set qj = qhat. If the result of step
+ -- D4 was negative, we will do the add back step (step D6).
+
+ q (j) := qhat;
+
+ if Negative then
+
+ -- D6. [Add back.] Decrease qj by 1, and add (0,v1,v2..vn)
+ -- to (uj,uj+1,uj+2..uj+n). (A carry will occur to the left
+ -- of uj, and it is be ignored since it cancels with the
+ -- borrow that occurred in D4.)
+
+ q (j) := q (j) - 1;
+
+ Carry := 0;
+ for K in reverse 1 .. n loop
+ Temp := DD (v (K)) + DD (u (j + K)) + Carry;
+ u (j + K) := LSD (Temp);
+ Carry := Temp / Base;
+ end loop;
+
+ u (j) := u (j) + SD (Carry);
+ end if;
+ end;
+
+ -- D7. [Loop on j.] Increase j by one. Now if j <= m, go back to
+ -- D3 (the start of the loop on j).
+
+ j := j + 1;
+ exit when not (j <= m);
+ end loop;
+
+ -- D8. [Unnormalize.] Now (qo,ql..qm) is the desired quotient, and
+ -- the desired remainder may be obtained by dividing (um+1..um+n)
+ -- by d.
+
+ if not Discard_Quotient then
+ Quotient := Normalize (q);
+ end if;
+
+ if not Discard_Remainder then
+ declare
+ Remdr : DD;
+
+ begin
+ Remdr := 0;
+ for K in 1 .. n loop
+ Remdr := Base * Remdr + DD (u (m + K));
+ r (K) := SD (Remdr / d);
+ Remdr := Remdr rem d;
+ end loop;
+
+ pragma Assert (Remdr = 0);
+ end;
+
+ Remainder := Normalize (r);
+ end if;
+ end Algorithm_D;
+ end Div_Rem;
+
+ -----------------
+ -- From_Bignum --
+ -----------------
+
+ function From_Bignum (X : Bignum) return Long_Long_Integer is
+ begin
+ if X.Len = 0 then
+ return 0;
+
+ elsif X.Len = 1 then
+ return (if X.Neg then -LLI (X.D (1)) else LLI (X.D (1)));
+
+ elsif X.Len = 2 then
+ declare
+ Mag : constant DD := X.D (1) & X.D (2);
+ begin
+ if X.Neg and then Mag <= 2 ** 63 then
+ return -LLI (Mag);
+ elsif Mag < 2 ** 63 then
+ return LLI (Mag);
+ end if;
+ end;
+ end if;
+
+ raise Constraint_Error with "expression value out of range";
+ end From_Bignum;
+
+ -------------------------
+ -- Bignum_In_LLI_Range --
+ -------------------------
+
+ function Bignum_In_LLI_Range (X : Bignum) return Boolean is
+ begin
+ -- If length is 0 or 1, definitely fits
+
+ if X.Len <= 1 then
+ return True;
+
+ -- If length is greater than 2, definitely does not fit
+
+ elsif X.Len > 2 then
+ return False;
+
+ -- Length is 2, more tests needed
+
+ else
+ declare
+ Mag : constant DD := X.D (1) & X.D (2);
+ begin
+ return Mag < 2 ** 63 or else (X.Neg and then Mag = 2 ** 63);
+ end;
+ end if;
+ end Bignum_In_LLI_Range;
+
+ ---------------
+ -- Normalize --
+ ---------------
+
+ function Normalize
+ (X : Digit_Vector;
+ Neg : Boolean := False) return Bignum
+ is
+ B : Bignum;
+ J : Length;
+
+ begin
+ J := X'First;
+ while J <= X'Last and then X (J) = 0 loop
+ J := J + 1;
+ end loop;
+
+ B := Allocate_Bignum (X'Last - J + 1);
+ B.Neg := B.Len > 0 and then Neg;
+ B.D := X (J .. X'Last);
+ return B;
+ end Normalize;
+
+ ---------------
+ -- To_Bignum --
+ ---------------
+
+ function To_Bignum (X : Long_Long_Integer) return Bignum is
+ R : Bignum;
+
+ begin
+ if X = 0 then
+ R := Allocate_Bignum (0);
+
+ -- One word result
+
+ elsif X in -(2 ** 32 - 1) .. +(2 ** 32 - 1) then
+ R := Allocate_Bignum (1);
+ R.D (1) := SD (abs (X));
+
+ -- Largest negative number annoyance
+
+ elsif X = Long_Long_Integer'First then
+ R := Allocate_Bignum (2);
+ R.D (1) := 2 ** 31;
+ R.D (2) := 0;
+
+ -- Normal two word case
+
+ else
+ R := Allocate_Bignum (2);
+ R.D (2) := SD (abs (X) mod Base);
+ R.D (1) := SD (abs (X) / Base);
+ end if;
+
+ R.Neg := X < 0;
+ return R;
+ end To_Bignum;
+
+end System.Bignums;
diff --git a/gcc/ada/s-bignum.ads b/gcc/ada/s-bignum.ads
new file mode 100644
index 000000000..7cc752688
--- /dev/null
+++ b/gcc/ada/s-bignum.ads
@@ -0,0 +1,116 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- S Y S T E M . B I G N U M S --
+-- --
+-- S p e c --
+-- --
+-- Copyright (C) 2012, Free Software Foundation, Inc. --
+-- --
+-- GNAT is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNAT was originally developed by the GNAT team at New York University. --
+-- Extensive contributions were provided by Ada Core Technologies Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides arbitrary precision signed integer arithmetic for
+-- use in computing intermediate values in expressions for the case where
+-- pragma Overflow_Check (Eliminated) is in effect.
+
+with Interfaces;
+
+package System.Bignums is
+
+ pragma Assert (Long_Long_Integer'Size = 64);
+ -- This package assumes that Long_Long_Integer size is 64 bit (i.e. that it
+ -- has a range of -2**63 to 2**63-1). The front end ensures that the mode
+ -- ELIMINATED is not allowed for overflow checking if this is not the case.
+
+ subtype Length is Natural range 0 .. 2 ** 23 - 1;
+ -- Represent number of words in Digit_Vector
+
+ Base : constant := 2 ** 32;
+ -- Digit vectors use this base
+
+ subtype SD is Interfaces.Unsigned_32;
+ -- Single length digit
+
+ type Digit_Vector is array (Length range <>) of SD;
+ -- Represent digits of a number (most significant digit first)
+
+ type Bignum_Data (Len : Length) is record
+ Neg : Boolean;
+ -- Set if value is negative, never set for zero
+
+ D : Digit_Vector (1 .. Len);
+ -- Digits of number, most significant first, represented in base
+ -- 2**Base. No leading zeroes are stored, and the value of zero is
+ -- represented using an empty vector for D.
+ end record;
+
+ for Bignum_Data use record
+ Len at 0 range 0 .. 23;
+ Neg at 3 range 0 .. 7;
+ end record;
+
+ type Bignum is access all Bignum_Data;
+ -- This is the type that is used externally. Possibly this could be a
+ -- private type, but we leave the structure exposed for now. For one
+ -- thing it helps with debugging. Note that this package never shares
+ -- an allocated Bignum value, so for example for X + 0, a copy of X is
+ -- returned, not X itself.
+
+ -- Note: none of the subprograms in this package modify the Bignum_Data
+ -- records referenced by Bignum arguments of mode IN.
+
+ function Big_Add (X, Y : Bignum) return Bignum; -- "+"
+ function Big_Sub (X, Y : Bignum) return Bignum; -- "-"
+ function Big_Mul (X, Y : Bignum) return Bignum; -- "*"
+ function Big_Div (X, Y : Bignum) return Bignum; -- "/"
+ function Big_Exp (X, Y : Bignum) return Bignum; -- "**"
+ function Big_Mod (X, Y : Bignum) return Bignum; -- "mod"
+ function Big_Rem (X, Y : Bignum) return Bignum; -- "rem"
+ function Big_Neg (X : Bignum) return Bignum; -- "-"
+ function Big_Abs (X : Bignum) return Bignum; -- "abs"
+ -- Perform indicated arithmetic operation on bignum values. No exception
+ -- raised except for Div/Mod/Rem by 0 which raises Constraint_Error with
+ -- an appropriate message.
+
+ function Big_EQ (X, Y : Bignum) return Boolean; -- "="
+ function Big_NE (X, Y : Bignum) return Boolean; -- "/="
+ function Big_GE (X, Y : Bignum) return Boolean; -- ">="
+ function Big_LE (X, Y : Bignum) return Boolean; -- "<="
+ function Big_GT (X, Y : Bignum) return Boolean; -- ">"
+ function Big_LT (X, Y : Bignum) return Boolean; -- "<"
+ -- Perform indicated comparison on bignums, returning result as Boolean.
+ -- No exception raised for any input arguments.
+
+ function Bignum_In_LLI_Range (X : Bignum) return Boolean;
+ -- Returns True if the Bignum value is in the range of Long_Long_Integer,
+ -- so that a call to From_Bignum is guaranteed not to raise an exception.
+
+ function To_Bignum (X : Long_Long_Integer) return Bignum;
+ -- Convert Long_Long_Integer to Bignum. No exception can be raised for any
+ -- input argument.
+
+ function From_Bignum (X : Bignum) return Long_Long_Integer;
+ -- Convert Bignum to Long_Long_Integer. Constraint_Error raised with
+ -- appropriate message if value is out of range of Long_Long_Integer.
+
+end System.Bignums;
diff --git a/gcc/ada/s-dimmks.ads b/gcc/ada/s-dimmks.ads
index fd0fc0060..fa0c6e035 100644
--- a/gcc/ada/s-dimmks.ads
+++ b/gcc/ada/s-dimmks.ads
@@ -103,6 +103,9 @@ package System.Dim.Mks is
-- SI Base units
+ pragma Warnings (Off);
+ -- Turn off the all the dimension warnings
+
m : constant Length := 1.0;
kg : constant Mass := 1.0;
s : constant Time := 1.0;
@@ -111,98 +114,134 @@ package System.Dim.Mks is
mol : constant Amount_Of_Substance := 1.0;
cd : constant Luminous_Intensity := 1.0;
+ pragma Warnings (On);
+
-- SI Derived dimensioned subtypes
+ subtype Absorbed_Dose is Mks_Type
+ with
+ Dimension => (Symbol => "Gy",
+ Meter => 2,
+ Second => -2,
+ others => 0);
+
subtype Angle is Mks_Type
with
Dimension => (Symbol => "rad",
others => 0);
- subtype Solid_Angle is Mks_Type
+ subtype Area is Mks_Type
with
- Dimension => (Symbol => "sr",
+ Dimension => (
+ Meter => 2,
others => 0);
- subtype Frequency is Mks_Type
+ subtype Catalytic_Activity is Mks_Type
with
- Dimension => (Symbol => "Hz",
+ Dimension => (Symbol => "kat",
Second => -1,
+ Mole => 1,
others => 0);
- subtype Force is Mks_Type
+ subtype Celsius_Temperature is Mks_Type
with
- Dimension => (Symbol => 'N',
- Meter => 1,
- Kilogram => 1,
- Second => -2,
+ Dimension => (Symbol => "°C",
+ Kelvin => 1,
+ others => 0);
+
+ subtype Electric_Capacitance is Mks_Type
+ with
+ Dimension => (Symbol => 'F',
+ Meter => -2,
+ Kilogram => -1,
+ Second => 4,
+ Ampere => 2,
others => 0);
- subtype Pressure is Mks_Type
+ subtype Electric_Charge is Mks_Type
with
- Dimension => (Symbol => "Pa",
- Meter => -1,
- Kilogram => 1,
- Second => -2,
+ Dimension => (Symbol => 'C',
+ Second => 1,
+ Ampere => 1,
+ others => 0);
+
+ subtype Electric_Conductance is Mks_Type
+ with
+ Dimension => (Symbol => 'S',
+ Meter => -2,
+ Kilogram => -1,
+ Second => 3,
+ Ampere => 2,
others => 0);
- subtype Energy is Mks_Type
+ subtype Electric_Potential_Difference is Mks_Type
with
- Dimension => (Symbol => 'J',
+ Dimension => (Symbol => 'V',
Meter => 2,
Kilogram => 1,
- Second => -2,
+ Second => -3,
+ Ampere => -1,
others => 0);
- subtype Power is Mks_Type
+ subtype Electric_Resistance is Mks_Type
with
- Dimension => (Symbol => 'W',
+ Dimension => (Symbol => "Ω",
Meter => 2,
Kilogram => 1,
Second => -3,
+ Ampere => -2,
others => 0);
- subtype Electric_Charge is Mks_Type
+ subtype Energy is Mks_Type
with
- Dimension => (Symbol => 'C',
- Second => 1,
- Ampere => 1,
+ Dimension => (Symbol => 'J',
+ Meter => 2,
+ Kilogram => 1,
+ Second => -2,
+ others => 0);
+
+ subtype Equivalent_Dose is Mks_Type
+ with
+ Dimension => (Symbol => "Sv",
+ Meter => 2,
+ Second => -2,
others => 0);
- subtype Electric_Potential_Difference is Mks_Type
+ subtype Force is Mks_Type
with
- Dimension => (Symbol => 'V',
- Meter => 2,
+ Dimension => (Symbol => 'N',
+ Meter => 1,
Kilogram => 1,
- Second => -3,
- Ampere => -1,
+ Second => -2,
others => 0);
- subtype Electric_Capacitance is Mks_Type
+ subtype Frequency is Mks_Type
with
- Dimension => (Symbol => 'F',
- Meter => -2,
- Kilogram => -1,
- Second => 4,
- Ampere => 2,
- others => 0);
+ Dimension => (Symbol => "Hz",
+ Second => -1,
+ others => 0);
- subtype Electric_Resistance is Mks_Type
+ subtype Illuminance is Mks_Type
with
- Dimension => (Symbol => "Ω",
+ Dimension => (Symbol => "lx",
+ Meter => -2,
+ Candela => 1,
+ others => 0);
+
+ subtype Inductance is Mks_Type
+ with
+ Dimension => (Symbol => 'H',
Meter => 2,
Kilogram => 1,
- Second => -3,
+ Second => -2,
Ampere => -2,
others => 0);
- subtype Electric_Conductance is Mks_Type
+ subtype Luminous_Flux is Mks_Type
with
- Dimension => (Symbol => 'S',
- Meter => -2,
- Kilogram => -1,
- Second => 3,
- Ampere => 2,
- others => 0);
+ Dimension => (Symbol => "lm",
+ Candela => 1,
+ others => 0);
subtype Magnetic_Flux is Mks_Type
with
@@ -221,33 +260,21 @@ package System.Dim.Mks is
Ampere => -1,
others => 0);
- subtype Inductance is Mks_Type
+ subtype Power is Mks_Type
with
- Dimension => (Symbol => 'H',
+ Dimension => (Symbol => 'W',
Meter => 2,
Kilogram => 1,
- Second => -2,
- Ampere => -2,
+ Second => -3,
others => 0);
- subtype Celsius_Temperature is Mks_Type
- with
- Dimension => (Symbol => "°C",
- Kelvin => 1,
- others => 0);
-
- subtype Luminous_Flux is Mks_Type
- with
- Dimension => (Symbol => "lm",
- Candela => 1,
- others => 0);
-
- subtype Illuminance is Mks_Type
+ subtype Pressure is Mks_Type
with
- Dimension => (Symbol => "lx",
- Meter => -2,
- Candela => 1,
- others => 0);
+ Dimension => (Symbol => "Pa",
+ Meter => -1,
+ Kilogram => 1,
+ Second => -2,
+ others => 0);
subtype Radioactivity is Mks_Type
with
@@ -255,27 +282,27 @@ package System.Dim.Mks is
Second => -1,
others => 0);
- subtype Absorbed_Dose is Mks_Type
+ subtype Solid_Angle is Mks_Type
with
- Dimension => (Symbol => "Gy",
- Meter => 2,
- Second => -2,
+ Dimension => (Symbol => "sr",
others => 0);
- subtype Equivalent_Dose is Mks_Type
+ subtype Speed is Mks_Type
with
- Dimension => (Symbol => "Sv",
- Meter => 2,
- Second => -2,
+ Dimension => (
+ Meter => 1,
+ Second => -1,
others => 0);
- subtype Catalytic_Activity is Mks_Type
+ subtype Volume is Mks_Type
with
- Dimension => (Symbol => "kat",
- Second => -1,
- Mole => 1,
+ Dimension => (
+ Meter => 3,
others => 0);
+ pragma Warnings (Off);
+ -- Turn off the all the dimension warnings
+
rad : constant Angle := 1.0;
sr : constant Solid_Angle := 1.0;
Hz : constant Frequency := 1.0;
@@ -349,4 +376,5 @@ package System.Dim.Mks is
kA : constant Electric_Current := 1.0E+03; -- kilo
MeA : constant Electric_Current := 1.0E+06; -- mega
+ pragma Warnings (On);
end System.Dim.Mks;
diff --git a/gcc/ada/s-dmotpr.ads b/gcc/ada/s-dmotpr.ads
index 78bc57ee3..902341c59 100644
--- a/gcc/ada/s-dmotpr.ads
+++ b/gcc/ada/s-dmotpr.ads
@@ -38,6 +38,9 @@ package System.Dim.Mks.Other_Prefixes is
-- SI prefixes for Meter
+ pragma Warnings (Off);
+ -- Turn off the all the dimension warnings
+
ym : constant Length := 1.0E-24; -- yocto
zm : constant Length := 1.0E-21; -- zepto
am : constant Length := 1.0E-18; -- atto
@@ -165,4 +168,5 @@ package System.Dim.Mks.Other_Prefixes is
Zecd : constant Luminous_Intensity := 1.0E+21; -- zetta
Yocd : constant Luminous_Intensity := 1.0E+24; -- yotta
+ pragma Warnings (On);
end System.Dim.Mks.Other_Prefixes;
diff --git a/gcc/ada/s-exnllf.adb b/gcc/ada/s-exnllf.adb
index a1e59c179..c6765e8fe 100644
--- a/gcc/ada/s-exnllf.adb
+++ b/gcc/ada/s-exnllf.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2009 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -37,8 +37,7 @@ package body System.Exn_LLF is
function Exn_Long_Long_Float
(Left : Long_Long_Float;
- Right : Integer)
- return Long_Long_Float
+ Right : Integer) return Long_Long_Float
is
Result : Long_Long_Float := 1.0;
Factor : Long_Long_Float := Left;
diff --git a/gcc/ada/s-exnllf.ads b/gcc/ada/s-exnllf.ads
index 59575b0e0..ba2828277 100644
--- a/gcc/ada/s-exnllf.ads
+++ b/gcc/ada/s-exnllf.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2009 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -36,7 +36,6 @@ package System.Exn_LLF is
function Exn_Long_Long_Float
(Left : Long_Long_Float;
- Right : Integer)
- return Long_Long_Float;
+ Right : Integer) return Long_Long_Float;
end System.Exn_LLF;
diff --git a/gcc/ada/s-gearop.adb b/gcc/ada/s-gearop.adb
index e1ce7e5d5..f84280ee8 100644
--- a/gcc/ada/s-gearop.adb
+++ b/gcc/ada/s-gearop.adb
@@ -902,7 +902,7 @@ package body System.Generic_Array_Operations is
is
begin
return R : Result_Vector (Right'Range (2)) do
- if Left'Length /= Right'Length (2) then
+ if Left'Length /= Right'Length (1) then
raise Constraint_Error with
"incompatible dimensions in vector-matrix multiplication";
end if;
@@ -913,7 +913,7 @@ package body System.Generic_Array_Operations is
begin
for K in Right'Range (1) loop
- S := S + Left (J - Right'First (1)
+ S := S + Left (K - Right'First (1)
+ Left'First) * Right (K, J);
end loop;
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index eef71b4b7..50a55e43d 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -288,8 +288,12 @@ C("Target_OS", OS_Type, TARGET_OS, "")
#define Target_Name TARGET
CST(Target_Name, "")
-#define sizeof_unsigned_int sizeof (unsigned int)
-CND(sizeof_unsigned_int, "Size of unsigned int")
+/**
+ ** Note: the name of the following constant is recognized specially by
+ ** xoscons (case sensitive).
+ **/
+#define SIZEOF_unsigned_int sizeof (unsigned int)
+CND(SIZEOF_unsigned_int, "Size of unsigned int")
/*
diff --git a/gcc/ada/s-spsufi.adb b/gcc/ada/s-spsufi.adb
index 86b18aad7..ef2c935f3 100644
--- a/gcc/ada/s-spsufi.adb
+++ b/gcc/ada/s-spsufi.adb
@@ -2,12 +2,11 @@
-- --
-- GNAT COMPILER COMPONENTS --
-- --
--- S Y S T E M . S T O R A G E _ P O O L S . S U B P O O L S . --
--- F I N A L I Z A T I O N --
+-- SYSTEM.STORAGE_POOLS.SUBPOOLS.FINALIZATION --
-- --
-- B o d y --
-- --
--- Copyright (C) 2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2011-2012, 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- --
@@ -30,6 +29,10 @@
-- --
------------------------------------------------------------------------------
+with Ada.Unchecked_Deallocation;
+
+with System.Finalization_Masters; use System.Finalization_Masters;
+
package body System.Storage_Pools.Subpools.Finalization is
-----------------------------
@@ -37,6 +40,8 @@ package body System.Storage_Pools.Subpools.Finalization is
-----------------------------
procedure Finalize_And_Deallocate (Subpool : in out Subpool_Handle) is
+ procedure Free is new Ada.Unchecked_Deallocation (SP_Node, SP_Node_Ptr);
+
begin
-- Do nothing if the subpool was never created or never used. The latter
-- case may arise with an array of subpool implementations.
@@ -48,9 +53,18 @@ package body System.Storage_Pools.Subpools.Finalization is
return;
end if;
- -- Clean up all controlled objects allocated through the subpool
+ -- Clean up all controlled objects chained on the subpool's master
+
+ Finalize (Subpool.Master);
+
+ -- Remove the subpool from its owner's list of subpools
+
+ Detach (Subpool.Node);
+
+ -- Destroy the associated doubly linked list node which was created in
+ -- Set_Pool_Of_Subpools.
- Finalize_Subpool (Subpool);
+ Free (Subpool.Node);
-- Dispatch to the user-defined implementation of Deallocate_Subpool
diff --git a/gcc/ada/s-spsufi.ads b/gcc/ada/s-spsufi.ads
index 66aac4b07..1de738b6f 100644
--- a/gcc/ada/s-spsufi.ads
+++ b/gcc/ada/s-spsufi.ads
@@ -2,12 +2,11 @@
-- --
-- GNAT COMPILER COMPONENTS --
-- --
--- S Y S T E M . S T O R A G E _ P O O L S . S U B P O O L S . --
--- F I N A L I Z A T I O N --
+-- SYSTEM.STORAGE_POOLS.SUBPOOLS.FINALIZATION --
-- --
-- S p e c --
-- --
--- Copyright (C) 2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2011-2012, 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- --
@@ -34,6 +33,11 @@ pragma Compiler_Unit;
package System.Storage_Pools.Subpools.Finalization is
+ -- The pragma is needed because package System.Storage_Pools.Subpools which
+ -- is already preelaborated now depends on this unit.
+
+ pragma Preelaborate;
+
procedure Finalize_And_Deallocate (Subpool : in out Subpool_Handle);
-- This routine performs the following actions:
-- 1) Finalize all objects chained on the subpool's master
diff --git a/gcc/ada/s-stposu.adb b/gcc/ada/s-stposu.adb
index 7838e48d8..cf43f2232 100644
--- a/gcc/ada/s-stposu.adb
+++ b/gcc/ada/s-stposu.adb
@@ -29,15 +29,18 @@
-- --
------------------------------------------------------------------------------
-with Ada.Exceptions; use Ada.Exceptions;
+with Ada.Exceptions; use Ada.Exceptions;
with Ada.Unchecked_Conversion;
-with Ada.Unchecked_Deallocation;
+
with System.Address_Image;
with System.Finalization_Masters; use System.Finalization_Masters;
with System.IO; use System.IO;
with System.Soft_Links; use System.Soft_Links;
with System.Storage_Elements; use System.Storage_Elements;
+with System.Storage_Pools.Subpools.Finalization;
+use System.Storage_Pools.Subpools.Finalization;
+
package body System.Storage_Pools.Subpools is
Finalize_Address_Table_In_Use : Boolean := False;
@@ -51,11 +54,6 @@ package body System.Storage_Pools.Subpools is
procedure Attach (N : not null SP_Node_Ptr; L : not null SP_Node_Ptr);
-- Attach a subpool node to a pool
- procedure Free is new Ada.Unchecked_Deallocation (SP_Node, SP_Node_Ptr);
-
- procedure Detach (N : not null SP_Node_Ptr);
- -- Unhook a subpool node from an arbitrary subpool list
-
-----------------------------------
-- Adjust_Controlled_Dereference --
-----------------------------------
@@ -544,9 +542,10 @@ package body System.Storage_Pools.Subpools is
-- 2) Remove the the subpool from the owner's list of subpools
-- 3) Deallocate the doubly linked list node associated with the
-- subpool.
+ -- 4) Call Deallocate_Subpool
begin
- Finalize_Subpool (Curr_Ptr.Subpool);
+ Finalize_And_Deallocate (Curr_Ptr.Subpool);
exception
when Fin_Occur : others =>
@@ -565,32 +564,6 @@ package body System.Storage_Pools.Subpools is
end if;
end Finalize_Pool;
- ----------------------
- -- Finalize_Subpool --
- ----------------------
-
- procedure Finalize_Subpool (Subpool : not null Subpool_Handle) is
- begin
- -- Do nothing if the subpool was never used
-
- if Subpool.Owner = null or else Subpool.Node = null then
- return;
- end if;
-
- -- Clean up all controlled objects chained on the subpool's master
-
- Finalize (Subpool.Master);
-
- -- Remove the subpool from its owner's list of subpools
-
- Detach (Subpool.Node);
-
- -- Destroy the associated doubly linked list node which was created in
- -- Set_Pool_Of_Subpool.
-
- Free (Subpool.Node);
- end Finalize_Subpool;
-
------------------------------
-- Header_Size_With_Padding --
------------------------------
diff --git a/gcc/ada/s-stposu.ads b/gcc/ada/s-stposu.ads
index 40fe676bd..c80dd9e34 100644
--- a/gcc/ada/s-stposu.ads
+++ b/gcc/ada/s-stposu.ads
@@ -325,6 +325,9 @@ private
-- is controlled. When set to True, the machinery generates additional
-- data.
+ procedure Detach (N : not null SP_Node_Ptr);
+ -- Unhook a subpool node from an arbitrary subpool list
+
overriding procedure Finalize (Controller : in out Pool_Controller);
-- Buffer routine, calls Finalize_Pool
@@ -333,11 +336,6 @@ private
-- their masters. This action first detaches a controlled object from a
-- particular master, then invokes its Finalize_Address primitive.
- procedure Finalize_Subpool (Subpool : not null Subpool_Handle);
- -- Finalize all controlled objects chained on Subpool's master. Remove the
- -- subpool from its owner's list. Deallocate the associated doubly linked
- -- list node.
-
function Header_Size_With_Padding
(Alignment : System.Storage_Elements.Storage_Count)
return System.Storage_Elements.Storage_Count;
diff --git a/gcc/ada/s-tassta.adb b/gcc/ada/s-tassta.adb
index 57c28be4e..08886c157 100644
--- a/gcc/ada/s-tassta.adb
+++ b/gcc/ada/s-tassta.adb
@@ -1905,7 +1905,16 @@ package body System.Tasking.Stages is
C := All_Tasks_List;
P := null;
while C /= null loop
- if C.Common.Parent = Self_ID and then C.Master_of_Task >= CM then
+
+ -- If Free_On_Termination is set, do nothing here, and let the
+ -- task free itself if not already done, otherwise we risk a race
+ -- condition where Vulnerable_Free_Task is called in the loop below,
+ -- while the task calls Free_Task itself, in Terminate_Task.
+
+ if C.Common.Parent = Self_ID
+ and then C.Master_of_Task >= CM
+ and then not C.Free_On_Termination
+ then
if P /= null then
P.Common.All_Tasks_Link := C.Common.All_Tasks_Link;
else
@@ -2088,9 +2097,7 @@ package body System.Tasking.Stages is
-- is called from Expunge_Unactivated_Tasks.
-- For tasks created by elaboration of task object declarations it is
- -- called from the finalization code of the Task_Wrapper procedure. It is
- -- also called from Ada.Unchecked_Deallocation, for objects that are or
- -- contain tasks.
+ -- called from the finalization code of the Task_Wrapper procedure.
procedure Vulnerable_Free_Task (T : Task_Id) is
begin
diff --git a/gcc/ada/scans.ads b/gcc/ada/scans.ads
index ca2a5bb90..eb062af42 100644
--- a/gcc/ada/scans.ads
+++ b/gcc/ada/scans.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -464,8 +464,8 @@ package Scans is
-- Is it really right for this to be a Name rather than a String, what
-- about the case of Wide_Wide_Characters???
- Inside_Conditional_Expression : Nat := 0;
- -- This is a counter that is set non-zero while scanning out a conditional
+ Inside_If_Expression : Nat := 0;
+ -- This is a counter that is set non-zero while scanning out an if
-- expression (incremented on entry, decremented on exit). It is used to
-- disconnect format checks that normally apply to keywords THEN, ELSE etc.
diff --git a/gcc/ada/scng.adb b/gcc/ada/scng.adb
index b0a17db28..ce644bc09 100644
--- a/gcc/ada/scng.adb
+++ b/gcc/ada/scng.adb
@@ -2742,13 +2742,13 @@ package body Scng is
end if;
-- Check THEN/ELSE style rules. These do not apply to AND THEN
- -- or OR ELSE, and do not apply in conditional expressions.
+ -- or OR ELSE, and do not apply in if expressions.
if (Token = Tok_Then and then Prev_Token /= Tok_And)
or else
(Token = Tok_Else and then Prev_Token /= Tok_Or)
then
- if Inside_Conditional_Expression = 0 then
+ if Inside_If_Expression = 0 then
Style.Check_Separate_Stmt_Lines;
end if;
end if;
diff --git a/gcc/ada/scos.adb b/gcc/ada/scos.adb
index b7df692de..fa8c66d6d 100644
--- a/gcc/ada/scos.adb
+++ b/gcc/ada/scos.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2009-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 2009-2012, 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- --
@@ -33,6 +33,7 @@ package body SCOs is
begin
SCO_Table.Init;
SCO_Unit_Table.Init;
+ SCO_Instance_Table.Init;
-- Set dummy zeroth entry for sort routine, real entries start at 1
diff --git a/gcc/ada/scos.ads b/gcc/ada/scos.ads
index 9f4789852..076a66ef3 100644
--- a/gcc/ada/scos.ads
+++ b/gcc/ada/scos.ads
@@ -246,13 +246,13 @@ package SCOs is
-- For each decision, a decision line is generated with the form:
- -- C* sloc expression [chaining]
+ -- C* sloc expression
-- Here * is one of the following characters:
-- E decision in EXIT WHEN statement
-- G decision in entry guard
- -- I decision in IF statement or conditional expression
+ -- I decision in IF statement or if expression
-- P decision in pragma Assert/Check/Pre_Condition/Post_Condition
-- W decision in WHILE iteration scheme
-- X decision appearing in some other expression context
@@ -308,35 +308,6 @@ package SCOs is
-- condition, and that is true even if the Ada 2005 set membership
-- form is used, e.g. A in (2,7,11.15).
- -- The expression can be followed by chaining indicators of the form
- -- Tsloc-range or Fsloc-range, where the sloc-range is that of some
- -- entry on a CS line.
-
- -- T* is present when the statement with the given sloc range is executed
- -- if, and only if, the decision evaluates to TRUE.
-
- -- F* is present when the statement with the given sloc range is executed
- -- if, and only if, the decision evaluates to FALSE.
-
- -- For an IF statement or ELSIF part, a T chaining indicator is always
- -- present, with the sloc range of the first statement in the
- -- corresponding sequence.
-
- -- For an ELSE part, the last decision in the IF statement (that of the
- -- last ELSIF part, if any, or that of the IF statement if there is no
- -- ELSIF part) has an F chaining indicator with the sloc range of the
- -- first statement in the sequence of the ELSE part.
-
- -- For a WHILE loop, a T chaining indicator is always present, with the
- -- sloc range of the first statement in the loop, but no F chaining
- -- indicator is ever present.
-
- -- For an EXIT WHEN statement, an F chaining indicator is present if
- -- there is an immediately following sequence in the same sequence of
- -- statements.
-
- -- In all other cases, chaining indicators are omitted
-
-- Implementation permission: a SCO generator is permitted to emit a
-- narrower SLOC range for a condition if the corresponding code
-- generation circuitry ensures that all debug information for the code
@@ -360,6 +331,19 @@ package SCOs is
-- entries appear in one logical statement sequence, continuation lines
-- are marked by Cc and appear immediately after the CC line.
+ -- Generic instances
+
+ -- A table of all generic instantiations in the compilation is generated
+ -- whose entries have the form:
+
+ -- C i index dependency-number|sloc [enclosing]
+
+ -- Where index is the 1-based index of the entry in the table,
+ -- dependency-number and sloc indicate the source location of the
+ -- instantiation, and enclosing is the index of the enclosing
+ -- instantiation in the table (for a nested instantiation), or is
+ -- omitted for an outer instantiation.
+
-- Disabled pragmas
-- No SCO is generated for disabled pragmas
@@ -471,12 +455,6 @@ package SCOs is
-- To = ending source location
-- Last = False for all but the last entry, True for last entry
- -- Element (chaining indicator)
- -- C1 = 'H' (cHain)
- -- C2 = 'T' or 'F' (chaining on decision true/false)
- -- From = starting source location of chained statement
- -- To = ending source location of chained statement
-
-- Note: the sequence starting with a decision, and continuing with
-- operators and elements up to and including the first one labeled with
-- Last = True, indicate the sequence to be output on one decision line.
@@ -515,6 +493,27 @@ package SCOs is
Table_Initial => 20,
Table_Increment => 200);
+ -----------------------
+ -- Generic instances --
+ -----------------------
+
+ type SCO_Instance_Index is new Nat;
+
+ type SCO_Instance_Table_Entry is record
+ Inst_Dep_Num : Nat;
+ Inst_Loc : Source_Location;
+ -- File and source location of instantiation
+
+ Enclosing_Instance : SCO_Instance_Index;
+ end record;
+
+ package SCO_Instance_Table is new GNAT.Table (
+ Table_Component_Type => SCO_Instance_Table_Entry,
+ Table_Index_Type => SCO_Instance_Index,
+ Table_Low_Bound => 1,
+ Table_Initial => 20,
+ Table_Increment => 200);
+
-----------------
-- Subprograms --
-----------------
diff --git a/gcc/ada/sem.adb b/gcc/ada/sem.adb
index 46fd546fa..6aafad8e0 100644
--- a/gcc/ada/sem.adb
+++ b/gcc/ada/sem.adb
@@ -33,6 +33,7 @@ with Fname; use Fname;
with Lib; use Lib;
with Lib.Load; use Lib.Load;
with Nlists; use Nlists;
+with Opt; use Opt;
with Output; use Output;
with Restrict; use Restrict;
with Sem_Attr; use Sem_Attr;
@@ -167,9 +168,6 @@ package body Sem is
when N_Component_Declaration =>
Analyze_Component_Declaration (N);
- when N_Conditional_Expression =>
- Analyze_Conditional_Expression (N);
-
when N_Conditional_Entry_Call =>
Analyze_Conditional_Entry_Call (N);
@@ -278,6 +276,9 @@ package body Sem is
when N_Identifier =>
Analyze_Identifier (N);
+ when N_If_Expression =>
+ Analyze_If_Expression (N);
+
when N_If_Statement =>
Analyze_If_Statement (N);
@@ -729,6 +730,20 @@ package body Sem is
Scope_Suppress := Svg;
end;
+ elsif Suppress = Overflow_Check then
+ declare
+ Svg : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ Sva : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
+ begin
+ Scope_Suppress.Overflow_Checks_General := Suppressed;
+ Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
+ Analyze (N);
+ Scope_Suppress.Overflow_Checks_General := Svg;
+ Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ end;
+
else
declare
Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
@@ -768,6 +783,20 @@ package body Sem is
Scope_Suppress := Svg;
end;
+ elsif Suppress = Overflow_Check then
+ declare
+ Svg : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ Sva : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
+ begin
+ Scope_Suppress.Overflow_Checks_General := Suppressed;
+ Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
+ Analyze_List (L);
+ Scope_Suppress.Overflow_Checks_General := Svg;
+ Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ end;
+
else
declare
Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
@@ -1217,59 +1246,6 @@ package body Sem is
end if;
end Insert_List_Before_And_Analyze;
- -------------------------
- -- Is_Check_Suppressed --
- -------------------------
-
- function Is_Check_Suppressed (E : Entity_Id; C : Check_Id) return Boolean is
-
- Ptr : Suppress_Stack_Entry_Ptr;
-
- begin
- -- First search the local entity suppress stack. We search this from the
- -- top of the stack down so that we get the innermost entry that applies
- -- to this case if there are nested entries.
-
- Ptr := Local_Suppress_Stack_Top;
- while Ptr /= null loop
- if (Ptr.Entity = Empty or else Ptr.Entity = E)
- and then (Ptr.Check = All_Checks or else Ptr.Check = C)
- then
- return Ptr.Suppress;
- end if;
-
- Ptr := Ptr.Prev;
- end loop;
-
- -- Now search the global entity suppress table for a matching entry.
- -- We also search this from the top down so that if there are multiple
- -- pragmas for the same entity, the last one applies (not clear what
- -- or whether the RM specifies this handling, but it seems reasonable).
-
- Ptr := Global_Suppress_Stack_Top;
- while Ptr /= null loop
- if (Ptr.Entity = Empty or else Ptr.Entity = E)
- and then (Ptr.Check = All_Checks or else Ptr.Check = C)
- then
- return Ptr.Suppress;
- end if;
-
- Ptr := Ptr.Prev;
- end loop;
-
- -- If we did not find a matching entry, then use the normal scope
- -- suppress value after all (actually this will be the global setting
- -- since it clearly was not overridden at any point). For a predefined
- -- check, we test the specific flag. For a user defined check, we check
- -- the All_Checks flag.
-
- if C in Predefined_Check_Id then
- return Scope_Suppress.Suppress (C);
- else
- return Scope_Suppress.Suppress (All_Checks);
- end if;
- end Is_Check_Suppressed;
-
----------
-- Lock --
----------
@@ -1353,13 +1329,14 @@ package body Sem is
-- these variables, and also that such calls do not disturb the settings
-- for units being analyzed at a higher level.
- S_Current_Sem_Unit : constant Unit_Number_Type := Current_Sem_Unit;
- S_Full_Analysis : constant Boolean := Full_Analysis;
- S_GNAT_Mode : constant Boolean := GNAT_Mode;
- S_Global_Dis_Names : constant Boolean := Global_Discard_Names;
- S_In_Spec_Expr : constant Boolean := In_Spec_Expression;
- S_Inside_A_Generic : constant Boolean := Inside_A_Generic;
- S_Outer_Gen_Scope : constant Entity_Id := Outer_Generic_Scope;
+ S_Current_Sem_Unit : constant Unit_Number_Type := Current_Sem_Unit;
+ S_Full_Analysis : constant Boolean := Full_Analysis;
+ S_GNAT_Mode : constant Boolean := GNAT_Mode;
+ S_Global_Dis_Names : constant Boolean := Global_Discard_Names;
+ S_In_Assertion_Expr : constant Nat := In_Assertion_Expr;
+ S_In_Spec_Expr : constant Boolean := In_Spec_Expression;
+ S_Inside_A_Generic : constant Boolean := Inside_A_Generic;
+ S_Outer_Gen_Scope : constant Entity_Id := Outer_Generic_Scope;
Generic_Main : constant Boolean :=
Nkind (Unit (Cunit (Main_Unit)))
@@ -1453,6 +1430,7 @@ package body Sem is
Full_Analysis := True;
Inside_A_Generic := False;
+ In_Assertion_Expr := 0;
In_Spec_Expression := False;
Set_Comes_From_Source_Default (False);
@@ -1526,6 +1504,7 @@ package body Sem is
Full_Analysis := S_Full_Analysis;
Global_Discard_Names := S_Global_Dis_Names;
GNAT_Mode := S_GNAT_Mode;
+ In_Assertion_Expr := S_In_Assertion_Expr;
In_Spec_Expression := S_In_Spec_Expr;
Inside_A_Generic := S_Inside_A_Generic;
Outer_Generic_Scope := S_Outer_Gen_Scope;
diff --git a/gcc/ada/sem.ads b/gcc/ada/sem.ads
index 00bce6969..31fc37b95 100644
--- a/gcc/ada/sem.ads
+++ b/gcc/ada/sem.ads
@@ -203,7 +203,6 @@
with Alloc;
with Einfo; use Einfo;
-with Opt; use Opt;
with Table;
with Types; use Types;
@@ -243,6 +242,15 @@ package Sem is
-- frozen from start, because the tree on which they depend will not
-- be available at the freeze point.
+ In_Assertion_Expr : Nat := 0;
+ -- This is set non-zero if we are within the expression of an assertion
+ -- pragma or aspect. It is a counter which is incremented at the start
+ -- of expanding such an expression, and decremented on completion of
+ -- expanding that expression. Probably a boolean would be good enough,
+ -- since we think that such expressions cannot nest, but that might not
+ -- be true in the future (e.g. if let expressions are added to Ada) so
+ -- we prepare for that future possibility by making it a counter.
+
In_Inlined_Body : Boolean := False;
-- Switch to indicate that we are analyzing and resolving an inlined body.
-- Type checking is disabled in this context, because types are known to be
@@ -283,10 +291,10 @@ package Sem is
-- Scope based suppress checks for the predefined checks (from initial
-- command line arguments, or from Suppress pragmas not including an entity
- -- entity name) are recorded in the Sem.Suppress variable, and all that is
- -- necessary is to save the state of this variable on scope entry, and
- -- restore it on scope exit. This mechanism allows for fast checking of
- -- the scope suppress state without needing complex data structures.
+ -- name) are recorded in the Sem.Scope_Suppress variable, and all that
+ -- is necessary is to save the state of this variable on scope entry, and
+ -- restore it on scope exit. This mechanism allows for fast checking of the
+ -- scope suppress state without needing complex data structures.
-- Entity based checks, from Suppress/Unsuppress pragmas giving an
-- Entity_Id and scope based checks for non-predefined checks (introduced
@@ -310,15 +318,15 @@ package Sem is
-- that are applicable to all entities. A similar search is needed for any
-- non-predefined check even if no specific entity is involved.
- Scope_Suppress : Suppress_Record := Suppress_Options;
+ Scope_Suppress : Suppress_Record;
-- This variable contains the current scope based settings of the suppress
- -- switches. It is initialized from the options as shown, and then modified
- -- by pragma Suppress. On entry to each scope, the current setting is saved
- -- the scope stack, and then restored on exit from the scope. This record
- -- may be rapidly checked to determine the current status of a check if
- -- no specific entity is involved or if the specific entity involved is
- -- one for which no specific Suppress/Unsuppress pragma has been set (as
- -- indicated by the Checks_May_Be_Suppressed flag being set).
+ -- switches. It is initialized from Suppress_Options in Gnat1drv, and then
+ -- modified by pragma Suppress. On entry to each scope, the current setting
+ -- is saved on the scope stack, and then restored on exit from the scope.
+ -- This record may be rapidly checked to determine the current status of
+ -- a check if no specific entity is involved or if the specific entity
+ -- involved is one for which no specific Suppress/Unsuppress pragma has
+ -- been set (as indicated by the Checks_May_Be_Suppressed flag being set).
-- This scheme is a little complex, but serves the purpose of enabling
-- a very rapid check in the common case where no entity specific pragma
@@ -633,13 +641,6 @@ package Sem is
-- This function returns True if an explicit pragma Suppress for check C
-- is present in the package defining E.
- function Is_Check_Suppressed (E : Entity_Id; C : Check_Id) return Boolean;
- -- This function is called if Checks_May_Be_Suppressed (E) is True to
- -- determine whether check C is suppressed either on the entity E or
- -- as the result of a scope suppress pragma. If Checks_May_Be_Suppressed
- -- is False, then the status of the check can be determined simply by
- -- examining Scope_Checks (C), so this routine is not called in that case.
-
procedure Preanalyze (N : Node_Id);
-- Performs a pre-analysis of node N. During pre-analysis no expansion is
-- carried out for N or its children. For more info on pre-analysis read
diff --git a/gcc/ada/sem_aggr.adb b/gcc/ada/sem_aggr.adb
index 993235210..e73b87583 100644
--- a/gcc/ada/sem_aggr.adb
+++ b/gcc/ada/sem_aggr.adb
@@ -47,6 +47,7 @@ with Sem_Cat; use Sem_Cat;
with Sem_Ch3; use Sem_Ch3;
with Sem_Ch8; use Sem_Ch8;
with Sem_Ch13; use Sem_Ch13;
+with Sem_Dim; use Sem_Dim;
with Sem_Eval; use Sem_Eval;
with Sem_Res; use Sem_Res;
with Sem_Util; use Sem_Util;
@@ -1726,6 +1727,9 @@ package body Sem_Aggr is
Discard : Node_Id;
pragma Warnings (Off, Discard);
+ Delete_Choice : Boolean;
+ -- Used when replacing a subtype choice with predicate by a list
+
Aggr_Low : Node_Id := Empty;
Aggr_High : Node_Id := Empty;
-- The actual low and high bounds of this sub-aggregate
@@ -1766,6 +1770,8 @@ package body Sem_Aggr is
Assoc := First (Component_Associations (N));
while Present (Assoc) loop
Choice := First (Choices (Assoc));
+ Delete_Choice := False;
+
while Present (Choice) loop
if Nkind (Choice) = N_Others_Choice then
Others_Present := True;
@@ -1792,10 +1798,56 @@ package body Sem_Aggr is
Error_Msg_N
("(Ada 83) illegal context for OTHERS choice", N);
end if;
+
+ elsif Is_Entity_Name (Choice) then
+ Analyze (Choice);
+
+ declare
+ E : constant Entity_Id := Entity (Choice);
+ New_Cs : List_Id;
+ P : Node_Id;
+ C : Node_Id;
+
+ begin
+ if Is_Type (E) and then Has_Predicates (E) then
+ Freeze_Before (N, E);
+
+ -- If the subtype has a static predicate, replace the
+ -- original choice with the list of individual values
+ -- covered by the predicate.
+
+ if Present (Static_Predicate (E)) then
+ Delete_Choice := True;
+
+ New_Cs := New_List;
+ P := First (Static_Predicate (E));
+ while Present (P) loop
+ C := New_Copy (P);
+ Set_Sloc (C, Sloc (Choice));
+ Append_To (New_Cs, C);
+ Next (P);
+ end loop;
+
+ Insert_List_After (Choice, New_Cs);
+ end if;
+ end if;
+ end;
end if;
Nb_Choices := Nb_Choices + 1;
- Next (Choice);
+
+ declare
+ C : constant Node_Id := Choice;
+
+ begin
+ Next (Choice);
+
+ if Delete_Choice then
+ Remove (C);
+ Nb_Choices := Nb_Choices - 1;
+ Delete_Choice := False;
+ end if;
+ end;
end loop;
Next (Assoc);
@@ -1998,6 +2050,7 @@ package body Sem_Aggr is
Nb_Discrete_Choices := Nb_Discrete_Choices + 1;
Table (Nb_Discrete_Choices).Choice_Lo := Low;
Table (Nb_Discrete_Choices).Choice_Hi := High;
+ Table (Nb_Discrete_Choices).Choice_Node := Choice;
Next (Choice);
@@ -2115,7 +2168,7 @@ package body Sem_Aggr is
then
Error_Msg_N
("duplicate choice values in array aggregate",
- Table (J).Choice_Hi);
+ Table (J).Choice_Node);
return Failure;
elsif not Others_Present then
@@ -2497,6 +2550,10 @@ package body Sem_Aggr is
Duplicate_Subexpr (High_Bound (Aggregate_Bounds (N))));
end if;
+ -- Check the dimensions of each component in the array aggregate
+
+ Analyze_Dimension_Array_Aggregate (N, Component_Typ);
+
return Success;
end Resolve_Array_Aggregate;
@@ -2876,6 +2933,14 @@ package body Sem_Aggr is
-- An error message is emitted if the components taking their value from
-- the others choice do not have same type.
+ function New_Copy_Tree_And_Copy_Dimensions
+ (Source : Node_Id;
+ Map : Elist_Id := No_Elist;
+ New_Sloc : Source_Ptr := No_Location;
+ New_Scope : Entity_Id := Empty) return Node_Id;
+ -- Same as New_Copy_Tree (defined in Sem_Util), except that this routine
+ -- also copies the dimensions of Source to the returned node.
+
procedure Resolve_Aggr_Expr (Expr : Node_Id; Component : Node_Id);
-- Analyzes and resolves expression Expr against the Etype of the
-- Component. This routine also applies all appropriate checks to Expr.
@@ -3077,7 +3142,7 @@ package body Sem_Aggr is
if Expander_Active then
return
- New_Copy_Tree
+ New_Copy_Tree_And_Copy_Dimensions
(Expression (Parent (Compon)),
New_Sloc => Sloc (Assoc));
else
@@ -3096,7 +3161,9 @@ package body Sem_Aggr is
Others_Etype := Etype (Compon);
if Expander_Active then
- return New_Copy_Tree (Expression (Assoc));
+ return
+ New_Copy_Tree_And_Copy_Dimensions
+ (Expression (Assoc));
else
return Expression (Assoc);
end if;
@@ -3132,18 +3199,20 @@ package body Sem_Aggr is
-- order to create a proper association for the
-- expanded aggregate.
- Expr := New_Copy_Tree (Expression (Parent (Compon)));
-
-- Component may have no default, in which case the
-- expression is empty and the component is default-
-- initialized, but an association for the component
-- exists, and it is not covered by an others clause.
- return Expr;
+ return
+ New_Copy_Tree_And_Copy_Dimensions
+ (Expression (Parent (Compon)));
else
if Present (Next (Selector_Name)) then
- Expr := New_Copy_Tree (Expression (Assoc));
+ Expr :=
+ New_Copy_Tree_And_Copy_Dimensions
+ (Expression (Assoc));
else
Expr := Expression (Assoc);
end if;
@@ -3168,13 +3237,33 @@ package body Sem_Aggr is
return Expr;
end Get_Value;
+ ---------------------------------------
+ -- New_Copy_Tree_And_Copy_Dimensions --
+ ---------------------------------------
+
+ function New_Copy_Tree_And_Copy_Dimensions
+ (Source : Node_Id;
+ Map : Elist_Id := No_Elist;
+ New_Sloc : Source_Ptr := No_Location;
+ New_Scope : Entity_Id := Empty) return Node_Id
+ is
+ New_Copy : constant Node_Id :=
+ New_Copy_Tree (Source, Map, New_Sloc, New_Scope);
+ begin
+ -- Move the dimensions of Source to New_Copy
+
+ Copy_Dimensions (Source, New_Copy);
+ return New_Copy;
+ end New_Copy_Tree_And_Copy_Dimensions;
+
-----------------------
-- Resolve_Aggr_Expr --
-----------------------
procedure Resolve_Aggr_Expr (Expr : Node_Id; Component : Node_Id) is
- New_C : Entity_Id := Component;
Expr_Type : Entity_Id := Empty;
+ New_C : Entity_Id := Component;
+ New_Expr : Node_Id;
function Has_Expansion_Delayed (Expr : Node_Id) return Boolean;
-- If the expression is an aggregate (possibly qualified) then its
@@ -3328,10 +3417,18 @@ package body Sem_Aggr is
end if;
if Relocate then
- Add_Association (New_C, Relocate_Node (Expr), New_Assoc_List);
+ New_Expr := Relocate_Node (Expr);
+
+ -- Since New_Expr is not gonna be analyzed later on, we need to
+ -- propagate here the dimensions form Expr to New_Expr.
+
+ Copy_Dimensions (Expr, New_Expr);
+
else
- Add_Association (New_C, Expr, New_Assoc_List);
+ New_Expr := Expr;
end if;
+
+ Add_Association (New_C, New_Expr, New_Assoc_List);
end Resolve_Aggr_Expr;
-- Start of processing for Resolve_Record_Aggregate
@@ -3920,7 +4017,7 @@ package body Sem_Aggr is
and then Present (Expression (Parent (Component)))
then
Expr :=
- New_Copy_Tree
+ New_Copy_Tree_And_Copy_Dimensions
(Expression (Parent (Component)),
New_Scope => Current_Scope,
New_Sloc => Sloc (N));
@@ -3983,6 +4080,7 @@ package body Sem_Aggr is
-- We build a partially initialized aggregate with the
-- values of the discriminants and box initialization
-- for the rest, if other components are present.
+
-- The type of the aggregate is the known subtype of
-- the component. The capture of discriminants must
-- be recursive because subcomponents may be constrained
@@ -4337,9 +4435,8 @@ package body Sem_Aggr is
Next (New_Assoc);
end loop;
- -- If no association, this is not a legal component of
- -- of the type in question, except if its association
- -- is provided with a box.
+ -- If no association, this is not a legal component of the type
+ -- in question, unless its association is provided with a box.
if No (New_Assoc) then
if Box_Present (Parent (Selectr)) then
@@ -4438,6 +4535,10 @@ package body Sem_Aggr is
Rewrite (N, New_Aggregate);
end Step_8;
+
+ -- Check the dimensions of the components in the record aggregate
+
+ Analyze_Dimension_Extension_Or_Record_Aggregate (N);
end Resolve_Record_Aggregate;
-----------------------------
diff --git a/gcc/ada/sem_attr.adb b/gcc/ada/sem_attr.adb
index 737ede238..5b1585a39 100644
--- a/gcc/ada/sem_attr.adb
+++ b/gcc/ada/sem_attr.adb
@@ -4053,6 +4053,7 @@ package body Sem_Attr is
P_Type := Base_Type (P_Type);
Set_Etype (N, P_Type);
Set_Etype (P, P_Type);
+ Analyze_Dimension (N);
Expand (N);
end if;
end Old;
@@ -4062,7 +4063,6 @@ package body Sem_Attr is
----------------------
when Attribute_Overlaps_Storage =>
- Check_Ada_2012_Attribute;
Check_E1;
-- Both arguments must be objects of any type
@@ -9003,6 +9003,21 @@ package body Sem_Attr is
then
Accessibility_Message;
return;
+
+ -- AI05-0225: If the context is not an access to protected
+ -- function, the prefix must be a variable, given that it may
+ -- be used subsequently in a protected call.
+
+ elsif Nkind (P) = N_Selected_Component
+ and then not Is_Variable (Prefix (P))
+ and then Ekind (Entity (Selector_Name (P))) /= E_Function
+ then
+ Error_Msg_N
+ ("target object of access to protected procedure "
+ & "must be variable", N);
+
+ elsif Is_Entity_Name (P) then
+ Check_Internal_Protected_Use (N, Entity (P));
end if;
elsif Ekind_In (Btyp, E_Access_Subprogram_Type,
diff --git a/gcc/ada/sem_ch10.adb b/gcc/ada/sem_ch10.adb
index 31e8e5564..0a90eb2e8 100644
--- a/gcc/ada/sem_ch10.adb
+++ b/gcc/ada/sem_ch10.adb
@@ -164,6 +164,11 @@ package body Sem_Ch10 is
-- an enclosing scope. Iterate over context to find child units of U_Name
-- or of some ancestor of it.
+ function Is_Ancestor_Unit (U1 : Node_Id; U2 : Node_Id) return Boolean;
+ -- When compiling a unit Q descended from some parent unit P, a limited
+ -- with_clause in the context of P that names some other ancestor of Q
+ -- must not be installed because the ancestor is immediately visible.
+
function Is_Child_Spec (Lib_Unit : Node_Id) return Boolean;
-- Lib_Unit is a library unit which may be a spec or a body. Is_Child_Spec
-- returns True if Lib_Unit is a library spec which is a child spec, i.e.
@@ -1822,7 +1827,7 @@ package body Sem_Ch10 is
Set_Corresponding_Stub (Unit (Comp_Unit), N);
-- Collect SCO information for loaded subunit if we are
- -- in the main unit).
+ -- in the main unit.
if Generate_SCO
and then
@@ -3521,11 +3526,6 @@ package body Sem_Ch10 is
-- units. The shadow entities are created when the inserted clause is
-- analyzed. Implements Ada 2005 (AI-50217).
- function Is_Ancestor_Unit (U1 : Node_Id; U2 : Node_Id) return Boolean;
- -- When compiling a unit Q descended from some parent unit P, a limited
- -- with_clause in the context of P that names some other ancestor of Q
- -- must not be installed because the ancestor is immediately visible.
-
---------------------
-- Check_Renamings --
---------------------
@@ -3794,22 +3794,6 @@ package body Sem_Ch10 is
end if;
end Expand_Limited_With_Clause;
- ----------------------
- -- Is_Ancestor_Unit --
- ----------------------
-
- function Is_Ancestor_Unit (U1 : Node_Id; U2 : Node_Id) return Boolean is
- E1 : constant Entity_Id := Defining_Entity (Unit (U1));
- E2 : Entity_Id;
- begin
- if Nkind_In (Unit (U2), N_Package_Body, N_Subprogram_Body) then
- E2 := Defining_Entity (Unit (Library_Unit (U2)));
- return Is_Ancestor_Package (E1, E2);
- else
- return False;
- end if;
- end Is_Ancestor_Unit;
-
-- Start of processing for Install_Limited_Context_Clauses
begin
@@ -4061,8 +4045,17 @@ package body Sem_Ch10 is
if Nkind (Item) = N_With_Clause
and then Private_Present (Item)
then
+ -- If the unit is an ancestor of the current one, it is the
+ -- case of a private limited with clause on a child unit, and
+ -- the compilation of one of its descendants, In that case the
+ -- limited view is errelevant.
+
if Limited_Present (Item) then
- if not Limited_View_Installed (Item) then
+ if not Limited_View_Installed (Item)
+ and then
+ not Is_Ancestor_Unit (Library_Unit (Item),
+ Cunit (Current_Sem_Unit))
+ then
Install_Limited_Withed_Unit (Item);
end if;
else
@@ -5269,6 +5262,22 @@ package body Sem_Ch10 is
(C_Unit, Cunit_Entity (Get_Source_Unit (Non_Limited_View (T))));
end Is_Legal_Shadow_Entity_In_Body;
+ ----------------------
+ -- Is_Ancestor_Unit --
+ ----------------------
+
+ function Is_Ancestor_Unit (U1 : Node_Id; U2 : Node_Id) return Boolean is
+ E1 : constant Entity_Id := Defining_Entity (Unit (U1));
+ E2 : Entity_Id;
+ begin
+ if Nkind_In (Unit (U2), N_Package_Body, N_Subprogram_Body) then
+ E2 := Defining_Entity (Unit (Library_Unit (U2)));
+ return Is_Ancestor_Package (E1, E2);
+ else
+ return False;
+ end if;
+ end Is_Ancestor_Unit;
+
-----------------------
-- Load_Needed_Body --
-----------------------
diff --git a/gcc/ada/sem_ch13.adb b/gcc/ada/sem_ch13.adb
index fff9bded5..521eb80b1 100644
--- a/gcc/ada/sem_ch13.adb
+++ b/gcc/ada/sem_ch13.adb
@@ -856,7 +856,7 @@ package body Sem_Ch13 is
-- Start of processing for Analyze_Aspects_At_Freeze_Point
begin
- -- Must be visible in current scope.
+ -- Must be visible in current scope
if not Scope_Within_Or_Same (Current_Scope, Scope (E)) then
return;
@@ -888,6 +888,15 @@ package body Sem_Ch13 is
Aspect_Default_Component_Value =>
Analyze_Aspect_Default_Value (ASN);
+ -- Ditto for iterator aspects, because the corresponding
+ -- attributes may not have been analyzed yet.
+
+ when Aspect_Constant_Indexing |
+ Aspect_Variable_Indexing |
+ Aspect_Default_Iterator |
+ Aspect_Iterator_Element =>
+ Analyze (Expression (ASN));
+
when others =>
null;
end case;
@@ -1919,7 +1928,7 @@ package body Sem_Ch13 is
procedure Check_Indexing_Functions;
-- Check that the function in Constant_Indexing or Variable_Indexing
-- attribute has the proper type structure. If the name is overloaded,
- -- check that all interpretations are legal.
+ -- check that some interpretation is legal.
procedure Check_Iterator_Functions;
-- Check that there is a single function in Default_Iterator attribute
@@ -2070,9 +2079,11 @@ package body Sem_Ch13 is
------------------------------
procedure Check_Indexing_Functions is
+ Indexing_Found : Boolean;
procedure Check_One_Function (Subp : Entity_Id);
- -- Check one possible interpretation
+ -- Check one possible interpretation. Sets Indexing_Found True if an
+ -- indexing function is found.
------------------------
-- Check_One_Function --
@@ -2085,29 +2096,39 @@ package body Sem_Ch13 is
Aspect_Iterator_Element);
begin
- if not Check_Primitive_Function (Subp) then
+ if not Check_Primitive_Function (Subp)
+ and then not Is_Overloaded (Expr)
+ then
Error_Msg_NE
("aspect Indexing requires a function that applies to type&",
- Subp, Ent);
+ Subp, Ent);
end if;
-- An indexing function must return either the default element of
- -- the container, or a reference type.
+ -- the container, or a reference type. For variable indexing it
+ -- must be the latter.
if Present (Default_Element) then
Analyze (Default_Element);
+
if Is_Entity_Name (Default_Element)
and then Covers (Entity (Default_Element), Etype (Subp))
then
+ Indexing_Found := True;
return;
end if;
end if;
- -- Otherwise the return type must be a reference type.
+ -- For variable_indexing the return type must be a reference type
- if not Has_Implicit_Dereference (Etype (Subp)) then
+ if Attr = Name_Variable_Indexing
+ and then not Has_Implicit_Dereference (Etype (Subp))
+ then
Error_Msg_N
("function for indexing must return a reference type", Subp);
+
+ else
+ Indexing_Found := True;
end if;
end Check_One_Function;
@@ -2129,6 +2150,7 @@ package body Sem_Ch13 is
It : Interp;
begin
+ Indexing_Found := False;
Get_First_Interp (Expr, I, It);
while Present (It.Nam) loop
@@ -2142,6 +2164,12 @@ package body Sem_Ch13 is
Get_Next_Interp (I, It);
end loop;
+
+ if not Indexing_Found then
+ Error_Msg_NE
+ ("aspect Indexing requires a function that "
+ & "applies to type&", Expr, Ent);
+ end if;
end;
end if;
end Check_Indexing_Functions;
@@ -4874,6 +4902,48 @@ package body Sem_Ch13 is
end if;
end Analyze_Record_Representation_Clause;
+ -------------------------------------------
+ -- Build_Invariant_Procedure_Declaration --
+ -------------------------------------------
+
+ function Build_Invariant_Procedure_Declaration
+ (Typ : Entity_Id) return Node_Id
+ is
+ Loc : constant Source_Ptr := Sloc (Typ);
+ Object_Entity : constant Entity_Id :=
+ Make_Defining_Identifier (Loc, New_Internal_Name ('I'));
+ Spec : Node_Id;
+ SId : Entity_Id;
+
+ begin
+ Set_Etype (Object_Entity, Typ);
+
+ -- Check for duplicate definiations.
+
+ if Has_Invariants (Typ)
+ and then Present (Invariant_Procedure (Typ))
+ then
+ return Empty;
+ end if;
+
+ SId := Make_Defining_Identifier (Loc,
+ Chars => New_External_Name (Chars (Typ), "Invariant"));
+ Set_Has_Invariants (SId);
+ Set_Has_Invariants (Typ);
+ Set_Ekind (SId, E_Procedure);
+ Set_Invariant_Procedure (Typ, SId);
+
+ Spec :=
+ Make_Procedure_Specification (Loc,
+ Defining_Unit_Name => SId,
+ Parameter_Specifications => New_List (
+ Make_Parameter_Specification (Loc,
+ Defining_Identifier => Object_Entity,
+ Parameter_Type => New_Occurrence_Of (Typ, Loc))));
+
+ return Make_Subprogram_Declaration (Loc, Specification => Spec);
+ end Build_Invariant_Procedure_Declaration;
+
-------------------------------
-- Build_Invariant_Procedure --
-------------------------------
@@ -4908,12 +4978,11 @@ package body Sem_Ch13 is
-- "inherited" to the exception message and generating an informational
-- message about the inheritance of an invariant.
- Object_Name : constant Name_Id := New_Internal_Name ('I');
+ Object_Name : Name_Id;
-- Name for argument of invariant procedure
- Object_Entity : constant Node_Id :=
- Make_Defining_Identifier (Loc, Object_Name);
- -- The procedure declaration entity for the argument
+ Object_Entity : Node_Id;
+ -- The entity of the formal for the procedure
--------------------
-- Add_Invariants --
@@ -5051,7 +5120,7 @@ package body Sem_Ch13 is
-- at the end of the private part and has the wrong visibility.
Set_Parent (Exp, N);
- Preanalyze_Spec_Expression (Exp, Standard_Boolean);
+ Preanalyze_Assert_Expression (Exp, Standard_Boolean);
-- Build first two arguments for Check pragma
@@ -5112,7 +5181,29 @@ package body Sem_Ch13 is
Stmts := No_List;
PDecl := Empty;
PBody := Empty;
- Set_Etype (Object_Entity, Typ);
+ SId := Empty;
+
+ -- If the aspect specification exists for some view of the type, the
+ -- declaration for the procedure has been created.
+
+ if Has_Invariants (Typ) then
+ SId := Invariant_Procedure (Typ);
+ end if;
+
+ if Present (SId) then
+ PDecl := Unit_Declaration_Node (SId);
+
+ else
+ PDecl := Build_Invariant_Procedure_Declaration (Typ);
+ end if;
+
+ -- Recover formal of procedure, for use in the calls to invariant
+ -- functions (including inherited ones).
+
+ Object_Entity :=
+ Defining_Identifier
+ (First (Parameter_Specifications (Specification (PDecl))));
+ Object_Name := Chars (Object_Entity);
-- Add invariants for the current type
@@ -5146,38 +5237,7 @@ package body Sem_Ch13 is
if Stmts /= No_List then
- -- Build procedure declaration
-
- SId :=
- Make_Defining_Identifier (Loc,
- Chars => New_External_Name (Chars (Typ), "Invariant"));
- Set_Has_Invariants (SId);
- Set_Invariant_Procedure (Typ, SId);
-
- Spec :=
- Make_Procedure_Specification (Loc,
- Defining_Unit_Name => SId,
- Parameter_Specifications => New_List (
- Make_Parameter_Specification (Loc,
- Defining_Identifier => Object_Entity,
- Parameter_Type => New_Occurrence_Of (Typ, Loc))));
-
- PDecl := Make_Subprogram_Declaration (Loc, Specification => Spec);
-
- -- Build procedure body
-
- SId :=
- Make_Defining_Identifier (Loc,
- Chars => New_External_Name (Chars (Typ), "Invariant"));
-
- Spec :=
- Make_Procedure_Specification (Loc,
- Defining_Unit_Name => SId,
- Parameter_Specifications => New_List (
- Make_Parameter_Specification (Loc,
- Defining_Identifier =>
- Make_Defining_Identifier (Loc, Object_Name),
- Parameter_Type => New_Occurrence_Of (Typ, Loc))));
+ Spec := Copy_Separate_Tree (Specification (PDecl));
PBody :=
Make_Subprogram_Body (Loc,
@@ -5188,17 +5248,18 @@ package body Sem_Ch13 is
Statements => Stmts));
-- Insert procedure declaration and spec at the appropriate points.
- -- Skip this if there are no private declarations (that's an error
- -- that will be diagnosed elsewhere, and there is no point in having
- -- an invariant procedure set if the full declaration is missing).
+ -- If declaration is already analyzed, it was processed by the
+ -- generated pragma.
if Present (Private_Decls) then
-- The spec goes at the end of visible declarations, but they have
-- already been analyzed, so we need to explicitly do the analyze.
- Append_To (Visible_Decls, PDecl);
- Analyze (PDecl);
+ if not Analyzed (PDecl) then
+ Append_To (Visible_Decls, PDecl);
+ Analyze (PDecl);
+ end if;
-- The body goes at the end of the private declarations, which we
-- have not analyzed yet, so we do not need to perform an explicit
@@ -5214,6 +5275,19 @@ package body Sem_Ch13 is
if In_Private_Part (Current_Scope) then
Analyze (PBody);
end if;
+
+ -- If there are no private declarations this may be an error that
+ -- will be diagnosed elsewhere. However, if this is a non-private
+ -- type that inherits invariants, it needs no completion and there
+ -- may be no private part. In this case insert invariant procedure
+ -- at end of current declarative list, and analyze at once, given
+ -- that the type is about to be frozen.
+
+ elsif not Is_Private_Type (Typ) then
+ Append_To (Visible_Decls, PDecl);
+ Append_To (Visible_Decls, PBody);
+ Analyze (PDecl);
+ Analyze (PBody);
end if;
end if;
end Build_Invariant_Procedure;
@@ -5222,16 +5296,16 @@ package body Sem_Ch13 is
-- Build_Predicate_Function --
------------------------------
- -- The procedure that is constructed here has the form
+ -- The procedure that is constructed here has the form:
- -- function typPredicate (Ixxx : typ) return Boolean is
- -- begin
- -- return
- -- exp1 and then exp2 and then ...
- -- and then typ1Predicate (typ1 (Ixxx))
- -- and then typ2Predicate (typ2 (Ixxx))
- -- and then ...;
- -- end typPredicate;
+ -- function typPredicate (Ixxx : typ) return Boolean is
+ -- begin
+ -- return
+ -- exp1 and then exp2 and then ...
+ -- and then typ1Predicate (typ1 (Ixxx))
+ -- and then typ2Predicate (typ2 (Ixxx))
+ -- and then ...;
+ -- end typPredicate;
-- Here exp1, and exp2 are expressions from Predicate pragmas. Note that
-- this is the point at which these expressions get analyzed, providing the
@@ -5485,6 +5559,7 @@ package body Sem_Ch13 is
Make_Defining_Identifier (Loc,
Chars => New_External_Name (Chars (Typ), "Predicate"));
Set_Has_Predicates (SId);
+ Set_Ekind (SId, E_Function);
Set_Predicate_Function (Typ, SId);
-- The predicate function is shared between views of a type.
@@ -7966,18 +8041,20 @@ package body Sem_Ch13 is
(Entity (Rep_Item), Aspect_Rep_Item (Rep_Item));
end Is_Pragma_Or_Corr_Pragma_Present_In_Rep_Item;
+ -- Start of processing for Inherit_Aspects_At_Freeze_Point
+
begin
-- A representation item is either subtype-specific (Size and Alignment
-- clauses) or type-related (all others). Subtype-specific aspects may
- -- differ for different subtypes of the same type.(RM 13.1.8)
+ -- differ for different subtypes of the same type (RM 13.1.8).
-- A derived type inherits each type-related representation aspect of
-- its parent type that was directly specified before the declaration of
- -- the derived type. (RM 13.1.15)
+ -- the derived type (RM 13.1.15).
-- A derived subtype inherits each subtype-specific representation
-- aspect of its parent subtype that was directly specified before the
- -- declaration of the derived type .(RM 13.1.15)
+ -- declaration of the derived type (RM 13.1.15).
-- The general processing involves inheriting a representation aspect
-- from a parent type whenever the first rep item (aspect specification,
@@ -7986,11 +8063,11 @@ package body Sem_Ch13 is
-- directly specified to Typ but to one of its parents.
-- ??? Note that, for now, just a limited number of representation
- -- aspects have been inherited here so far. Many of them are still
- -- inherited in Sem_Ch3. This will be fixed soon. Here is a
- -- non-exhaustive list of aspects that likely also need to be moved to
- -- this routine: Alignment, Component_Alignment, Component_Size,
- -- Machine_Radix, Object_Size, Pack, Predicates,
+ -- aspects have been inherited here so far. Many of them are
+ -- still inherited in Sem_Ch3. This will be fixed soon. Here is
+ -- a non- exhaustive list of aspects that likely also need to
+ -- be moved to this routine: Alignment, Component_Alignment,
+ -- Component_Size, Machine_Radix, Object_Size, Pack, Predicates,
-- Preelaborable_Initialization, RM_Size and Small.
if Nkind (Parent (Typ)) = N_Private_Extension_Declaration then
@@ -8029,7 +8106,7 @@ package body Sem_Ch13 is
Set_Is_Volatile (Typ);
end if;
- -- Default_Component_Value.
+ -- Default_Component_Value
if Is_Array_Type (Typ)
and then Has_Rep_Item (Typ, Name_Default_Component_Value, False)
@@ -8040,7 +8117,7 @@ package body Sem_Ch13 is
(Entity (Get_Rep_Item (Typ, Name_Default_Component_Value))));
end if;
- -- Default_Value.
+ -- Default_Value
if Is_Scalar_Type (Typ)
and then Has_Rep_Item (Typ, Name_Default_Value, False)
@@ -8135,6 +8212,7 @@ package body Sem_Ch13 is
-- Record type specific aspects
if Is_Record_Type (Typ) then
+
-- Bit_Order
if not Has_Rep_Item (Typ, Name_Bit_Order, False)
diff --git a/gcc/ada/sem_ch13.ads b/gcc/ada/sem_ch13.ads
index 0ac7386e8..611f3f1c6 100644
--- a/gcc/ada/sem_ch13.ads
+++ b/gcc/ada/sem_ch13.ads
@@ -46,6 +46,14 @@ package Sem_Ch13 is
-- order is specified and there is at least one component clause. Adjusts
-- component positions according to either Ada 95 or Ada 2005 (AI-133).
+ function Build_Invariant_Procedure_Declaration
+ (Typ : Entity_Id) return Node_Id;
+ -- If a type declaration has a specified invariant aspect, build the
+ -- declaration for the procedure at once, so that calls to it can be
+ -- generated before the body of the invariant procedure is built. This
+ -- is needed in the presence of public expression functions that return
+ -- the type in question.
+
procedure Build_Invariant_Procedure (Typ : Entity_Id; N : Node_Id);
-- Typ is a private type with invariants (indicated by Has_Invariants being
-- set for Typ, indicating the presence of pragma Invariant entries on the
diff --git a/gcc/ada/sem_ch3.adb b/gcc/ada/sem_ch3.adb
index b61821e65..7dd808c0d 100644
--- a/gcc/ada/sem_ch3.adb
+++ b/gcc/ada/sem_ch3.adb
@@ -23,6 +23,7 @@
-- --
------------------------------------------------------------------------------
+with Aspects; use Aspects;
with Atree; use Atree;
with Checks; use Checks;
with Debug; use Debug;
@@ -4974,12 +4975,9 @@ package body Sem_Ch3 is
Subtype_Indication (Component_Def));
end if;
- -- Ada 2012: if the element type has invariants we must create an
- -- invariant procedure for the array type as well.
-
- if Has_Invariants (Element_Type) then
- Set_Has_Invariants (T);
- end if;
+ -- There may be an invariant declared for the component type, but
+ -- the construction of the component invariant checking procedure
+ -- takes place during expansion.
end Array_Type_Declaration;
------------------------------------------------------
@@ -7544,16 +7542,38 @@ package body Sem_Ch3 is
-- subtype must be statically compatible with the parent
-- discriminant's subtype (3.7(15)).
- if Present (Corresponding_Discriminant (Discrim))
- and then
- not Subtypes_Statically_Compatible
- (Etype (Discrim),
- Etype (Corresponding_Discriminant (Discrim)))
- then
- Error_Msg_N
- ("subtype must be compatible with parent discriminant",
- Discrim);
- end if;
+ -- However, if the record contains an array constrained by
+ -- the discriminant but with some different bound, the compiler
+ -- attemps to create a smaller range for the discriminant type.
+ -- (See exp_ch3.Adjust_Discriminants). In this case, where
+ -- the discriminant type is a scalar type, the check must use
+ -- the original discriminant type in the parent declaration.
+
+ declare
+ Corr_Disc : constant Entity_Id :=
+ Corresponding_Discriminant (Discrim);
+ Disc_Type : constant Entity_Id := Etype (Discrim);
+ Corr_Type : Entity_Id;
+
+ begin
+ if Present (Corr_Disc) then
+ if Is_Scalar_Type (Disc_Type) then
+ Corr_Type :=
+ Entity (Discriminant_Type (Parent (Corr_Disc)));
+ else
+ Corr_Type := Etype (Corr_Disc);
+ end if;
+
+ if not
+ Subtypes_Statically_Compatible (Disc_Type, Corr_Type)
+ then
+ Error_Msg_N
+ ("subtype must be compatible "
+ & "with parent discriminant",
+ Discrim);
+ end if;
+ end if;
+ end;
Next_Discriminant (Discrim);
end loop;
@@ -14786,6 +14806,11 @@ package body Sem_Ch3 is
New_Id : Entity_Id;
Prev_Par : Node_Id;
+ procedure Check_Duplicate_Aspects;
+ -- Check that aspects specified in a completion have not been specified
+ -- already in the partial view. Type_Invariant and others can be
+ -- specified on either view but never on both.
+
procedure Tag_Mismatch;
-- Diagnose a tagged partial view whose full view is untagged.
-- We post the message on the full view, with a reference to
@@ -14794,6 +14819,38 @@ package body Sem_Ch3 is
-- so we determine the position of the error message from the
-- respective slocs of both.
+ -----------------------------
+ -- Check_Duplicate_Aspects --
+ -----------------------------
+ procedure Check_Duplicate_Aspects is
+ Prev_Aspects : constant List_Id := Aspect_Specifications (Prev_Par);
+ Full_Aspects : constant List_Id := Aspect_Specifications (N);
+ F_Spec, P_Spec : Node_Id;
+
+ begin
+ if Present (Prev_Aspects) and then Present (Full_Aspects) then
+ F_Spec := First (Full_Aspects);
+ while Present (F_Spec) loop
+ P_Spec := First (Prev_Aspects);
+ while Present (P_Spec) loop
+ if
+ Chars (Identifier (P_Spec)) = Chars (Identifier (F_Spec))
+ then
+ Error_Msg_N
+ ("aspect already specified in private declaration",
+ F_Spec);
+ Remove (F_Spec);
+ return;
+ end if;
+
+ Next (P_Spec);
+ end loop;
+
+ Next (F_Spec);
+ end loop;
+ end if;
+ end Check_Duplicate_Aspects;
+
------------------
-- Tag_Mismatch --
------------------
@@ -15003,6 +15060,10 @@ package body Sem_Ch3 is
("declaration of full view must appear in private part", N);
end if;
+ if Ada_Version >= Ada_2012 then
+ Check_Duplicate_Aspects;
+ end if;
+
Copy_And_Swap (Prev, Id);
Set_Has_Private_Declaration (Prev);
Set_Has_Private_Declaration (Id);
@@ -17010,18 +17071,7 @@ package body Sem_Ch3 is
when N_Attribute_Reference =>
return Attribute_Name (Original_Node (Exp)) = Name_Input;
- -- For a conditional expression, all dependent expressions must be
- -- legal constructs.
-
- when N_Conditional_Expression =>
- declare
- Then_Expr : constant Node_Id :=
- Next (First (Expressions (Original_Node (Exp))));
- Else_Expr : constant Node_Id := Next (Then_Expr);
- begin
- return OK_For_Limited_Init_In_05 (Typ, Then_Expr)
- and then OK_For_Limited_Init_In_05 (Typ, Else_Expr);
- end;
+ -- For a case expression, all dependent expressions must be legal
when N_Case_Expression =>
declare
@@ -17040,6 +17090,19 @@ package body Sem_Ch3 is
return True;
end;
+ -- For an if expression, all dependent expressions must be legal
+
+ when N_If_Expression =>
+ declare
+ Then_Expr : constant Node_Id :=
+ Next (First (Expressions (Original_Node (Exp))));
+ Else_Expr : constant Node_Id := Next (Then_Expr);
+ begin
+ return OK_For_Limited_Init_In_05 (Typ, Then_Expr)
+ and then
+ OK_For_Limited_Init_In_05 (Typ, Else_Expr);
+ end;
+
when others =>
return False;
end case;
@@ -19306,6 +19369,17 @@ package body Sem_Ch3 is
end if;
end Check_Anonymous_Access_Components;
+ ----------------------------------
+ -- Preanalyze_Assert_Expression --
+ ----------------------------------
+
+ procedure Preanalyze_Assert_Expression (N : Node_Id; T : Entity_Id) is
+ begin
+ In_Assertion_Expr := In_Assertion_Expr + 1;
+ Preanalyze_Spec_Expression (N, T);
+ In_Assertion_Expr := In_Assertion_Expr - 1;
+ end Preanalyze_Assert_Expression;
+
--------------------------------
-- Preanalyze_Spec_Expression --
--------------------------------
diff --git a/gcc/ada/sem_ch3.ads b/gcc/ada/sem_ch3.ads
index a57b65d7d..482450176 100644
--- a/gcc/ada/sem_ch3.ads
+++ b/gcc/ada/sem_ch3.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -246,6 +246,10 @@ package Sem_Ch3 is
-- This mechanism is also used for aspect specifications that have an
-- expression parameter that needs similar preanalysis.
+ procedure Preanalyze_Assert_Expression (N : Node_Id; T : Entity_Id);
+ -- Wrapper on Preanalyze_Spec_Expression for assertion expressions, so that
+ -- In_Assertion_Expr can be properly adjusted.
+
procedure Process_Full_View (N : Node_Id; Full_T, Priv_T : Entity_Id);
-- Process some semantic actions when the full view of a private type is
-- encountered and analyzed. The first action is to create the full views
diff --git a/gcc/ada/sem_ch4.adb b/gcc/ada/sem_ch4.adb
index d1cdeeabf..9d63e886a 100644
--- a/gcc/ada/sem_ch4.adb
+++ b/gcc/ada/sem_ch4.adb
@@ -1570,79 +1570,6 @@ package body Sem_Ch4 is
Operator_Check (N);
end Analyze_Concatenation_Rest;
- ------------------------------------
- -- Analyze_Conditional_Expression --
- ------------------------------------
-
- procedure Analyze_Conditional_Expression (N : Node_Id) is
- Condition : constant Node_Id := First (Expressions (N));
- Then_Expr : constant Node_Id := Next (Condition);
- Else_Expr : Node_Id;
-
- begin
- -- Defend against error of missing expressions from previous error
-
- if No (Then_Expr) then
- return;
- end if;
-
- Check_SPARK_Restriction ("conditional expression is not allowed", N);
-
- Else_Expr := Next (Then_Expr);
-
- if Comes_From_Source (N) then
- Check_Compiler_Unit (N);
- end if;
-
- Analyze_Expression (Condition);
- Analyze_Expression (Then_Expr);
-
- if Present (Else_Expr) then
- Analyze_Expression (Else_Expr);
- end if;
-
- -- If then expression not overloaded, then that decides the type
-
- if not Is_Overloaded (Then_Expr) then
- Set_Etype (N, Etype (Then_Expr));
-
- -- Case where then expression is overloaded
-
- else
- declare
- I : Interp_Index;
- It : Interp;
-
- begin
- Set_Etype (N, Any_Type);
-
- -- Shouldn't the following statement be down in the ELSE of the
- -- following loop? ???
-
- Get_First_Interp (Then_Expr, I, It);
-
- -- if no Else_Expression the conditional must be boolean
-
- if No (Else_Expr) then
- Set_Etype (N, Standard_Boolean);
-
- -- Else_Expression Present. For each possible intepretation of
- -- the Then_Expression, add it only if the Else_Expression has
- -- a compatible type.
-
- else
- while Present (It.Nam) loop
- if Has_Compatible_Type (Else_Expr, It.Typ) then
- Add_One_Interp (N, It.Typ, It.Typ);
- end if;
-
- Get_Next_Interp (I, It);
- end loop;
- end if;
- end;
- end if;
- end Analyze_Conditional_Expression;
-
-------------------------
-- Analyze_Equality_Op --
-------------------------
@@ -1981,6 +1908,79 @@ package body Sem_Ch4 is
Set_Etype (N, Etype (Expression (N)));
end Analyze_Expression_With_Actions;
+ ---------------------------
+ -- Analyze_If_Expression --
+ ---------------------------
+
+ procedure Analyze_If_Expression (N : Node_Id) is
+ Condition : constant Node_Id := First (Expressions (N));
+ Then_Expr : constant Node_Id := Next (Condition);
+ Else_Expr : Node_Id;
+
+ begin
+ -- Defend against error of missing expressions from previous error
+
+ if No (Then_Expr) then
+ return;
+ end if;
+
+ Check_SPARK_Restriction ("if expression is not allowed", N);
+
+ Else_Expr := Next (Then_Expr);
+
+ if Comes_From_Source (N) then
+ Check_Compiler_Unit (N);
+ end if;
+
+ Analyze_Expression (Condition);
+ Analyze_Expression (Then_Expr);
+
+ if Present (Else_Expr) then
+ Analyze_Expression (Else_Expr);
+ end if;
+
+ -- If then expression not overloaded, then that decides the type
+
+ if not Is_Overloaded (Then_Expr) then
+ Set_Etype (N, Etype (Then_Expr));
+
+ -- Case where then expression is overloaded
+
+ else
+ declare
+ I : Interp_Index;
+ It : Interp;
+
+ begin
+ Set_Etype (N, Any_Type);
+
+ -- Shouldn't the following statement be down in the ELSE of the
+ -- following loop? ???
+
+ Get_First_Interp (Then_Expr, I, It);
+
+ -- if no Else_Expression the conditional must be boolean
+
+ if No (Else_Expr) then
+ Set_Etype (N, Standard_Boolean);
+
+ -- Else_Expression Present. For each possible intepretation of
+ -- the Then_Expression, add it only if the Else_Expression has
+ -- a compatible type.
+
+ else
+ while Present (It.Nam) loop
+ if Has_Compatible_Type (Else_Expr, It.Typ) then
+ Add_One_Interp (N, It.Typ, It.Typ);
+ end if;
+
+ Get_Next_Interp (I, It);
+ end loop;
+ end if;
+ end;
+ end if;
+ end Analyze_If_Expression;
+
------------------------------------
-- Analyze_Indexed_Component_Form --
------------------------------------
@@ -2386,6 +2386,8 @@ package body Sem_Ch4 is
Process_Indexed_Component_Or_Slice;
end if;
end if;
+
+ Analyze_Dimension (N);
end Analyze_Indexed_Component_Form;
------------------------
@@ -3404,6 +3406,50 @@ package body Sem_Ch4 is
procedure Analyze_Quantified_Expression (N : Node_Id) is
QE_Scop : Entity_Id;
+ function Is_Empty_Range (Typ : Entity_Id) return Boolean;
+ -- If the iterator is part of a quantified expression, and the range is
+ -- known to be statically empty, emit a warning and replace expression
+ -- with its static value. Returns True if the replacement occurs.
+
+ --------------------
+ -- Is_Empty_Range --
+ --------------------
+
+ function Is_Empty_Range (Typ : Entity_Id) return Boolean is
+ Loc : constant Source_Ptr := Sloc (N);
+
+ begin
+ if Is_Array_Type (Typ)
+ and then Compile_Time_Known_Bounds (Typ)
+ and then
+ (Expr_Value (Type_Low_Bound (Etype (First_Index (Typ)))) >
+ Expr_Value (Type_High_Bound (Etype (First_Index (Typ)))))
+ then
+ Preanalyze_And_Resolve (Condition (N), Standard_Boolean);
+
+ if All_Present (N) then
+ Error_Msg_N
+ ("?quantified expression with ALL "
+ & "over a null range has value True", N);
+ Rewrite (N, New_Occurrence_Of (Standard_True, Loc));
+
+ else
+ Error_Msg_N
+ ("?quantified expression with SOME "
+ & "over a null range has value False", N);
+ Rewrite (N, New_Occurrence_Of (Standard_False, Loc));
+ end if;
+
+ Analyze (N);
+ return True;
+
+ else
+ return False;
+ end if;
+ end Is_Empty_Range;
+
+ -- Start of processing for Analyze_Quantified_Expression
+
begin
Check_SPARK_Restriction ("quantified expression is not allowed", N);
@@ -3425,6 +3471,13 @@ package body Sem_Ch4 is
if Present (Iterator_Specification (N)) then
Preanalyze (Iterator_Specification (N));
+
+ if Is_Entity_Name (Name (Iterator_Specification (N)))
+ and then Is_Empty_Range (Etype (Name (Iterator_Specification (N))))
+ then
+ return;
+ end if;
+
else
Preanalyze (Loop_Parameter_Specification (N));
end if;
@@ -5601,8 +5654,24 @@ package body Sem_Ch4 is
return;
end if;
+ -- If the right operand has a type compatible with T1, check for an
+ -- acceptable interpretation, unless T1 is limited (no predefined
+ -- equality available), or this is use of a "/=" for a tagged type.
+ -- In the latter case, possible interpretations of equality need to
+ -- be considered, we don't want the default inequality declared in
+ -- Standard to be chosen, and the "/=" will be rewritten as a
+ -- negation of "=" (see the end of Analyze_Equality_Op). This ensures
+ -- that that rewriting happens during analysis rather than being
+ -- delayed until expansion (this is needed for ASIS, which only sees
+ -- the unexpanded tree). Note that if the node is N_Op_Ne, but Op_Id
+ -- is Name_Op_Eq then we still proceed with the interpretation,
+ -- because that indicates the potential rewriting case where the
+ -- interpretation to consider is actually "=" and the node may be
+ -- about to be rewritten by Analyze_Equality_Op.
+
if T1 /= Standard_Void_Type
and then Has_Compatible_Type (R, T1)
+
and then
((not Is_Limited_Type (T1)
and then not Is_Limited_Composite (T1))
@@ -5611,6 +5680,11 @@ package body Sem_Ch4 is
(Is_Array_Type (T1)
and then not Is_Limited_Type (Component_Type (T1))
and then Available_Full_View_Of_Component (T1)))
+
+ and then
+ (Nkind (N) /= N_Op_Ne
+ or else not Is_Tagged_Type (T1)
+ or else Chars (Op_Id) = Name_Op_Eq)
then
if Found
and then Base_Type (T1) /= Base_Type (T_F)
@@ -5814,14 +5888,36 @@ package body Sem_Ch4 is
begin
if not Is_Overloaded (R) then
if Is_Numeric_Type (Etype (R)) then
- Add_One_Interp (N, Op_Id, Base_Type (Etype (R)));
+
+ -- In an instance a generic actual may be a numeric type even if
+ -- the formal in the generic unit was not. In that case, the
+ -- predefined operator was not a possible interpretation in the
+ -- generic, and cannot be one in the instance.
+
+ if In_Instance
+ and then
+ not Is_Numeric_Type (Corresponding_Generic_Type (Etype (R)))
+ then
+ null;
+ else
+ Add_One_Interp (N, Op_Id, Base_Type (Etype (R)));
+ end if;
end if;
else
Get_First_Interp (R, Index, It);
while Present (It.Typ) loop
if Is_Numeric_Type (It.Typ) then
- Add_One_Interp (N, Op_Id, Base_Type (It.Typ));
+ if In_Instance
+ and then
+ not Is_Numeric_Type
+ (Corresponding_Generic_Type (Etype (It.Typ)))
+ then
+ null;
+
+ else
+ Add_One_Interp (N, Op_Id, Base_Type (It.Typ));
+ end if;
end if;
Get_Next_Interp (Index, It);
diff --git a/gcc/ada/sem_ch4.ads b/gcc/ada/sem_ch4.ads
index 5e3150b69..0a196439f 100644
--- a/gcc/ada/sem_ch4.ads
+++ b/gcc/ada/sem_ch4.ads
@@ -33,10 +33,10 @@ package Sem_Ch4 is
procedure Analyze_Case_Expression (N : Node_Id);
procedure Analyze_Comparison_Op (N : Node_Id);
procedure Analyze_Concatenation (N : Node_Id);
- procedure Analyze_Conditional_Expression (N : Node_Id);
procedure Analyze_Equality_Op (N : Node_Id);
procedure Analyze_Explicit_Dereference (N : Node_Id);
procedure Analyze_Expression_With_Actions (N : Node_Id);
+ procedure Analyze_If_Expression (N : Node_Id);
procedure Analyze_Logical_Op (N : Node_Id);
procedure Analyze_Membership_Op (N : Node_Id);
procedure Analyze_Mod (N : Node_Id);
diff --git a/gcc/ada/sem_ch5.adb b/gcc/ada/sem_ch5.adb
index f3df8c5c6..f756dbcaf 100644
--- a/gcc/ada/sem_ch5.adb
+++ b/gcc/ada/sem_ch5.adb
@@ -1808,6 +1808,13 @@ package body Sem_Ch5 is
return;
else
Set_Etype (Def_Id, Entity (Element));
+
+ -- If the container has a variable indexing aspect, the
+ -- element is a variable and is modifiable in the loop.
+
+ if Present (Find_Aspect (Typ, Aspect_Variable_Indexing)) then
+ Set_Ekind (Def_Id, E_Variable);
+ end if;
end if;
end;
diff --git a/gcc/ada/sem_ch6.adb b/gcc/ada/sem_ch6.adb
index d48dd10e5..ea92eb932 100644
--- a/gcc/ada/sem_ch6.adb
+++ b/gcc/ada/sem_ch6.adb
@@ -869,6 +869,24 @@ package body Sem_Ch6 is
then
Rewrite (Expr, Convert_To (R_Type, Relocate_Node (Expr)));
Analyze_And_Resolve (Expr, R_Type);
+
+ -- If this is a local anonymous access to subprogram, the
+ -- accessibility check can be applied statically. The return is
+ -- illegal if the access type of the return expression is declared
+ -- inside of the subprogram (except if it is the subtype indication
+ -- of an extended return statement).
+
+ elsif Ekind (R_Type) = E_Anonymous_Access_Subprogram_Type then
+ if not Comes_From_Source (Current_Scope)
+ or else Ekind (Current_Scope) = E_Return_Statement
+ then
+ null;
+
+ elsif
+ Scope_Depth (Scope (Etype (Expr))) >= Scope_Depth (Scope_Id)
+ then
+ Error_Msg_N ("cannot return local access to subprogram", N);
+ end if;
end if;
-- If the result type is class-wide, then check that the return
@@ -3450,6 +3468,10 @@ package body Sem_Ch6 is
Push_Scope (Designator);
Process_Formals (Formals, N);
+ -- Check dimensions in N for formals with default expression
+
+ Analyze_Dimension_Formals (N, Formals);
+
-- Ada 2005 (AI-345): If this is an overriding operation of an
-- inherited interface operation, and the controlling type is
-- a synchronized type, replace the type with its corresponding
@@ -5734,14 +5756,31 @@ package body Sem_Ch6 is
declare
TSS_Name : constant TSS_Name_Type := Get_TSS_Name (New_Id);
+
begin
if TSS_Name /= TSS_Stream_Read
and then TSS_Name /= TSS_Stream_Write
and then TSS_Name /= TSS_Stream_Input
and then TSS_Name /= TSS_Stream_Output
then
- Conformance_Error
- ("\type of & does not match!", New_Formal);
+ -- Here we have a definite conformance error. It is worth
+ -- special casing the error message for the case of a
+ -- controlling formal (which excludes null).
+
+ if Is_Controlling_Formal (New_Formal) then
+ Error_Msg_Node_2 := Scope (New_Formal);
+ Conformance_Error
+ ("\controlling formal& of& excludes null, "
+ & "declaration must exclude null as well",
+ New_Formal);
+
+ -- Normal case (couldn't we give more detail here???)
+
+ else
+ Conformance_Error
+ ("\type of & does not match!", New_Formal);
+ end if;
+
return;
end if;
end;
@@ -8024,7 +8063,12 @@ package body Sem_Ch6 is
Set_Homonym (S, E);
- Append_Entity (S, Current_Scope);
+ if Is_Inherited_Operation (S) then
+ Append_Inherited_Subprogram (S);
+ else
+ Append_Entity (S, Current_Scope);
+ end if;
+
Set_Public_Status (S);
if Debug_Flag_E then
@@ -8655,10 +8699,6 @@ package body Sem_Ch6 is
and then
FCE (Expression (E1), Expression (E2));
- when N_Conditional_Expression =>
- return
- FCL (Expressions (E1), Expressions (E2));
-
when N_Explicit_Dereference =>
return
FCE (Prefix (E1), Prefix (E2));
@@ -8678,6 +8718,10 @@ package body Sem_Ch6 is
FCL (Parameter_Associations (E1),
Parameter_Associations (E2));
+ when N_If_Expression =>
+ return
+ FCL (Expressions (E1), Expressions (E2));
+
when N_Indexed_Component =>
return
FCE (Prefix (E1), Prefix (E2))
@@ -11074,6 +11118,12 @@ package body Sem_Ch6 is
Plist : List_Id := No_List;
-- List of generated postconditions
+ procedure Check_Access_Invariants (E : Entity_Id);
+ -- If the subprogram returns an access to a type with invariants, or
+ -- has access parameters whose designated type has an invariant, then
+ -- under the same visibility conditions as for other invariant checks,
+ -- the type invariant must be applied to the returned value.
+
function Grab_CC return Node_Id;
-- Prag contains an analyzed contract case pragma. This function copies
-- relevant components of the pragma, creates the corresponding Check
@@ -11087,6 +11137,9 @@ package body Sem_Ch6 is
-- references to parameters of the inherited subprogram to point to the
-- corresponding parameters of the current subprogram.
+ procedure Insert_After_Last_Declaration (Nod : Node_Id);
+ -- Insert node Nod after the last declaration of the context
+
function Invariants_Or_Predicates_Present return Boolean;
-- Determines if any invariants or predicates are present for any OUT
-- or IN OUT parameters of the subprogram, or (for a function) if the
@@ -11101,8 +11154,42 @@ package body Sem_Ch6 is
-- that an invariant check is required (for an IN OUT parameter, or
-- the returned value of a function.
- function Last_Implicit_Declaration return Node_Id;
- -- Return the last internally-generated declaration of N
+ -----------------------------
+ -- Check_Access_Invariants --
+ -----------------------------
+
+ procedure Check_Access_Invariants (E : Entity_Id) is
+ Call : Node_Id;
+ Obj : Node_Id;
+ Typ : Entity_Id;
+
+ begin
+ if Is_Access_Type (Etype (E))
+ and then not Is_Access_Constant (Etype (E))
+ then
+ Typ := Designated_Type (Etype (E));
+
+ if Has_Invariants (Typ)
+ and then Present (Invariant_Procedure (Typ))
+ and then Is_Public_Subprogram_For (Typ)
+ then
+ Obj :=
+ Make_Explicit_Dereference (Loc,
+ Prefix => New_Occurrence_Of (E, Loc));
+ Set_Etype (Obj, Typ);
+
+ Call := Make_Invariant_Call (Obj);
+
+ Append_To (Plist,
+ Make_If_Statement (Loc,
+ Condition =>
+ Make_Op_Ne (Loc,
+ Left_Opnd => Make_Null (Loc),
+ Right_Opnd => New_Occurrence_Of (E, Loc)),
+ Then_Statements => New_List (Call)));
+ end if;
+ end if;
+ end Check_Access_Invariants;
-------------
-- Grab_CC --
@@ -11281,6 +11368,21 @@ package body Sem_Ch6 is
return CP;
end Grab_PPC;
+ -----------------------------------
+ -- Insert_After_Last_Declaration --
+ -----------------------------------
+
+ procedure Insert_After_Last_Declaration (Nod : Node_Id) is
+ Decls : constant List_Id := Declarations (N);
+
+ begin
+ if No (Decls) then
+ Set_Declarations (N, New_List (Nod));
+ else
+ Append_To (Decls, Nod);
+ end if;
+ end Insert_After_Last_Declaration;
+
--------------------------------------
-- Invariants_Or_Predicates_Present --
--------------------------------------
@@ -11289,12 +11391,19 @@ package body Sem_Ch6 is
Formal : Entity_Id;
begin
- -- Check function return result
+ -- Check function return result. If result is an access type there
+ -- may be invariants on the designated type.
if Ekind (Designator) /= E_Procedure
and then Has_Invariants (Etype (Designator))
then
return True;
+
+ elsif Ekind (Designator) /= E_Procedure
+ and then Is_Access_Type (Etype (Designator))
+ and then Has_Invariants (Designated_Type (Etype (Designator)))
+ then
+ return True;
end if;
-- Check parameters
@@ -11302,9 +11411,13 @@ package body Sem_Ch6 is
Formal := First_Formal (Designator);
while Present (Formal) loop
if Ekind (Formal) /= E_In_Parameter
- and then
- (Has_Invariants (Etype (Formal))
- or else Present (Predicate_Function (Etype (Formal))))
+ and then (Has_Invariants (Etype (Formal))
+ or else Present (Predicate_Function (Etype (Formal))))
+ then
+ return True;
+
+ elsif Is_Access_Type (Etype (Formal))
+ and then Has_Invariants (Designated_Type (Etype (Formal)))
then
return True;
end if;
@@ -11342,10 +11455,14 @@ package body Sem_Ch6 is
-- If the subprogram declaration is not a list member, it must be
-- an Init_Proc, in which case we want to consider it to be a
-- public subprogram, since we do get initializations to deal with.
+ -- Other internally generated subprograms are not public.
- if not Is_List_Member (DD) then
+ if not Is_List_Member (DD) and then Is_Init_Proc (DD) then
return True;
+ elsif not Comes_From_Source (DD) then
+ return False;
+
-- Otherwise we test whether the subprogram is declared in the
-- visible declarations of the package containing the type.
@@ -11354,50 +11471,6 @@ package body Sem_Ch6 is
end if;
end Is_Public_Subprogram_For;
- -------------------------------
- -- Last_Implicit_Declaration --
- -------------------------------
-
- function Last_Implicit_Declaration return Node_Id is
- Loc : constant Source_Ptr := Sloc (N);
- Decls : List_Id := Declarations (N);
- Decl : Node_Id;
- Succ : Node_Id;
-
- begin
- if No (Decls) then
- Decls := New_List (Make_Null_Statement (Loc));
- Set_Declarations (N, Decls);
-
- elsif Is_Empty_List (Declarations (N)) then
- Append_To (Decls, Make_Null_Statement (Loc));
- end if;
-
- -- Implicit and source declarations may be interspersed. Search for
- -- the last implicit declaration which is either succeeded by a
- -- source construct or is the last node in the declarative list.
-
- Decl := First (Declarations (N));
- while Present (Decl) loop
- Succ := Next (Decl);
-
- -- The current declaration is the last one, do not return Empty
-
- if No (Succ) then
- exit;
-
- -- The successor is a source construct
-
- elsif Comes_From_Source (Succ) then
- exit;
- end if;
-
- Next (Decl);
- end loop;
-
- return Decl;
- end Last_Implicit_Declaration;
-
-- Start of processing for Process_PPCs
begin
@@ -11752,6 +11825,10 @@ package body Sem_Ch6 is
Append_To (Plist,
Make_Invariant_Call (New_Occurrence_Of (Rent, Loc)));
end if;
+
+ -- Same if return value is an access to type with invariants.
+
+ Check_Access_Invariants (Rent);
end;
-- Procedure rather than a function
@@ -11771,7 +11848,9 @@ package body Sem_Ch6 is
begin
Formal := First_Formal (Designator);
while Present (Formal) loop
- if Ekind (Formal) /= E_In_Parameter then
+ if Ekind (Formal) /= E_In_Parameter
+ or else Is_Access_Type (Etype (Formal))
+ then
Ftype := Etype (Formal);
if Has_Invariants (Ftype)
@@ -11783,6 +11862,8 @@ package body Sem_Ch6 is
(New_Occurrence_Of (Formal, Loc)));
end if;
+ Check_Access_Invariants (Formal);
+
if Present (Predicate_Function (Ftype)) then
Append_To (Plist,
Make_Predicate_Check
@@ -11803,7 +11884,26 @@ package body Sem_Ch6 is
-- The entity for the _Postconditions procedure
begin
- Insert_After (Last_Implicit_Declaration,
+ -- Insert the corresponding body of a post condition pragma after
+ -- the last declaration of the context. This ensures that the body
+ -- will not cause any premature freezing as it may mention types:
+
+ -- procedure Proc (Obj : Array_Typ) is
+ -- procedure _postconditions is
+ -- begin
+ -- ... Obj ...
+ -- end _postconditions;
+
+ -- subtype T is Array_Typ (Obj'First (1) .. Obj'Last (1));
+ -- begin
+
+ -- In the example above, Obj is of type T but the incorrect
+ -- placement of _postconditions will cause a crash in gigi due to
+ -- an out of order reference. The body of _postconditions must be
+ -- placed after the declaration of Temp to preserve correct
+ -- visibility.
+
+ Insert_After_Last_Declaration (
Make_Subprogram_Body (Loc,
Specification =>
Make_Procedure_Specification (Loc,
diff --git a/gcc/ada/sem_ch7.adb b/gcc/ada/sem_ch7.adb
index 326219d1f..a25e32833 100644
--- a/gcc/ada/sem_ch7.adb
+++ b/gcc/ada/sem_ch7.adb
@@ -28,6 +28,7 @@
-- handling of private and full declarations, and the construction of dispatch
-- tables for tagged types.
+with Aspects; use Aspects;
with Atree; use Atree;
with Debug; use Debug;
with Einfo; use Einfo;
@@ -1387,7 +1388,23 @@ package body Sem_Ch7 is
and then Nkind (Parent (E)) = N_Full_Type_Declaration
and then Has_Aspects (Parent (E))
then
- Build_Invariant_Procedure (E, N);
+ declare
+ ASN : Node_Id;
+
+ begin
+ ASN := First (Aspect_Specifications (Parent (E)));
+ while Present (ASN) loop
+ if Chars (Identifier (ASN)) = Name_Invariant
+ or else
+ Chars (Identifier (ASN)) = Name_Type_Invariant
+ then
+ Build_Invariant_Procedure (E, N);
+ exit;
+ end if;
+
+ Next (ASN);
+ end loop;
+ end;
end if;
Next_Entity (E);
@@ -2143,6 +2160,14 @@ package body Sem_Ch7 is
Set_Freeze_Node (Priv, Freeze_Node (Full));
+ -- Propagate information of type invariants, which may be specified
+ -- for the full view.
+
+ if Has_Invariants (Full) and not Has_Invariants (Priv) then
+ Set_Has_Invariants (Priv);
+ Set_Subprograms_For_Type (Priv, Subprograms_For_Type (Full));
+ end if;
+
if Is_Tagged_Type (Priv)
and then Is_Tagged_Type (Full)
and then not Error_Posted (Full)
diff --git a/gcc/ada/sem_ch8.adb b/gcc/ada/sem_ch8.adb
index b4348c5bd..ec94ed627 100644
--- a/gcc/ada/sem_ch8.adb
+++ b/gcc/ada/sem_ch8.adb
@@ -577,6 +577,8 @@ package body Sem_Ch8 is
else
Find_Expanded_Name (N);
end if;
+
+ Analyze_Dimension (N);
end Analyze_Expanded_Name;
---------------------------------------
@@ -1456,9 +1458,10 @@ package body Sem_Ch8 is
New_S : Entity_Id;
Is_Body : Boolean)
is
- Nam : constant Node_Id := Name (N);
- Sel : constant Node_Id := Selector_Name (Nam);
- Old_S : Entity_Id;
+ Nam : constant Node_Id := Name (N);
+ Sel : constant Node_Id := Selector_Name (Nam);
+ Is_Actual : constant Boolean := Present (Corresponding_Formal_Spec (N));
+ Old_S : Entity_Id;
begin
if Entity (Sel) = Any_Id then
@@ -1489,8 +1492,8 @@ package body Sem_Ch8 is
Inherit_Renamed_Profile (New_S, Old_S);
- -- The prefix can be an arbitrary expression that yields a task type,
- -- so it must be resolved.
+ -- The prefix can be an arbitrary expression that yields a task or
+ -- protected object, so it must be resolved.
Resolve (Prefix (Nam), Scope (Old_S));
end if;
@@ -1498,6 +1501,24 @@ package body Sem_Ch8 is
Set_Convention (New_S, Convention (Old_S));
Set_Has_Completion (New_S, Inside_A_Generic);
+ -- AI05-0225: If the renamed entity is a procedure or entry of a
+ -- protected object, the target object must be a variable.
+
+ if Ekind (Scope (Old_S)) in Protected_Kind
+ and then Ekind (New_S) = E_Procedure
+ and then not Is_Variable (Prefix (Nam))
+ then
+ if Is_Actual then
+ Error_Msg_N
+ ("target object of protected operation used as actual for "
+ & "formal procedure must be a variable", Nam);
+ else
+ Error_Msg_N
+ ("target object of protected operation renamed as procedure, "
+ & "must be a variable", Nam);
+ end if;
+ end if;
+
if Is_Body then
Check_Frozen_Renaming (N, New_S);
end if;
@@ -2572,6 +2593,8 @@ package body Sem_Ch8 is
Generate_Reference (Old_S, Nam);
end if;
+ Check_Internal_Protected_Use (N, Old_S);
+
-- For a renaming-as-body, require subtype conformance, but if the
-- declaration being completed has not been frozen, then inherit the
-- convention of the renamed subprogram prior to checking conformance
@@ -4998,10 +5021,14 @@ package body Sem_Ch8 is
Set_Entity_Or_Discriminal (N, E);
+ -- The name may designate a generalized reference, in which case
+ -- the dereference interpretation will be included.
+
if Ada_Version >= Ada_2012
and then
(Nkind (Parent (N)) in N_Subexpr
- or else Nkind (Parent (N)) = N_Object_Declaration)
+ or else Nkind_In (Parent (N), N_Object_Declaration,
+ N_Assignment_Statement))
then
Check_Implicit_Dereference (N, Etype (E));
end if;
@@ -6132,6 +6159,8 @@ package body Sem_Ch8 is
Analyze_Selected_Component (N);
end if;
+
+ Analyze_Dimension (N);
end Find_Selected_Component;
---------------
diff --git a/gcc/ada/sem_ch9.adb b/gcc/ada/sem_ch9.adb
index 6ee0bceeb..a81ea5c61 100644
--- a/gcc/ada/sem_ch9.adb
+++ b/gcc/ada/sem_ch9.adb
@@ -1345,9 +1345,10 @@ package body Sem_Ch9 is
-- Check for unreferenced variables etc. Before the Check_References
-- call, we transfer Never_Set_In_Source and Referenced flags from
-- parameters in the spec to the corresponding entities in the body,
- -- since we want the warnings on the body entities. Note that we do
- -- not have to transfer Referenced_As_LHS, since that flag can only
- -- be set for simple variables.
+ -- since we want the warnings on the body entities. Note that we do not
+ -- have to transfer Referenced_As_LHS, since that flag can only be set
+ -- for simple variables, but we include Has_Pragma_Unreferenced,
+ -- which may have been specified for a formal in the body.
-- At the same time, we set the flags on the spec entities to suppress
-- any warnings on the spec formals, since we also scan the spec.
@@ -1382,6 +1383,7 @@ package body Sem_Ch9 is
Set_Referenced (E2, Referenced (E1));
Set_Referenced (E1);
+ Set_Has_Pragma_Unreferenced (E2, Has_Pragma_Unreferenced (E1));
Set_Entry_Component (E2, Entry_Component (E1));
<<Continue>>
@@ -2379,6 +2381,18 @@ package body Sem_Ch9 is
end;
end if;
end if;
+
+ -- AI05-0225: the target protected object of a requeue must be a
+ -- variable. This is a binding interpretation that applies to all
+ -- versions of the language.
+
+ if Present (Target_Obj)
+ and then Ekind (Scope (Entry_Id)) in Protected_Kind
+ and then not Is_Variable (Target_Obj)
+ then
+ Error_Msg_N
+ ("target protected object of requeue must be a variable", N);
+ end if;
end Analyze_Requeue;
------------------------------
diff --git a/gcc/ada/sem_dim.adb b/gcc/ada/sem_dim.adb
index a2dd53c40..9b9de0a10 100644
--- a/gcc/ada/sem_dim.adb
+++ b/gcc/ada/sem_dim.adb
@@ -36,7 +36,9 @@ with Rtsfind; use Rtsfind;
with Sem; use Sem;
with Sem_Eval; use Sem_Eval;
with Sem_Res; use Sem_Res;
+with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
+with Sinput; use Sinput;
with Snames; use Snames;
with Stand; use Stand;
with Stringt; use Stringt;
@@ -190,6 +192,7 @@ package body Sem_Dim is
OK_For_Dimension : constant array (Node_Kind) of Boolean :=
(N_Attribute_Reference => True,
+ N_Expanded_Name => True,
N_Defining_Identifier => True,
N_Function_Call => True,
N_Identifier => True,
@@ -236,14 +239,6 @@ package body Sem_Dim is
-- that the dimensions of the returned type and of the returned object
-- match.
- procedure Analyze_Dimension_Function_Call (N : Node_Id);
- -- Subroutine of Analyze_Dimension for function call. General case:
- -- propagate the dimensions from the returned type to N. Elementary
- -- function case (Ada.Numerics.Generic_Elementary_Functions): If N
- -- is a Sqrt call, then evaluate the resulting dimensions as half the
- -- dimensions of the parameter. Otherwise, verify that each parameters
- -- are dimensionless.
-
procedure Analyze_Dimension_Has_Etype (N : Node_Id);
-- Subroutine of Analyze_Dimension for a subset of N_Has_Etype denoted by
-- the list below:
@@ -292,9 +287,17 @@ package body Sem_Dim is
function Dimensions_Of (N : Node_Id) return Dimension_Type;
-- Return the dimension vector of node N
- function Dimensions_Msg_Of (N : Node_Id) return String;
- -- Given a node, return "has dimension" followed by the dimension symbols
- -- of N or "is dimensionless" if N is dimensionless.
+ function Dimensions_Msg_Of
+ (N : Node_Id;
+ Description_Needed : Boolean := False) return String;
+ -- Given a node N, return the dimension symbols of N, preceded by "has
+ -- dimension" if Description_Needed. if N is dimensionless, return "[]", or
+ -- "is dimensionless" if Description_Needed.
+
+ procedure Dim_Warning_For_Numeric_Literal (N : Node_Id; Typ : Entity_Id);
+ -- Issue a warning on the given numeric literal N to indicate the
+ -- compilateur made the assumption that the literal is not dimensionless
+ -- but has the dimension of Typ.
procedure Eval_Op_Expon_With_Rational_Exponent
(N : Node_Id;
@@ -304,6 +307,9 @@ package body Sem_Dim is
function Exists (Dim : Dimension_Type) return Boolean;
-- Returns True iff Dim does not denote the null dimension
+ function Exists (Str : String_Id) return Boolean;
+ -- Returns True iff Str does not denote No_String
+
function Exists (Sys : System_Type) return Boolean;
-- Returns True iff Sys does not denote the null system
@@ -331,7 +337,7 @@ package body Sem_Dim is
-- Return True if Pos denotes the invalid position
procedure Move_Dimensions (From : Node_Id; To : Node_Id);
- -- Copy dimension vector of From to To, delete dimension vector of From
+ -- Copy dimension vector of From to To and delete dimension vector of From
procedure Remove_Dimensions (N : Node_Id);
-- Remove the dimension vector of node N
@@ -342,6 +348,10 @@ package body Sem_Dim is
procedure Set_Symbol (E : Entity_Id; Val : String_Id);
-- Associate a symbol representation of a dimension vector with a subtype
+ function String_From_Numeric_Literal (N : Node_Id) return String_Id;
+ -- Return the string that corresponds to the numeric litteral N as it
+ -- appears in the source.
+
function Symbol_Of (E : Entity_Id) return String_Id;
-- E denotes a subtype with a dimension. Return the symbol representation
-- of the dimension vector.
@@ -1122,14 +1132,14 @@ package body Sem_Dim is
procedure Analyze_Dimension (N : Node_Id) is
begin
- -- Aspect is an Ada 2012 feature
+ -- Aspect is an Ada 2012 feature. Note that there is no need to check
+ -- dimensions for nodes that don't come from source.
- if Ada_Version < Ada_2012 then
+ if Ada_Version < Ada_2012 or else not Comes_From_Source (N) then
return;
end if;
case Nkind (N) is
-
when N_Assignment_Statement =>
Analyze_Dimension_Assignment_Statement (N);
@@ -1142,10 +1152,9 @@ package body Sem_Dim is
when N_Extended_Return_Statement =>
Analyze_Dimension_Extended_Return_Statement (N);
- when N_Function_Call =>
- Analyze_Dimension_Function_Call (N);
-
when N_Attribute_Reference |
+ N_Expanded_Name |
+ N_Function_Call |
N_Identifier |
N_Indexed_Component |
N_Qualified_Expression |
@@ -1177,6 +1186,98 @@ package body Sem_Dim is
end case;
end Analyze_Dimension;
+ ---------------------------------------
+ -- Analyze_Dimension_Array_Aggregate --
+ ---------------------------------------
+
+ procedure Analyze_Dimension_Array_Aggregate
+ (N : Node_Id;
+ Comp_Typ : Entity_Id)
+ is
+ Comp_Ass : constant List_Id := Component_Associations (N);
+ Dims_Of_Comp_Typ : constant Dimension_Type := Dimensions_Of (Comp_Typ);
+ Exps : constant List_Id := Expressions (N);
+
+ Comp : Node_Id;
+ Expr : Node_Id;
+
+ Error_Detected : Boolean := False;
+ -- This flag is used in order to indicate if an error has been detected
+ -- so far by the compiler in this routine.
+
+ begin
+ -- Aspect is an Ada 2012 feature. Nothing to do here if the component
+ -- base type is not a dimensioned type.
+
+ -- Note that here the original node must come from source since the
+ -- original array aggregate may not have been entirely decorated.
+
+ if Ada_Version < Ada_2012
+ or else not Comes_From_Source (Original_Node (N))
+ or else not Has_Dimension_System (Base_Type (Comp_Typ))
+ then
+ return;
+ end if;
+
+ -- Check whether there is any positional component association
+
+ if Is_Empty_List (Exps) then
+ Comp := First (Comp_Ass);
+ else
+ Comp := First (Exps);
+ end if;
+
+ while Present (Comp) loop
+
+ -- Get the expression from the component
+
+ if Nkind (Comp) = N_Component_Association then
+ Expr := Expression (Comp);
+ else
+ Expr := Comp;
+ end if;
+
+ -- Issue an error if the dimensions of the component type and the
+ -- dimensions of the component mismatch.
+
+ -- Note that we must ensure the expression has been fully analyzed
+ -- since it may not be decorated at this point. We also don't want to
+ -- issue the same error message multiple times on the same expression
+ -- (may happen when an aggregate is converted into a positional
+ -- aggregate).
+
+ if Comes_From_Source (Original_Node (Expr))
+ and then Present (Etype (Expr))
+ and then Dimensions_Of (Expr) /= Dims_Of_Comp_Typ
+ and then Sloc (Comp) /= Sloc (Prev (Comp))
+ then
+ -- Check if an error has already been encountered so far
+
+ if not Error_Detected then
+ Error_Msg_N ("dimensions mismatch in array aggregate", N);
+ Error_Detected := True;
+ end if;
+
+ Error_Msg_N
+ ("\expected dimension "
+ & Dimensions_Msg_Of (Comp_Typ)
+ & ", found "
+ & Dimensions_Msg_Of (Expr),
+ Expr);
+ end if;
+
+ -- Look at the named components right after the positional components
+
+ if not Present (Next (Comp))
+ and then List_Containing (Comp) = Exps
+ then
+ Comp := First (Comp_Ass);
+ else
+ Next (Comp);
+ end if;
+ end loop;
+ end Analyze_Dimension_Array_Aggregate;
+
--------------------------------------------
-- Analyze_Dimension_Assignment_Statement --
--------------------------------------------
@@ -1205,8 +1306,8 @@ package body Sem_Dim is
is
begin
Error_Msg_N ("dimensions mismatch in assignment", N);
- Error_Msg_N ("\left-hand side " & Dimensions_Msg_Of (Lhs), N);
- Error_Msg_N ("\right-hand side " & Dimensions_Msg_Of (Rhs), N);
+ Error_Msg_N ("\left-hand side " & Dimensions_Msg_Of (Lhs, True), N);
+ Error_Msg_N ("\right-hand side " & Dimensions_Msg_Of (Rhs, True), N);
end Error_Dim_Msg_For_Assignment_Statement;
-- Start of processing for Analyze_Dimension_Assignment
@@ -1241,8 +1342,8 @@ package body Sem_Dim is
"dimensions",
N,
Entity (N));
- Error_Msg_N ("\left operand " & Dimensions_Msg_Of (L), N);
- Error_Msg_N ("\right operand " & Dimensions_Msg_Of (R), N);
+ Error_Msg_N ("\left operand " & Dimensions_Msg_Of (L, True), N);
+ Error_Msg_N ("\right operand " & Dimensions_Msg_Of (R, True), N);
end Error_Dim_Msg_For_Binary_Op;
-- Start of processing for Analyze_Dimension_Binary_Op
@@ -1390,6 +1491,186 @@ package body Sem_Dim is
end if;
end Analyze_Dimension_Binary_Op;
+ ----------------------------
+ -- Analyze_Dimension_Call --
+ ----------------------------
+
+ procedure Analyze_Dimension_Call (N : Node_Id; Nam : Entity_Id) is
+ Actuals : constant List_Id := Parameter_Associations (N);
+ Actual : Node_Id;
+ Dims_Of_Formal : Dimension_Type;
+ Formal : Node_Id;
+ Formal_Typ : Entity_Id;
+
+ Error_Detected : Boolean := False;
+ -- This flag is used in order to indicate if an error has been detected
+ -- so far by the compiler in this routine.
+
+ begin
+ -- Aspect is an Ada 2012 feature. Note that there is no need to check
+ -- dimensions for calls that don't come from source, or those that may
+ -- have semantic errors.
+
+ if Ada_Version < Ada_2012
+ or else not Comes_From_Source (N)
+ or else Error_Posted (N)
+ then
+ return;
+ end if;
+
+ -- Check the dimensions of the actuals, if any
+
+ if not Is_Empty_List (Actuals) then
+
+ -- Special processing for elementary functions
+
+ -- For Sqrt call, the resulting dimensions equal to half the
+ -- dimensions of the actual. For all other elementary calls, this
+ -- routine check that every actual is dimensionless.
+
+ if Nkind (N) = N_Function_Call then
+ Elementary_Function_Calls : declare
+ Dims_Of_Call : Dimension_Type;
+ Ent : Entity_Id := Nam;
+
+ function Is_Elementary_Function_Entity
+ (Sub_Id : Entity_Id) return Boolean;
+ -- Given Sub_Id, the original subprogram entity, return True
+ -- if call is to an elementary function (see Ada.Numerics.
+ -- Generic_Elementary_Functions).
+
+ -----------------------------------
+ -- Is_Elementary_Function_Entity --
+ -----------------------------------
+
+ function Is_Elementary_Function_Entity
+ (Sub_Id : Entity_Id) return Boolean
+ is
+ Loc : constant Source_Ptr := Sloc (Sub_Id);
+
+ begin
+ -- Is entity in Ada.Numerics.Generic_Elementary_Functions?
+
+ return
+ Loc > No_Location
+ and then
+ Is_RTU
+ (Cunit_Entity (Get_Source_Unit (Loc)),
+ Ada_Numerics_Generic_Elementary_Functions);
+ end Is_Elementary_Function_Entity;
+
+ -- Start of processing for Elementary_Function_Calls
+
+ begin
+ -- Get original subprogram entity following the renaming chain
+
+ if Present (Alias (Ent)) then
+ Ent := Alias (Ent);
+ end if;
+
+ -- Check the call is an Elementary function call
+
+ if Is_Elementary_Function_Entity (Ent) then
+
+ -- Sqrt function call case
+
+ if Chars (Ent) = Name_Sqrt then
+ Dims_Of_Call := Dimensions_Of (First_Actual (N));
+
+ -- Evaluates the resulting dimensions (i.e. half the
+ -- dimensions of the actual).
+
+ if Exists (Dims_Of_Call) then
+ for Position in Dims_Of_Call'Range loop
+ Dims_Of_Call (Position) :=
+ Dims_Of_Call (Position) *
+ Rational'(Numerator => 1, Denominator => 2);
+ end loop;
+
+ Set_Dimensions (N, Dims_Of_Call);
+ end if;
+
+ -- All other elementary functions case. Note that every
+ -- actual here should be dimensionless.
+
+ else
+ Actual := First_Actual (N);
+ while Present (Actual) loop
+ if Exists (Dimensions_Of (Actual)) then
+
+ -- Check if error has already been encountered
+
+ if not Error_Detected then
+ Error_Msg_NE ("dimensions mismatch in call of&",
+ N, Name (N));
+ Error_Detected := True;
+ end if;
+
+ Error_Msg_N ("\expected dimension [], found " &
+ Dimensions_Msg_Of (Actual),
+ Actual);
+ end if;
+
+ Next_Actual (Actual);
+ end loop;
+ end if;
+
+ -- Nothing more to do for elementary functions
+
+ return;
+ end if;
+ end Elementary_Function_Calls;
+ end if;
+
+ -- General case. Check, for each parameter, the dimensions of the
+ -- actual and its corresponding formal match. Otherwise, complain.
+
+ Actual := First_Actual (N);
+ Formal := First_Formal (Nam);
+
+ while Present (Formal) loop
+
+ -- A missing corresponding actual indicates that the analysis of
+ -- the call was aborted due to a previous error.
+
+ if No (Actual) then
+ Cascaded_Error;
+ return;
+ end if;
+
+ Formal_Typ := Etype (Formal);
+ Dims_Of_Formal := Dimensions_Of (Formal_Typ);
+
+ -- If the formal is not dimensionless, check dimensions of formal
+ -- and actual match. Otherwise, complain.
+
+ if Exists (Dims_Of_Formal)
+ and then Dimensions_Of (Actual) /= Dims_Of_Formal
+ then
+ -- Check if an error has already been encountered so far
+
+ if not Error_Detected then
+ Error_Msg_NE ("dimensions mismatch in& call", N, Name (N));
+ Error_Detected := True;
+ end if;
+
+ Error_Msg_N
+ ("\expected dimension " & Dimensions_Msg_Of (Formal_Typ)
+ & ", found " & Dimensions_Msg_Of (Actual), Actual);
+ end if;
+
+ Next_Actual (Actual);
+ Next_Formal (Formal);
+ end loop;
+ end if;
+
+ -- For function calls, propagate the dimensions from the returned type
+
+ if Nkind (N) = N_Function_Call then
+ Analyze_Dimension_Has_Etype (N);
+ end if;
+ end Analyze_Dimension_Call;
+
---------------------------------------------
-- Analyze_Dimension_Component_Declaration --
---------------------------------------------
@@ -1418,26 +1699,39 @@ package body Sem_Dim is
Expr : Node_Id) is
begin
Error_Msg_N ("dimensions mismatch in component declaration", N);
- Error_Msg_N ("\component type " & Dimensions_Msg_Of (Etyp), N);
- Error_Msg_N ("\component expression " & Dimensions_Msg_Of (Expr), N);
+ Error_Msg_N ("\expected dimension "
+ & Dimensions_Msg_Of (Etyp)
+ & ", found "
+ & Dimensions_Msg_Of (Expr),
+ Expr);
end Error_Dim_Msg_For_Component_Declaration;
-- Start of processing for Analyze_Dimension_Component_Declaration
begin
+ -- Expression is present
+
if Present (Expr) then
Dims_Of_Expr := Dimensions_Of (Expr);
- -- Return an error if the dimension of the expression and the
- -- dimension of the type mismatch.
+ -- Check dimensions match
if Dims_Of_Etyp /= Dims_Of_Expr then
- Error_Dim_Msg_For_Component_Declaration (N, Etyp, Expr);
- end if;
+ -- Numeric literal case. Issue a warning if the object type is not
+ -- dimensionless to indicate the literal is treated as if its
+ -- dimension matches the type dimension.
- -- Removal of dimensions in expression
+ if Nkind_In (Original_Node (Expr), N_Real_Literal,
+ N_Integer_Literal)
+ then
+ Dim_Warning_For_Numeric_Literal (Expr, Etyp);
- Remove_Dimensions (Expr);
+ -- Issue a dimension mismatch error for all other cases
+
+ else
+ Error_Dim_Msg_For_Component_Declaration (N, Etyp, Expr);
+ end if;
+ end if;
end if;
end Analyze_Dimension_Component_Declaration;
@@ -1446,38 +1740,37 @@ package body Sem_Dim is
-------------------------------------------------
procedure Analyze_Dimension_Extended_Return_Statement (N : Node_Id) is
- Return_Ent : constant Entity_Id :=
- Return_Statement_Entity (N);
- Return_Etyp : constant Entity_Id :=
- Etype (Return_Applies_To (Return_Ent));
- Dims_Of_Return_Etyp : constant Dimension_Type :=
- Dimensions_Of (Return_Etyp);
- Return_Obj_Decls : constant List_Id :=
- Return_Object_Declarations (N);
- Dims_Of_Return_Obj_Id : Dimension_Type;
- Return_Obj_Decl : Node_Id;
- Return_Obj_Id : Entity_Id;
+ Return_Ent : constant Entity_Id := Return_Statement_Entity (N);
+ Return_Etyp : constant Entity_Id :=
+ Etype (Return_Applies_To (Return_Ent));
+ Return_Obj_Decls : constant List_Id := Return_Object_Declarations (N);
+ Return_Obj_Decl : Node_Id;
+ Return_Obj_Id : Entity_Id;
+ Return_Obj_Typ : Entity_Id;
procedure Error_Dim_Msg_For_Extended_Return_Statement
- (N : Node_Id;
- Return_Etyp : Entity_Id;
- Return_Obj_Id : Entity_Id);
+ (N : Node_Id;
+ Return_Etyp : Entity_Id;
+ Return_Obj_Typ : Entity_Id);
-- Error using Error_Msg_N at node N. Output the dimensions of the
- -- returned type Return_Etyp and the returned object Return_Obj_Id of N.
+ -- returned type Return_Etyp and the returned object type Return_Obj_Typ
+ -- of N.
-------------------------------------------------
-- Error_Dim_Msg_For_Extended_Return_Statement --
-------------------------------------------------
procedure Error_Dim_Msg_For_Extended_Return_Statement
- (N : Node_Id;
- Return_Etyp : Entity_Id;
- Return_Obj_Id : Entity_Id)
+ (N : Node_Id;
+ Return_Etyp : Entity_Id;
+ Return_Obj_Typ : Entity_Id)
is
begin
Error_Msg_N ("dimensions mismatch in extended return statement", N);
- Error_Msg_N ("\returned type " & Dimensions_Msg_Of (Return_Etyp), N);
- Error_Msg_N ("\returned object " & Dimensions_Msg_Of (Return_Obj_Id),
+ Error_Msg_N ("\expected dimension "
+ & Dimensions_Msg_Of (Return_Etyp)
+ & ", found "
+ & Dimensions_Msg_Of (Return_Obj_Typ),
N);
end Error_Dim_Msg_For_Extended_Return_Statement;
@@ -1491,11 +1784,15 @@ package body Sem_Dim is
Return_Obj_Id := Defining_Identifier (Return_Obj_Decl);
if Is_Return_Object (Return_Obj_Id) then
- Dims_Of_Return_Obj_Id := Dimensions_Of (Return_Obj_Id);
+ Return_Obj_Typ := Etype (Return_Obj_Id);
+
+ -- Issue an error message if dimensions mismatch
- if Dims_Of_Return_Etyp /= Dims_Of_Return_Obj_Id then
+ if Dimensions_Of (Return_Etyp) /=
+ Dimensions_Of (Return_Obj_Typ)
+ then
Error_Dim_Msg_For_Extended_Return_Statement
- (N, Return_Etyp, Return_Obj_Id);
+ (N, Return_Etyp, Return_Obj_Typ);
return;
end if;
end if;
@@ -1506,106 +1803,120 @@ package body Sem_Dim is
end if;
end Analyze_Dimension_Extended_Return_Statement;
- -------------------------------------
- -- Analyze_Dimension_Function_Call --
- -------------------------------------
+ -----------------------------------------------------
+ -- Analyze_Dimension_Extension_Or_Record_Aggregate --
+ -----------------------------------------------------
- -- Propagate the dimensions from the returned type to the call node. Note
- -- that there is a special treatment for elementary function calls. Indeed
- -- for Sqrt call, the resulting dimensions equal to half the dimensions of
- -- the actual, and for other elementary calls, this routine check that
- -- every actuals are dimensionless.
+ procedure Analyze_Dimension_Extension_Or_Record_Aggregate (N : Node_Id) is
+ Comp : Node_Id;
+ Comp_Id : Entity_Id;
+ Comp_Typ : Entity_Id;
+ Expr : Node_Id;
- procedure Analyze_Dimension_Function_Call (N : Node_Id) is
- Actuals : constant List_Id := Parameter_Associations (N);
- Name_Call : constant Node_Id := Name (N);
- Actual : Node_Id;
- Dims_Of_Actual : Dimension_Type;
- Dims_Of_Call : Dimension_Type;
- Ent : Entity_Id;
+ Error_Detected : Boolean := False;
+ -- This flag is used in order to indicate if an error has been detected
+ -- so far by the compiler in this routine.
- function Is_Elementary_Function_Entity (E : Entity_Id) return Boolean;
- -- Given E, the original subprogram entity, return True if call is to an
- -- elementary function (see Ada.Numerics.Generic_Elementary_Functions).
+ begin
+ -- Aspect is an Ada 2012 feature. Note that there is no need to check
+ -- dimensions for aggregates that don't come from source.
- -----------------------------------
- -- Is_Elementary_Function_Entity --
- -----------------------------------
+ if Ada_Version < Ada_2012 or else not Comes_From_Source (N) then
+ return;
+ end if;
- function Is_Elementary_Function_Entity (E : Entity_Id) return Boolean is
- Loc : constant Source_Ptr := Sloc (E);
+ Comp := First (Component_Associations (N));
+ while Present (Comp) loop
+ Comp_Id := Entity (First (Choices (Comp)));
+ Comp_Typ := Etype (Comp_Id);
- begin
- -- Is function entity in Ada.Numerics.Generic_Elementary_Functions?
+ -- Check the component type is either a dimensioned type or a
+ -- dimensioned subtype.
- return
- Loc > No_Location
- and then
- Is_RTU
- (Cunit_Entity (Get_Source_Unit (Loc)),
- Ada_Numerics_Generic_Elementary_Functions);
- end Is_Elementary_Function_Entity;
+ if Has_Dimension_System (Base_Type (Comp_Typ)) then
+ Expr := Expression (Comp);
- -- Start of processing for Analyze_Dimension_Function_Call
+ -- Issue an error if the dimensions of the component type and the
+ -- dimensions of the component mismatch.
- begin
- -- Look for elementary function call
+ if Dimensions_Of (Expr) /= Dimensions_Of (Comp_Typ) then
- if Is_Entity_Name (Name_Call) then
- Ent := Entity (Name_Call);
+ -- Check if an error has already been encountered so far
- -- Get the original subprogram entity following the renaming chain
+ if not Error_Detected then
- if Present (Alias (Ent)) then
- Ent := Alias (Ent);
- end if;
+ -- Extension aggregate case
- -- Elementary function case
+ if Nkind (N) = N_Extension_Aggregate then
+ Error_Msg_N
+ ("dimensions mismatch in extension aggregate", N);
- if Is_Elementary_Function_Entity (Ent) then
+ -- Record aggregate case
- -- Sqrt function call case
+ else
+ Error_Msg_N
+ ("dimensions mismatch in record aggregate", N);
+ end if;
- if Chars (Ent) = Name_Sqrt then
- Dims_Of_Call := Dimensions_Of (First (Actuals));
+ Error_Detected := True;
+ end if;
- if Exists (Dims_Of_Call) then
- for Position in Dims_Of_Call'Range loop
- Dims_Of_Call (Position) :=
- Dims_Of_Call (Position) * Rational'(Numerator => 1,
- Denominator => 2);
- end loop;
+ Error_Msg_N
+ ("\expected dimension "
+ & Dimensions_Msg_Of (Comp_Typ)
+ & ", found "
+ & Dimensions_Msg_Of (Expr),
+ Comp);
+ end if;
+ end if;
- Set_Dimensions (N, Dims_Of_Call);
- end if;
+ Next (Comp);
+ end loop;
+ end Analyze_Dimension_Extension_Or_Record_Aggregate;
- -- All other elementary functions case. Note that every actual
- -- here should be dimensionless.
+ -------------------------------
+ -- Analyze_Dimension_Formals --
+ -------------------------------
- else
- Actual := First (Actuals);
- while Present (Actual) loop
- Dims_Of_Actual := Dimensions_Of (Actual);
-
- if Exists (Dims_Of_Actual) then
- Error_Msg_NE ("parameter of& must be dimensionless",
- Actual, Name_Call);
- Error_Msg_N ("\parameter " & Dimensions_Msg_Of (Actual),
- Actual);
- end if;
+ procedure Analyze_Dimension_Formals (N : Node_Id; Formals : List_Id) is
+ Dims_Of_Typ : Dimension_Type;
+ Formal : Node_Id;
+ Typ : Entity_Id;
- Next (Actual);
- end loop;
- end if;
+ begin
+ -- Aspect is an Ada 2012 feature. Note that there is no need to check
+ -- dimensions for sub specs that don't come from source.
- return;
- end if;
+ if Ada_Version < Ada_2012 or else not Comes_From_Source (N) then
+ return;
end if;
- -- Other cases
+ Formal := First (Formals);
+ while Present (Formal) loop
+ Typ := Parameter_Type (Formal);
+ Dims_Of_Typ := Dimensions_Of (Typ);
- Analyze_Dimension_Has_Etype (N);
- end Analyze_Dimension_Function_Call;
+ if Exists (Dims_Of_Typ) then
+ declare
+ Expr : constant Node_Id := Expression (Formal);
+
+ begin
+ -- Issue a warning if Expr is a numeric literal and if its
+ -- dimensions differ with the dimensions of the formal type.
+
+ if Present (Expr)
+ and then Dims_Of_Typ /= Dimensions_Of (Expr)
+ and then Nkind_In (Original_Node (Expr), N_Real_Literal,
+ N_Integer_Literal)
+ then
+ Dim_Warning_For_Numeric_Literal (Expr, Etype (Typ));
+ end if;
+ end;
+ end if;
+
+ Next (Formal);
+ end loop;
+ end Analyze_Dimension_Formals;
---------------------------------
-- Analyze_Dimension_Has_Etype --
@@ -1613,27 +1924,45 @@ package body Sem_Dim is
procedure Analyze_Dimension_Has_Etype (N : Node_Id) is
Etyp : constant Entity_Id := Etype (N);
- Dims_Of_Etyp : constant Dimension_Type := Dimensions_Of (Etyp);
+ Dims_Of_Etyp : Dimension_Type := Dimensions_Of (Etyp);
begin
- -- Propagation of the dimensions from the type
+ -- General case. Propagation of the dimensions from the type
if Exists (Dims_Of_Etyp) then
Set_Dimensions (N, Dims_Of_Etyp);
- -- Propagation of the dimensions from the entity for identifier whose
- -- entity is a non-dimensionless consant.
+ -- Identifier case. Propagate the dimensions from the entity for
+ -- identifier whose entity is a non-dimensionless constant.
+
+ elsif Nkind (N) = N_Identifier then
+ Analyze_Dimension_Identifier : declare
+ Id : constant Entity_Id := Entity (N);
+ begin
+ if Ekind (Id) = E_Constant
+ and then Exists (Dimensions_Of (Id))
+ then
+ Set_Dimensions (N, Dimensions_Of (Id));
+ end if;
+ end Analyze_Dimension_Identifier;
- elsif Nkind (N) = N_Identifier
- and then Exists (Dimensions_Of (Entity (N)))
+ -- Attribute reference case. Propagate the dimensions from the prefix.
+
+ elsif Nkind (N) = N_Attribute_Reference
+ and then Has_Dimension_System (Base_Type (Etyp))
then
- Set_Dimensions (N, Dimensions_Of (Entity (N)));
+ Dims_Of_Etyp := Dimensions_Of (Prefix (N));
+
+ -- Check the prefix is not dimensionless
+
+ if Exists (Dims_Of_Etyp) then
+ Set_Dimensions (N, Dims_Of_Etyp);
+ end if;
end if;
-- Removal of dimensions in expression
case Nkind (N) is
-
when N_Attribute_Reference |
N_Indexed_Component =>
declare
@@ -1659,7 +1988,6 @@ package body Sem_Dim is
Remove_Dimensions (Selector_Name (N));
when others => null;
-
end case;
end Analyze_Dimension_Has_Etype;
@@ -1691,8 +2019,12 @@ package body Sem_Dim is
Expr : Node_Id) is
begin
Error_Msg_N ("dimensions mismatch in object declaration", N);
- Error_Msg_N ("\object type " & Dimensions_Msg_Of (Etyp), N);
- Error_Msg_N ("\object expression " & Dimensions_Msg_Of (Expr), N);
+ Error_Msg_N
+ ("\expected dimension "
+ & Dimensions_Msg_Of (Etyp)
+ & ", found "
+ & Dimensions_Msg_Of (Expr),
+ Expr);
end Error_Dim_Msg_For_Object_Declaration;
-- Start of processing for Analyze_Dimension_Object_Declaration
@@ -1703,22 +2035,28 @@ package body Sem_Dim is
if Present (Expr) then
Dim_Of_Expr := Dimensions_Of (Expr);
- -- Case when expression is not a literal and when dimensions of the
- -- expression and of the type mismatch
+ -- Check dimensions match
- if not Nkind_In (Original_Node (Expr),
- N_Real_Literal,
- N_Integer_Literal)
- and then Dim_Of_Expr /= Dim_Of_Etyp
- then
- -- Propagate the dimension from the expression to the object
- -- entity when the object is a constant whose type is a
- -- dimensioned type.
+ if Dim_Of_Expr /= Dim_Of_Etyp then
+
+ -- Numeric literal case. Issue a warning if the object type is not
+ -- dimensionless to indicate the literal is treated as if its
+ -- dimension matches the type dimension.
+
+ if Nkind_In (Original_Node (Expr), N_Real_Literal,
+ N_Integer_Literal)
+ then
+ Dim_Warning_For_Numeric_Literal (Expr, Etyp);
+
+ -- Case of object is a constant whose type is a dimensioned type
+
+ elsif Constant_Present (N) and then not Exists (Dim_Of_Etyp) then
+
+ -- Propagate dimension from expression to object entity
- if Constant_Present (N) and then not Exists (Dim_Of_Etyp) then
Set_Dimensions (Id, Dim_Of_Expr);
- -- Otherwise, issue an error message
+ -- For all other cases, issue an error message
else
Error_Dim_Msg_For_Object_Declaration (N, Etyp, Expr);
@@ -1755,11 +2093,13 @@ package body Sem_Dim is
Sub_Mark : Node_Id;
Renamed_Name : Node_Id) is
begin
- Error_Msg_N ("dimensions mismatch in object renaming declaration",
- N);
- Error_Msg_N ("\type " & Dimensions_Msg_Of (Sub_Mark), N);
- Error_Msg_N ("\renamed object " & Dimensions_Msg_Of (Renamed_Name),
- N);
+ Error_Msg_N ("dimensions mismatch in object renaming declaration", N);
+ Error_Msg_N
+ ("\expected dimension "
+ & Dimensions_Msg_Of (Sub_Mark)
+ & ", found "
+ & Dimensions_Msg_Of (Renamed_Name),
+ Renamed_Name);
end Error_Dim_Msg_For_Object_Renaming_Declaration;
-- Start of processing for Analyze_Dimension_Object_Renaming_Declaration
@@ -1802,8 +2142,12 @@ package body Sem_Dim is
is
begin
Error_Msg_N ("dimensions mismatch in return statement", N);
- Error_Msg_N ("\returned type " & Dimensions_Msg_Of (Return_Etyp), N);
- Error_Msg_N ("\returned expression " & Dimensions_Msg_Of (Expr), N);
+ Error_Msg_N
+ ("\expected dimension "
+ & Dimensions_Msg_Of (Return_Etyp)
+ & ", found "
+ & Dimensions_Msg_Of (Expr),
+ Expr);
end Error_Dim_Msg_For_Simple_Return_Statement;
-- Start of processing for Analyze_Dimension_Simple_Return_Statement
@@ -1838,7 +2182,9 @@ package body Sem_Dim is
-- it cannot inherit a dimension from its subtype.
if Exists (Dims_Of_Id) then
- Error_Msg_N ("subtype& already" & Dimensions_Msg_Of (Id), N);
+ Error_Msg_N
+ ("subtype& already" & Dimensions_Msg_Of (Id, True), N);
+
else
Set_Dimensions (Id, Dims_Of_Etyp);
Set_Symbol (Id, Symbol_Of (Etyp));
@@ -1880,6 +2226,26 @@ package body Sem_Dim is
end case;
end Analyze_Dimension_Unary_Op;
+ ---------------------
+ -- Copy_Dimensions --
+ ---------------------
+
+ procedure Copy_Dimensions (From, To : Node_Id) is
+ Dims_Of_From : constant Dimension_Type := Dimensions_Of (From);
+
+ begin
+ -- Ignore if not Ada 2012 or beyond
+
+ if Ada_Version < Ada_2012 then
+ return;
+
+ -- For Ada 2012, Copy the dimension of 'From to 'To'
+
+ elsif Exists (Dims_Of_From) then
+ Set_Dimensions (To, Dims_Of_From);
+ end if;
+ end Copy_Dimensions;
+
--------------------------
-- Create_Rational_From --
--------------------------
@@ -2011,7 +2377,10 @@ package body Sem_Dim is
-- Dimensions_Msg_Of --
-----------------------
- function Dimensions_Msg_Of (N : Node_Id) return String is
+ function Dimensions_Msg_Of
+ (N : Node_Id;
+ Description_Needed : Boolean := False) return String
+ is
Dims_Of_N : constant Dimension_Type := Dimensions_Of (N);
Dimensions_Msg : Name_Id;
System : System_Type;
@@ -2021,13 +2390,32 @@ package body Sem_Dim is
Name_Len := 0;
+ -- N is not dimensionless
+
if Exists (Dims_Of_N) then
System := System_Of (Base_Type (Etype (N)));
- Add_Str_To_Name_Buffer ("has dimension ");
+
+ -- When Description_Needed, add to string "has dimension " before the
+ -- actual dimension.
+
+ if Description_Needed then
+ Add_Str_To_Name_Buffer ("has dimension ");
+ end if;
+
Add_String_To_Name_Buffer
(From_Dim_To_Str_Of_Dim_Symbols (Dims_Of_N, System, True));
- else
+
+ -- N is dimensionless
+
+ -- When Description_Needed, return "is dimensionless"
+
+ elsif Description_Needed then
Add_Str_To_Name_Buffer ("is dimensionless");
+
+ -- Otherwise, return "[]"
+
+ else
+ Add_Str_To_Name_Buffer ("[]");
end if;
Dimensions_Msg := Name_Find;
@@ -2045,6 +2433,27 @@ package body Sem_Dim is
return Dimension_Table_Range (Key mod 511);
end Dimension_Table_Hash;
+ -------------------------------------
+ -- Dim_Warning_For_Numeric_Literal --
+ -------------------------------------
+
+ procedure Dim_Warning_For_Numeric_Literal (N : Node_Id; Typ : Entity_Id) is
+ begin
+ -- Initialize name buffer
+
+ Name_Len := 0;
+
+ Add_String_To_Name_Buffer (String_From_Numeric_Literal (N));
+
+ -- Insert a blank between the literal and the symbol
+ Add_Str_To_Name_Buffer (" ");
+
+ Add_String_To_Name_Buffer (Symbol_Of (Typ));
+
+ Error_Msg_Name_1 := Name_Find;
+ Error_Msg_N ("?assumed to be%%", N);
+ end Dim_Warning_For_Numeric_Literal;
+
----------------------------------------
-- Eval_Op_Expon_For_Dimensioned_Type --
----------------------------------------
@@ -2243,6 +2652,11 @@ package body Sem_Dim is
return Dim /= Null_Dimension;
end Exists;
+ function Exists (Str : String_Id) return Boolean is
+ begin
+ return Str /= No_String;
+ end Exists;
+
function Exists (Sys : System_Type) return Boolean is
begin
return Sys /= Null_System;
@@ -2311,7 +2725,7 @@ package body Sem_Dim is
Dims_Of_Actual : Dimension_Type;
Etyp : Entity_Id;
New_Str_Lit : Node_Id := Empty;
- System : System_Type;
+ Symbols : String_Id;
Is_Put_Dim_Of : Boolean := False;
-- This flag is used in order to differentiate routines Put and
@@ -2336,7 +2750,8 @@ package body Sem_Dim is
-----------------
function Has_Symbols return Boolean is
- Actual : Node_Id;
+ Actual : Node_Id;
+ Actual_Str : Node_Id;
begin
Actual := First (Actuals);
@@ -2344,16 +2759,50 @@ package body Sem_Dim is
-- Look for a symbols parameter association in the list of actuals
while Present (Actual) loop
- if Nkind (Actual) = N_Parameter_Association
+
+ -- Positional parameter association case when the actual is a
+ -- string literal.
+
+ if Nkind (Actual) = N_String_Literal then
+ Actual_Str := Actual;
+
+ -- Named parameter association case when selector name is Symbol
+
+ elsif Nkind (Actual) = N_Parameter_Association
and then Chars (Selector_Name (Actual)) = Name_Symbol
then
+ Actual_Str := Explicit_Actual_Parameter (Actual);
+
+ -- Ignore all other cases
+
+ else
+ Actual_Str := Empty;
+ end if;
+
+ if Present (Actual_Str) then
+
-- Return True if the actual comes from source or if the string
-- of symbols doesn't have the default value (i.e. it is "").
- return Comes_From_Source (Actual)
- or else
- String_Length
- (Strval (Explicit_Actual_Parameter (Actual))) /= 0;
+ if Comes_From_Source (Actual)
+ or else String_Length (Strval (Actual_Str)) /= 0
+ then
+ -- Complain only if the actual comes from source or if it
+ -- hasn't been fully analyzed yet.
+
+ if Comes_From_Source (Actual)
+ or else not Analyzed (Actual)
+ then
+ Error_Msg_N ("Symbol parameter should not be provided",
+ Actual);
+ Error_Msg_N ("\reserved for compiler use only", Actual);
+ end if;
+
+ return True;
+
+ else
+ return False;
+ end if;
end if;
Next (Actual);
@@ -2463,10 +2912,10 @@ package body Sem_Dim is
-- by the routine From_Dim_To_Str_Of_Dim_Symbols.
if Exists (Dims_Of_Actual) then
- System := System_Of (Base_Type (Etyp));
New_Str_Lit :=
Make_String_Literal (Loc,
- From_Dim_To_Str_Of_Dim_Symbols (Dims_Of_Actual, System));
+ From_Dim_To_Str_Of_Dim_Symbols
+ (Dims_Of_Actual, System_Of (Base_Type (Etyp))));
-- If dimensionless, the output is []
@@ -2481,25 +2930,23 @@ package body Sem_Dim is
-- Add the symbol as a suffix of the value if the subtype has a
-- unit symbol or if the parameter is not dimensionless.
- if Symbol_Of (Etyp) /= No_String then
+ if Exists (Symbol_Of (Etyp)) then
+ Symbols := Symbol_Of (Etyp);
+ else
+ Symbols := From_Dim_To_Str_Of_Unit_Symbols
+ (Dims_Of_Actual, System_Of (Base_Type (Etyp)));
+ end if;
+
+ -- Check Symbols exists
+
+ if Exists (Symbols) then
Start_String;
-- Put a space between the value and the dimension
Store_String_Char (' ');
- Store_String_Chars (Symbol_Of (Etyp));
+ Store_String_Chars (Symbols);
New_Str_Lit := Make_String_Literal (Loc, End_String);
-
- -- Check that the item is not dimensionless
-
- -- Create the new String_Literal with the new String_Id generated
- -- by the routine From_Dim_To_Str_Of_Unit_Symbols.
-
- elsif Exists (Dims_Of_Actual) then
- System := System_Of (Base_Type (Etyp));
- New_Str_Lit :=
- Make_String_Literal (Loc,
- From_Dim_To_Str_Of_Unit_Symbols (Dims_Of_Actual, System));
end if;
end if;
@@ -2672,13 +3119,15 @@ package body Sem_Dim is
First_Dim : Boolean := True;
begin
- -- Initialization of the new String_Id
+ -- Return No_String if dimensionless
- Start_String;
+ if not Exists (Dims) then
+ return No_String;
+ end if;
- -- Put a space between the value and the symbols
+ -- Initialization of the new String_Id
- Store_String_Char (' ');
+ Start_String;
for Position in Dimension_Type'Range loop
Dim_Power := Dims (Position);
@@ -2787,7 +3236,8 @@ package body Sem_Dim is
return
Is_RTU (E, System_Dim_Float_IO)
- or Is_RTU (E, System_Dim_Integer_IO);
+ or else
+ Is_RTU (E, System_Dim_Integer_IO);
end Is_Dim_IO_Package_Entity;
-------------------------------------
@@ -2820,15 +3270,15 @@ package body Sem_Dim is
---------------------
procedure Move_Dimensions (From, To : Node_Id) is
- Dims_Of_From : constant Dimension_Type := Dimensions_Of (From);
-
begin
+ if Ada_Version < Ada_2012 then
+ return;
+ end if;
+
-- Copy the dimension of 'From to 'To' and remove dimension of 'From'
- if Exists (Dims_Of_From) then
- Set_Dimensions (To, Dims_Of_From);
- Remove_Dimensions (From);
- end if;
+ Copy_Dimensions (From, To);
+ Remove_Dimensions (From);
end Move_Dimensions;
------------
@@ -2861,26 +3311,6 @@ package body Sem_Dim is
end if;
end Remove_Dimensions;
- ------------------------------
- -- Remove_Dimension_In_Call --
- ------------------------------
-
- procedure Remove_Dimension_In_Call (Call : Node_Id) is
- Actual : Node_Id;
-
- begin
- if Ada_Version < Ada_2012 then
- return;
- end if;
-
- Actual := First (Parameter_Associations (Call));
-
- while Present (Actual) loop
- Remove_Dimensions (Actual);
- Next (Actual);
- end loop;
- end Remove_Dimension_In_Call;
-
-----------------------------------
-- Remove_Dimension_In_Statement --
-----------------------------------
@@ -2935,13 +3365,83 @@ package body Sem_Dim is
Symbol_Table.Set (E, Val);
end Set_Symbol;
+ ---------------------------------
+ -- String_From_Numeric_Literal --
+ ---------------------------------
+
+ function String_From_Numeric_Literal (N : Node_Id) return String_Id is
+ Loc : constant Source_Ptr := Sloc (N);
+ Sbuffer : constant Source_Buffer_Ptr :=
+ Source_Text (Get_Source_File_Index (Loc));
+ Src_Ptr : Source_Ptr := Loc;
+ C : Character := Sbuffer (Src_Ptr);
+ -- Current source program character
+
+ function Belong_To_Numeric_Literal (C : Character) return Boolean;
+ -- Return True if C belongs to a numeric literal
+
+ -------------------------------
+ -- Belong_To_Numeric_Literal --
+ -------------------------------
+
+ function Belong_To_Numeric_Literal (C : Character) return Boolean is
+ begin
+ case C is
+ when '0' .. '9' |
+ '_' |
+ '.' |
+ 'e' |
+ '#' |
+ 'A' |
+ 'B' |
+ 'C' |
+ 'D' |
+ 'E' |
+ 'F' =>
+ return True;
+
+ -- Make sure '+' or '-' is part of an exponent.
+
+ when '+' | '-' =>
+ declare
+ Prev_C : constant Character := Sbuffer (Src_Ptr - 1);
+ begin
+ return Prev_C = 'e' or else Prev_C = 'E';
+ end;
+
+ -- All other character doesn't belong to a numeric literal
+
+ when others =>
+ return False;
+ end case;
+ end Belong_To_Numeric_Literal;
+
+ -- Start of processing for String_From_Numeric_Literal
+
+ begin
+ Start_String;
+ while Belong_To_Numeric_Literal (C) loop
+ Store_String_Char (C);
+ Src_Ptr := Src_Ptr + 1;
+ C := Sbuffer (Src_Ptr);
+ end loop;
+
+ return End_String;
+ end String_From_Numeric_Literal;
+
---------------
-- Symbol_Of --
---------------
function Symbol_Of (E : Entity_Id) return String_Id is
+ Subtype_Symbol : constant String_Id := Symbol_Table.Get (E);
begin
- return Symbol_Table.Get (E);
+ if Subtype_Symbol /= No_String then
+ return Subtype_Symbol;
+ else
+ return From_Dim_To_Str_Of_Unit_Symbols
+ (Dimensions_Of (E), System_Of (Base_Type (E)));
+ end if;
end Symbol_Of;
-----------------------
diff --git a/gcc/ada/sem_dim.ads b/gcc/ada/sem_dim.ads
index 3799651a0..2fdfd30ee 100644
--- a/gcc/ada/sem_dim.ads
+++ b/gcc/ada/sem_dim.ads
@@ -108,16 +108,19 @@ package Sem_Dim is
procedure Analyze_Dimension (N : Node_Id);
-- N may denote any of the following contexts:
+ -- * aggregate
-- * assignment statement
-- * attribute reference
-- * binary operator
+ -- * call
-- * compontent declaration
-- * extended return statement
- -- * function call
+ -- * expanded name
-- * identifier
-- * indexed component
-- * object declaration
-- * object renaming declaration
+ -- * procedure call statement
-- * qualified expression
-- * selected component
-- * simple return statement
@@ -129,6 +132,41 @@ package Sem_Dim is
-- Depending on the context, ensure that all expressions and entities
-- involved do not violate the rules of a system.
+ procedure Analyze_Dimension_Array_Aggregate
+ (N : Node_Id;
+ Comp_Typ : Entity_Id);
+ -- Check, for each component of the array aggregate denoted by N, the
+ -- dimensions of the component expression match the dimensions of the
+ -- component type Comp_Typ.
+
+ procedure Analyze_Dimension_Call (N : Node_Id; Nam : Entity_Id);
+ -- This routine is split in two steps. Note the second step applies only to
+ -- function calls.
+ -- Step 1. Dimension checking:
+ -- * General case: check the dimensions of each actual parameter match
+ -- the dimensions of the corresponding formal parameter.
+ -- * Elementary function case: check each actual is dimensionless except
+ -- for Sqrt call.
+ -- Step 2. Dimension propagation (only for functions):
+ -- * General case: propagate the dimensions from the returned type to the
+ -- function call.
+ -- * Sqrt case: the resulting dimensions equal to half the dimensions of
+ -- the actual
+
+ procedure Analyze_Dimension_Extension_Or_Record_Aggregate (N : Node_Id);
+ -- Check, for each component of the extension or record aggregate denoted
+ -- by N, the dimensions of the component expression match the dimensions of
+ -- the component type.
+
+ procedure Analyze_Dimension_Formals (N : Node_Id; Formals : List_Id);
+ -- For sub spec N, issue a warning for each dimensioned formal with a
+ -- literal default value in the list of formals Formals.
+
+ procedure Copy_Dimensions (From, To : Node_Id);
+ -- Copy dimension vector of node From to node To. Note that To must be a
+ -- node that is allowed to contain a dimension (see OK_For_Dimension in
+ -- body of Sem_Dim).
+
procedure Eval_Op_Expon_For_Dimensioned_Type
(N : Node_Id;
Btyp : Entity_Id);
@@ -150,9 +188,6 @@ package Sem_Dim is
-- Return True if N is a package instantiation of System.Dim.Integer_IO or
-- of System.Dim.Float_IO.
- procedure Remove_Dimension_In_Call (Call : Node_Id);
- -- Remove the dimensions from all formal parameters of Call
-
procedure Remove_Dimension_In_Statement (Stmt : Node_Id);
-- Remove the dimensions associated with Stmt
diff --git a/gcc/ada/sem_elab.adb b/gcc/ada/sem_elab.adb
index d1b5f7c6b..be3d7c5f9 100644
--- a/gcc/ada/sem_elab.adb
+++ b/gcc/ada/sem_elab.adb
@@ -153,7 +153,7 @@ package body Sem_Elab is
-- This is set True till the compilation is complete, including the
-- insertion of all instance bodies. Then when Check_Elab_Calls is called,
-- the delay table is used to make the delayed calls and this flag is reset
- -- to False, so that the calls are processed
+ -- to False, so that the calls are processed.
-----------------------
-- Local Subprograms --
@@ -1162,8 +1162,6 @@ package body Sem_Elab is
Ent : Entity_Id;
P : Node_Id;
- -- Start of processing for Check_Elab_Call
-
begin
-- If the call does not come from the main unit, there is nothing to
-- check. Elaboration call from units in the context of the main unit
@@ -1190,7 +1188,7 @@ package body Sem_Elab is
-- Nothing to do if this is a call already rewritten for elab checking
- elsif Nkind (Parent (N)) = N_Conditional_Expression then
+ elsif Nkind (Parent (N)) = N_If_Expression then
return;
-- Nothing to do if inside a generic template
@@ -1206,10 +1204,17 @@ package body Sem_Elab is
if Debug_Flag_LL then
Write_Str (" Check_Elab_Call: ");
- if No (Name (N))
- or else not Is_Entity_Name (Name (N))
- then
+ if Nkind (N) = N_Attribute_Reference then
+ if not Is_Entity_Name (Prefix (N)) then
+ Write_Str ("<<not entity name>>");
+ else
+ Write_Name (Chars (Entity (Prefix (N))));
+ end if;
+ Write_Str ("'Access");
+
+ elsif No (Name (N)) or else not Is_Entity_Name (Name (N)) then
Write_Str ("<<not entity name>> ");
+
else
Write_Name (Chars (Entity (Name (N))));
end if;
@@ -2930,7 +2935,8 @@ package body Sem_Elab is
-- the context of the call has already been analyzed, an insertion
-- will not work if it depends on subsequent expansion (e.g. a call in
-- a branch of a short-circuit). In that case we replace the call with
- -- a conditional expression, or with a Raise if it is unconditional.
+ -- an if expression, or with a Raise if it is unconditional.
+
-- Unfortunately this does not work if the call has a dynamic size,
-- because gigi regards it as a dynamic-sized temporary. If such a call
-- appears in a short-circuit expression, the elaboration check will be
@@ -2967,14 +2973,14 @@ package body Sem_Elab is
Reloc_N := Relocate_Node (N);
Save_Interps (N, Reloc_N);
Rewrite (N,
- Make_Conditional_Expression (Loc,
+ Make_If_Expression (Loc,
Expressions => New_List (C, Reloc_N, R)));
end if;
Analyze_And_Resolve (N, Typ);
-- If the original call requires a range check, so does the
- -- conditional expression.
+ -- if expression.
if Chk then
Enable_Range_Check (N);
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 8553ce628..f7e774308 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -37,6 +37,7 @@ with Namet; use Namet;
with Nmake; use Nmake;
with Nlists; use Nlists;
with Opt; use Opt;
+with Rtsfind; use Rtsfind;
with Sem; use Sem;
with Sem_Aux; use Sem_Aux;
with Sem_Cat; use Sem_Cat;
@@ -198,7 +199,7 @@ package body Sem_Eval is
-- Tests to see if expression N whose single operand is Op1 is foldable,
-- i.e. the operand value is known at compile time. If the operation is
-- foldable, then Fold is True on return, and Stat indicates whether
- -- the result is static (i.e. both operands were static). Note that it
+ -- the result is static (i.e. the operand was static). Note that it
-- is quite possible for Fold to be True, and Stat to be False, since
-- there are cases in which we know the value of an operand even though
-- it is not technically static (e.g. the static lower bound of a range
@@ -232,7 +233,7 @@ package body Sem_Eval is
Stat : out Boolean;
Fold : out Boolean);
-- Same processing, except applies to an expression N with two operands
- -- Op1 and Op2.
+ -- Op1 and Op2. The result is static only if both operands are static.
function Test_In_Range
(N : Node_Id;
@@ -240,11 +241,11 @@ package body Sem_Eval is
Assume_Valid : Boolean;
Fixed_Int : Boolean;
Int_Real : Boolean) return Range_Membership;
- -- Common processing for Is_In_Range and Is_Out_Of_Range:
- -- Returns In_Range or Out_Of_Range if it can be guaranteed at compile time
- -- that expression N is known to be in or out of range of the subtype Typ.
- -- If not compile time known, Unknown is returned.
- -- See documentation of Is_In_Range for complete description of parameters.
+ -- Common processing for Is_In_Range and Is_Out_Of_Range: Returns In_Range
+ -- or Out_Of_Range if it can be guaranteed at compile time that expression
+ -- N is known to be in or out of range of the subtype Typ. If not compile
+ -- time known, Unknown is returned. See documentation of Is_In_Range for
+ -- complete description of parameters.
procedure To_Bits (U : Uint; B : out Bits);
-- Converts a Uint value to a bit string of length B'Length
@@ -743,6 +744,16 @@ package body Sem_Eval is
begin
Diff.all := No_Uint;
+ -- In preanalysis mode, always return Unknown, it is too early to be
+ -- thinking we know the result of a comparison, save that judgment for
+ -- the full analysis. This is particularly important in the case of
+ -- pre and postconditions, which otherwise can be prematurely collapsed
+ -- into having True or False conditions when this is inappropriate.
+
+ if not Full_Analysis then
+ return Unknown;
+ end if;
+
-- If either operand could raise constraint error, then we cannot
-- know the result at compile time (since CE may be raised!)
@@ -932,28 +943,80 @@ package body Sem_Eval is
end if;
end if;
- -- Try range analysis on variables and see if ranges are disjoint
+ -- First attempt is to decompose the expressions to extract a
+ -- constant offset resulting from the use of any of the forms:
+
+ -- expr + literal
+ -- expr - literal
+ -- typ'Succ (expr)
+ -- typ'Pred (expr)
+
+ -- Then we see if the two expressions are the same value, and if so
+ -- the result is obtained by comparing the offsets.
+
+ -- Note: the reason we do this test first is that it returns only
+ -- decisive results (with diff set), where other tests, like the
+ -- range test, may not be as so decisive. Consider for example
+ -- J .. J + 1. This code can conclude LT with a difference of 1,
+ -- even if the range of J is not known.
+
+ declare
+ Lnode : Node_Id;
+ Loffs : Uint;
+ Rnode : Node_Id;
+ Roffs : Uint;
+
+ begin
+ Compare_Decompose (L, Lnode, Loffs);
+ Compare_Decompose (R, Rnode, Roffs);
+
+ if Is_Same_Value (Lnode, Rnode) then
+ if Loffs = Roffs then
+ return EQ;
+
+ elsif Loffs < Roffs then
+ Diff.all := Roffs - Loffs;
+ return LT;
+
+ else
+ Diff.all := Loffs - Roffs;
+ return GT;
+ end if;
+ end if;
+ end;
+
+ -- Next, try range analysis and see if operand ranges are disjoint
declare
LOK, ROK : Boolean;
LLo, LHi : Uint;
RLo, RHi : Uint;
+ Single : Boolean;
+ -- True if each range is a single point
+
begin
Determine_Range (L, LOK, LLo, LHi, Assume_Valid);
Determine_Range (R, ROK, RLo, RHi, Assume_Valid);
if LOK and ROK then
+ Single := (LLo = LHi) and then (RLo = RHi);
+
if LHi < RLo then
+ if Single and Assume_Valid then
+ Diff.all := RLo - LLo;
+ end if;
+
return LT;
elsif RHi < LLo then
+ if Single and Assume_Valid then
+ Diff.all := LLo - RLo;
+ end if;
+
return GT;
- elsif LLo = LHi
- and then RLo = RHi
- and then LLo = RLo
- then
+ elsif Single and then LLo = RLo then
-- If the range includes a single literal and we can assume
-- validity then the result is known even if an operand is
@@ -1054,42 +1117,6 @@ package body Sem_Eval is
end if;
end if;
- -- Next attempt is to decompose the expressions to extract
- -- a constant offset resulting from the use of any of the forms:
-
- -- expr + literal
- -- expr - literal
- -- typ'Succ (expr)
- -- typ'Pred (expr)
-
- -- Then we see if the two expressions are the same value, and if so
- -- the result is obtained by comparing the offsets.
-
- declare
- Lnode : Node_Id;
- Loffs : Uint;
- Rnode : Node_Id;
- Roffs : Uint;
-
- begin
- Compare_Decompose (L, Lnode, Loffs);
- Compare_Decompose (R, Rnode, Roffs);
-
- if Is_Same_Value (Lnode, Rnode) then
- if Loffs = Roffs then
- return EQ;
-
- elsif Loffs < Roffs then
- Diff.all := Roffs - Loffs;
- return LT;
-
- else
- Diff.all := Loffs - Roffs;
- return GT;
- end if;
- end if;
- end;
-
-- Next attempt is to see if we have an entity compared with a
-- compile time known value, where there is a current value
-- conditional for the entity which can tell us the result.
@@ -1862,15 +1889,74 @@ package body Sem_Eval is
end;
end Eval_Concatenation;
- ---------------------------------
- -- Eval_Conditional_Expression --
- ---------------------------------
+ ----------------------
+ -- Eval_Entity_Name --
+ ----------------------
- -- We can fold to a static expression if the condition and both constituent
+ -- This procedure is used for identifiers and expanded names other than
+ -- named numbers (see Eval_Named_Integer, Eval_Named_Real. These are
+ -- static if they denote a static constant (RM 4.9(6)) or if the name
+ -- denotes an enumeration literal (RM 4.9(22)).
+
+ procedure Eval_Entity_Name (N : Node_Id) is
+ Def_Id : constant Entity_Id := Entity (N);
+ Val : Node_Id;
+
+ begin
+ -- Enumeration literals are always considered to be constants
+ -- and cannot raise constraint error (RM 4.9(22)).
+
+ if Ekind (Def_Id) = E_Enumeration_Literal then
+ Set_Is_Static_Expression (N);
+ return;
+
+ -- A name is static if it denotes a static constant (RM 4.9(5)), and
+ -- we also copy Raise_Constraint_Error. Notice that even if non-static,
+ -- it does not violate 10.2.1(8) here, since this is not a variable.
+
+ elsif Ekind (Def_Id) = E_Constant then
+
+ -- Deferred constants must always be treated as nonstatic
+ -- outside the scope of their full view.
+
+ if Present (Full_View (Def_Id))
+ and then not In_Open_Scopes (Scope (Def_Id))
+ then
+ Val := Empty;
+ else
+ Val := Constant_Value (Def_Id);
+ end if;
+
+ if Present (Val) then
+ Set_Is_Static_Expression
+ (N, Is_Static_Expression (Val)
+ and then Is_Static_Subtype (Etype (Def_Id)));
+ Set_Raises_Constraint_Error (N, Raises_Constraint_Error (Val));
+
+ if not Is_Static_Expression (N)
+ and then not Is_Generic_Type (Etype (N))
+ then
+ Validate_Static_Object_Name (N);
+ end if;
+
+ return;
+ end if;
+ end if;
+
+ -- Fall through if the name is not static
+
+ Validate_Static_Object_Name (N);
+ end Eval_Entity_Name;
+
+ ------------------------
+ -- Eval_If_Expression --
+ ------------------------
+
+ -- We can fold to a static expression if the condition and both dependent
-- expressions are static. Otherwise, the only required processing is to do
-- the check for non-static context for the then and else expressions.
- procedure Eval_Conditional_Expression (N : Node_Id) is
+ procedure Eval_If_Expression (N : Node_Id) is
Condition : constant Node_Id := First (Expressions (N));
Then_Expr : constant Node_Id := Next (Condition);
Else_Expr : constant Node_Id := Next (Then_Expr);
@@ -1939,66 +2025,7 @@ package body Sem_Eval is
end if;
Set_Is_Static_Expression (N, Rstat);
- end Eval_Conditional_Expression;
-
- ----------------------
- -- Eval_Entity_Name --
- ----------------------
-
- -- This procedure is used for identifiers and expanded names other than
- -- named numbers (see Eval_Named_Integer, Eval_Named_Real. These are
- -- static if they denote a static constant (RM 4.9(6)) or if the name
- -- denotes an enumeration literal (RM 4.9(22)).
-
- procedure Eval_Entity_Name (N : Node_Id) is
- Def_Id : constant Entity_Id := Entity (N);
- Val : Node_Id;
-
- begin
- -- Enumeration literals are always considered to be constants
- -- and cannot raise constraint error (RM 4.9(22)).
-
- if Ekind (Def_Id) = E_Enumeration_Literal then
- Set_Is_Static_Expression (N);
- return;
-
- -- A name is static if it denotes a static constant (RM 4.9(5)), and
- -- we also copy Raise_Constraint_Error. Notice that even if non-static,
- -- it does not violate 10.2.1(8) here, since this is not a variable.
-
- elsif Ekind (Def_Id) = E_Constant then
-
- -- Deferred constants must always be treated as nonstatic
- -- outside the scope of their full view.
-
- if Present (Full_View (Def_Id))
- and then not In_Open_Scopes (Scope (Def_Id))
- then
- Val := Empty;
- else
- Val := Constant_Value (Def_Id);
- end if;
-
- if Present (Val) then
- Set_Is_Static_Expression
- (N, Is_Static_Expression (Val)
- and then Is_Static_Subtype (Etype (Def_Id)));
- Set_Raises_Constraint_Error (N, Raises_Constraint_Error (Val));
-
- if not Is_Static_Expression (N)
- and then not Is_Generic_Type (Etype (N))
- then
- Validate_Static_Object_Name (N);
- end if;
-
- return;
- end if;
- end if;
-
- -- Fall through if the name is not static
-
- Validate_Static_Object_Name (N);
- end Eval_Entity_Name;
+ end Eval_If_Expression;
----------------------------
-- Eval_Indexed_Component --
@@ -3239,6 +3266,38 @@ package body Sem_Eval is
end if;
end Eval_Slice;
+ ---------------------------------
+ -- Eval_Static_Predicate_Check --
+ ---------------------------------
+
+ function Eval_Static_Predicate_Check
+ (N : Node_Id;
+ Typ : Entity_Id) return Boolean
+ is
+ Loc : constant Source_Ptr := Sloc (N);
+ Pred : constant List_Id := Static_Predicate (Typ);
+ Test : Node_Id;
+
+ begin
+ if No (Pred) then
+ return True;
+ end if;
+
+ -- The static predicate is a list of alternatives in the proper format
+ -- for an Ada 2012 membership test. If the argument is a literal, the
+ -- membership test can be evaluated statically. The caller transforms
+ -- a result of False into a static contraint error.
+
+ Test := Make_In (Loc,
+ Left_Opnd => New_Copy_Tree (N),
+ Right_Opnd => Empty,
+ Alternatives => Pred);
+ Analyze_And_Resolve (Test, Standard_Boolean);
+
+ return Nkind (Test) = N_Identifier
+ and then Entity (Test) = Standard_True;
+ end Eval_Static_Predicate_Check;
+
-------------------------
-- Eval_String_Literal --
-------------------------
@@ -3987,12 +4046,18 @@ package body Sem_Eval is
-- We now have the literal with the right value, both the actual type
-- and the expected type of this literal are taken from the expression
- -- that was evaluated.
+ -- that was evaluated. So now we do the Analyze and Resolve.
+
+ -- Note that we have to reset Is_Static_Expression both after the
+ -- analyze step (because Resolve will evaluate the literal, which
+ -- will cause semantic errors if it is marked as static), and after
+ -- the Resolve step (since Resolve in some cases sets this flag).
Analyze (N);
Set_Is_Static_Expression (N, Static);
Set_Etype (N, Typ);
Resolve (N);
+ Set_Is_Static_Expression (N, Static);
end Fold_Str;
---------------
@@ -4041,12 +4106,18 @@ package body Sem_Eval is
-- We now have the literal with the right value, both the actual type
-- and the expected type of this literal are taken from the expression
- -- that was evaluated.
+ -- that was evaluated. So now we do the Analyze and Resolve.
+
+ -- Note that we have to reset Is_Static_Expression both after the
+ -- analyze step (because Resolve will evaluate the literal, which
+ -- will cause semantic errors if it is marked as static), and after
+ -- the Resolve step (since Resolve in some cases sets this flag).
Analyze (N);
Set_Is_Static_Expression (N, Static);
Set_Etype (N, Typ);
Resolve (N);
+ Set_Is_Static_Expression (N, Static);
end Fold_Uint;
----------------
@@ -4076,12 +4147,20 @@ package body Sem_Eval is
Set_Original_Entity (N, Ent);
- -- Both the actual and expected type comes from the original expression
+ -- We now have the literal with the right value, both the actual type
+ -- and the expected type of this literal are taken from the expression
+ -- that was evaluated. So now we do the Analyze and Resolve.
+
+ -- Note that we have to reset Is_Static_Expression both after the
+ -- analyze step (because Resolve will evaluate the literal, which
+ -- will cause semantic errors if it is marked as static), and after
+ -- the Resolve step (since Resolve in some cases sets this flag).
Analyze (N);
Set_Is_Static_Expression (N, Static);
Set_Etype (N, Typ);
Resolve (N);
+ Set_Is_Static_Expression (N, Static);
end Fold_Ureal;
---------------
@@ -5361,10 +5440,12 @@ package body Sem_Eval is
return;
end if;
- -- Type must be scalar or string type
+ -- Type must be scalar or string type (but allow Bignum, since this
+ -- is really a scalar type from our point of view in this diagnosis).
if not Is_Scalar_Type (Typ)
and then not Is_String_Type (Typ)
+ and then not Is_RTE (Typ, RE_Bignum)
then
Error_Msg_N
("static expression must have scalar or string type " &
@@ -5481,7 +5562,14 @@ package body Sem_Eval is
when N_Function_Call =>
Why_Not_Static_List (Parameter_Associations (N));
- Error_Msg_N ("non-static function call (RM 4.9(6,18))!", N);
+
+ -- Complain about non-static function call unless we have Bignum
+ -- which means that the underlying expression is really some
+ -- scalar arithmetic operation.
+
+ if not Is_RTE (Typ, RE_Bignum) then
+ Error_Msg_N ("non-static function call (RM 4.9(6,18))!", N);
+ end if;
when N_Parameter_Association =>
Why_Not_Static (Explicit_Actual_Parameter (N));
diff --git a/gcc/ada/sem_eval.ads b/gcc/ada/sem_eval.ads
index a2f69feac..06607d778 100644
--- a/gcc/ada/sem_eval.ads
+++ b/gcc/ada/sem_eval.ads
@@ -296,8 +296,8 @@ package Sem_Eval is
procedure Eval_Case_Expression (N : Node_Id);
procedure Eval_Character_Literal (N : Node_Id);
procedure Eval_Concatenation (N : Node_Id);
- procedure Eval_Conditional_Expression (N : Node_Id);
procedure Eval_Entity_Name (N : Node_Id);
+ procedure Eval_If_Expression (N : Node_Id);
procedure Eval_Indexed_Component (N : Node_Id);
procedure Eval_Integer_Literal (N : Node_Id);
procedure Eval_Logical_Op (N : Node_Id);
@@ -317,6 +317,11 @@ package Sem_Eval is
procedure Eval_Unary_Op (N : Node_Id);
procedure Eval_Unchecked_Conversion (N : Node_Id);
+ function Eval_Static_Predicate_Check
+ (N : Node_Id;
+ Typ : Entity_Id) return Boolean;
+ -- Evaluate a static predicate check applied to a scalar literal
+
procedure Fold_Str (N : Node_Id; Val : String_Id; Static : Boolean);
-- Rewrite N with a new N_String_Literal node as the result of the compile
-- time evaluation of the node N. Val is the resulting string value from
@@ -434,7 +439,7 @@ private
pragma Inline (Eval_Actual);
pragma Inline (Eval_Allocator);
pragma Inline (Eval_Character_Literal);
- pragma Inline (Eval_Conditional_Expression);
+ pragma Inline (Eval_If_Expression);
pragma Inline (Eval_Indexed_Component);
pragma Inline (Eval_Named_Integer);
pragma Inline (Eval_Named_Real);
diff --git a/gcc/ada/sem_prag.adb b/gcc/ada/sem_prag.adb
index 4d377585e..2c9d518f6 100644
--- a/gcc/ada/sem_prag.adb
+++ b/gcc/ada/sem_prag.adb
@@ -286,7 +286,7 @@ package body Sem_Prag is
-- Preanalyze the boolean expression, we treat this as a spec expression
-- (i.e. similar to a default expression).
- Preanalyze_Spec_Expression (Get_Pragma_Arg (Arg1), Standard_Boolean);
+ Preanalyze_Assert_Expression (Get_Pragma_Arg (Arg1), Standard_Boolean);
-- In ASIS mode, for a pragma generated from a source aspect, also
-- analyze the original aspect expression.
@@ -294,7 +294,7 @@ package body Sem_Prag is
if ASIS_Mode
and then Present (Corresponding_Aspect (N))
then
- Preanalyze_Spec_Expression
+ Preanalyze_Assert_Expression
(Expression (Corresponding_Aspect (N)), Standard_Boolean);
end if;
@@ -2057,6 +2057,10 @@ package body Sem_Prag is
S := Defining_Entity (PO);
else
S := Defining_Unit_Name (Specification (PO));
+
+ if Nkind (S) = N_Defining_Program_Unit_Name then
+ S := Defining_Identifier (S);
+ end if;
end if;
-- Note: we do not analyze the pragma at this point. Instead we
@@ -2172,7 +2176,7 @@ package body Sem_Prag is
then
-- Analyze pragma expression for correctness and for ASIS use
- Preanalyze_Spec_Expression
+ Preanalyze_Assert_Expression
(Get_Pragma_Arg (Arg1), Standard_Boolean);
-- In ASIS mode, for a pragma generated from a source aspect,
@@ -2181,7 +2185,7 @@ package body Sem_Prag is
if ASIS_Mode
and then Present (Corresponding_Aspect (N))
then
- Preanalyze_Spec_Expression
+ Preanalyze_Assert_Expression
(Expression (Corresponding_Aspect (N)), Standard_Boolean);
end if;
end if;
@@ -3625,9 +3629,18 @@ package body Sem_Prag is
Generate_Reference (E, Id, 'i');
end if;
- -- Loop through the homonyms of the pragma argument's entity
+ -- If the pragma comes from from an aspect, it only applies
+ -- to the given entity, not its homonyms.
+
+ if From_Aspect_Specification (N) then
+ return;
+ end if;
+
+ -- Otherwise Loop through the homonyms of the pragma argument's
+ -- entity, an apply convention to those in the current scope.
E1 := Ent;
+
loop
E1 := Homonym (E1);
exit when No (E1) or else Scope (E1) /= Current_Scope;
@@ -3655,10 +3668,6 @@ package body Sem_Prag is
Generate_Reference (E1, Id, 'b');
end if;
end if;
-
- -- For aspect case, do NOT apply to homonyms
-
- exit when From_Aspect_Specification (N);
end loop;
end if;
end Process_Convention;
@@ -4524,10 +4533,12 @@ package body Sem_Prag is
or else Is_Generic_Subprogram (Def_Id)
then
-- If the name is overloaded, pragma applies to all of the denoted
- -- entities in the same declarative part.
+ -- entities in the same declarative part, unless the pragma comes
+ -- from an aspect specification.
Hom_Id := Def_Id;
while Present (Hom_Id) loop
+
Def_Id := Get_Base_Subprogram (Hom_Id);
-- Ignore inherited subprograms because the pragma will apply
@@ -4638,6 +4649,9 @@ package body Sem_Prag is
exit;
+ elsif From_Aspect_Specification (N) then
+ exit;
+
else
Hom_Id := Homonym (Hom_Id);
end if;
@@ -5668,12 +5682,11 @@ package body Sem_Prag is
if C = All_Checks or else C = Overflow_Check then
if Suppress_Case then
- Scope_Suppress.Overflow_Checks_General := Suppress;
- Scope_Suppress.Overflow_Checks_Assertions := Suppress;
+ Scope_Suppress.Overflow_Checks_General := Suppressed;
+ Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
else
- Scope_Suppress.Overflow_Checks_General := Check_All;
- Scope_Suppress.Overflow_Checks_Assertions := Check_All;
- Opt.Overflow_Checks_Unsuppressed := True;
+ Scope_Suppress.Overflow_Checks_General := Checked;
+ Scope_Suppress.Overflow_Checks_Assertions := Checked;
end if;
end if;
@@ -6768,7 +6781,8 @@ package body Sem_Prag is
-- pragma Check (Assertion, condition [, msg]);
- -- So rewrite pragma in this manner, and analyze the result
+ -- So rewrite pragma in this manner, transfer the message
+ -- argument if present, and analyze the result
Expr := Get_Pragma_Arg (Arg1);
Newa := New_List (
@@ -6780,8 +6794,7 @@ package body Sem_Prag is
if Arg_Count > 1 then
Check_Optional_Identifier (Arg2, Name_Message);
- Analyze_And_Resolve (Get_Pragma_Arg (Arg2), Standard_String);
- Append_To (Newa, Relocate_Node (Arg2));
+ Append_To (Newa, New_Copy_Tree (Arg2));
end if;
Rewrite (N,
@@ -6795,7 +6808,7 @@ package body Sem_Prag is
-- Assertion_Policy --
----------------------
- -- pragma Assertion_Policy (Check | Disable |Ignore)
+ -- pragma Assertion_Policy (Check | Disable | Ignore)
when Pragma_Assertion_Policy => Assertion_Policy : declare
Policy : Node_Id;
@@ -7285,7 +7298,9 @@ package body Sem_Prag is
-- Check is active
else
+ In_Assertion_Expr := In_Assertion_Expr + 1;
Analyze_And_Resolve (Expr, Any_Boolean);
+ In_Assertion_Expr := In_Assertion_Expr - 1;
end if;
end Check;
@@ -10314,6 +10329,7 @@ package body Sem_Prag is
when Pragma_Invariant => Invariant : declare
Type_Id : Node_Id;
Typ : Entity_Id;
+ PDecl : Node_Id;
Discard : Boolean;
pragma Unreferenced (Discard);
@@ -10365,8 +10381,13 @@ package body Sem_Prag is
-- Note that the type has at least one invariant, and also that
-- it has inheritable invariants if we have Invariant'Class.
+ -- Build the corresponding invariant procedure declaration, so
+ -- that calls to it can be generated before the body is built
+ -- (for example wihin an expression function).
- Set_Has_Invariants (Typ);
+ PDecl := Build_Invariant_Procedure_Declaration (Typ);
+ Insert_After (N, PDecl);
+ Analyze (PDecl);
if Class_Present (N) then
Set_Has_Inheritable_Invariants (Typ);
@@ -11749,6 +11770,96 @@ package body Sem_Prag is
Optimize_Alignment_Local := True;
end Optimize_Alignment;
+ ---------------------
+ -- Overflow_Checks --
+ ---------------------
+
+ -- pragma Overflow_Checks
+ -- ([General => ] MODE [, [Assertions => ] MODE]);
+
+ -- MODE := SUPPRESSED | CHECKED | MINIMIZED | ELIMINATED
+
+ -- Note: ELIMINATED is allowed only if Long_Long_Integer'Size is 64
+ -- since System.Bignums makes this assumption.
+
+ when Pragma_Overflow_Checks => Overflow_Checks : declare
+ function Get_Check_Mode
+ (Name : Name_Id;
+ Arg : Node_Id) return Overflow_Check_Type;
+ -- Function to process one pragma argument, Arg. If an identifier
+ -- is present, it must be Name. Check type is returned if a valid
+ -- argument exists, otherwise an error is signalled.
+
+ --------------------
+ -- Get_Check_Mode --
+ --------------------
+
+ function Get_Check_Mode
+ (Name : Name_Id;
+ Arg : Node_Id) return Overflow_Check_Type
+ is
+ Argx : constant Node_Id := Get_Pragma_Arg (Arg);
+
+ begin
+ Check_Optional_Identifier (Arg, Name);
+ Check_Arg_Is_Identifier (Argx);
+
+ -- Do not suppress overflow checks for formal verification.
+ -- Instead, require that a check is inserted so that formal
+ -- verification can detect wraparound errors.
+
+ if Chars (Argx) = Name_Suppressed then
+ if Alfa_Mode then
+ return Checked;
+ else
+ return Suppressed;
+ end if;
+
+ elsif Chars (Argx) = Name_Checked then
+ return Checked;
+
+ elsif Chars (Argx) = Name_Minimized then
+ return Minimized;
+
+ elsif Chars (Argx) = Name_Eliminated then
+ if Ttypes.Standard_Long_Long_Integer_Size /= 64 then
+ Error_Pragma_Arg
+ ("Eliminated not implemented on this target", Argx);
+ else
+ return Eliminated;
+ end if;
+
+ else
+ Error_Pragma_Arg ("invalid argument for pragma%", Argx);
+ end if;
+ end Get_Check_Mode;
+
+ -- Start of processing for Overflow_Checks
+
+ begin
+ GNAT_Pragma;
+ Check_At_Least_N_Arguments (1);
+ Check_At_Most_N_Arguments (2);
+
+ -- Process first argument
+
+ Scope_Suppress.Overflow_Checks_General :=
+ Get_Check_Mode (Name_General, Arg1);
+
+ -- Case of only one argument
+
+ if Arg_Count = 1 then
+ Scope_Suppress.Overflow_Checks_Assertions :=
+ Scope_Suppress.Overflow_Checks_General;
+
+ -- Case of two arguments present
+
+ else
+ Scope_Suppress.Overflow_Checks_Assertions :=
+ Get_Check_Mode (Name_Assertions, Arg2);
+ end if;
+ end Overflow_Checks;
+
-------------
-- Ordered --
-------------
@@ -12019,6 +12130,11 @@ package body Sem_Prag is
Ent := Entity (Get_Pragma_Arg (Arg1));
Decl := Parent (Ent);
+ -- Check for duplication before inserting in list of
+ -- representation items.
+
+ Check_Duplicate_Pragma (Ent);
+
if Rep_Item_Too_Late (Ent, N) then
return;
end if;
@@ -12034,8 +12150,6 @@ package body Sem_Prag is
Arg1);
end if;
- Check_Duplicate_Pragma (Ent);
-
Prag :=
Make_Linker_Section_Pragma
(Ent, Sloc (N), ".persistent.bss");
@@ -14705,10 +14819,17 @@ package body Sem_Prag is
loop
Set_Warnings_Off
(E, (Chars (Get_Pragma_Arg (Arg1)) =
- Name_Off));
+ Name_Off));
+
+ -- For OFF case, make entry in warnings off
+ -- pragma table for later processing. But we do
+ -- not do that within an instance, since these
+ -- warnings are about what is needed in the
+ -- template, not an instance of it.
if Chars (Get_Pragma_Arg (Arg1)) = Name_Off
and then Warn_On_Warnings_Off
+ and then not In_Instance
then
Warnings_Off_Pragmas.Append ((N, E));
end if;
@@ -15169,6 +15290,7 @@ package body Sem_Prag is
Pragma_Obsolescent => 0,
Pragma_Optimize => -1,
Pragma_Optimize_Alignment => -1,
+ Pragma_Overflow_Checks => 0,
Pragma_Ordered => 0,
Pragma_Pack => 0,
Pragma_Page => -1,
@@ -15454,27 +15576,27 @@ package body Sem_Prag is
-- expressions (i.e. similar to a default expression).
if Present (Arg_Req) then
- Preanalyze_Spec_Expression
+ Preanalyze_Assert_Expression
(Get_Pragma_Arg (Arg_Req), Standard_Boolean);
-- In ASIS mode, for a pragma generated from a source aspect, also
-- analyze the original aspect expression.
if ASIS_Mode and then Present (Corresponding_Aspect (N)) then
- Preanalyze_Spec_Expression
+ Preanalyze_Assert_Expression
(Original_Node (Get_Pragma_Arg (Arg_Req)), Standard_Boolean);
end if;
end if;
if Present (Arg_Ens) then
- Preanalyze_Spec_Expression
+ Preanalyze_Assert_Expression
(Get_Pragma_Arg (Arg_Ens), Standard_Boolean);
-- In ASIS mode, for a pragma generated from a source aspect, also
-- analyze the original aspect expression.
if ASIS_Mode and then Present (Corresponding_Aspect (N)) then
- Preanalyze_Spec_Expression
+ Preanalyze_Assert_Expression
(Original_Node (Get_Pragma_Arg (Arg_Ens)), Standard_Boolean);
end if;
end if;
diff --git a/gcc/ada/sem_res.adb b/gcc/ada/sem_res.adb
index 21d3e145d..4383754fa 100644
--- a/gcc/ada/sem_res.adb
+++ b/gcc/ada/sem_res.adb
@@ -178,11 +178,11 @@ package body Sem_Res is
procedure Resolve_Case_Expression (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Character_Literal (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Comparison_Op (N : Node_Id; Typ : Entity_Id);
- procedure Resolve_Conditional_Expression (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Entity_Name (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Equality_Op (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Explicit_Dereference (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Expression_With_Actions (N : Node_Id; Typ : Entity_Id);
+ procedure Resolve_If_Expression (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Indexed_Component (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Integer_Literal (N : Node_Id; Typ : Entity_Id);
procedure Resolve_Logical_Op (N : Node_Id; Typ : Entity_Id);
@@ -322,7 +322,7 @@ package body Sem_Res is
Resolve (N, Typ);
end Analyze_And_Resolve;
- -- Version withs check(s) suppressed
+ -- Versions with check(s) suppressed
procedure Analyze_And_Resolve
(N : Node_Id;
@@ -341,6 +341,20 @@ package body Sem_Res is
Scope_Suppress := Svg;
end;
+ elsif Suppress = Overflow_Check then
+ declare
+ Svg : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ Sva : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
+ begin
+ Scope_Suppress.Overflow_Checks_General := Suppressed;
+ Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
+ Analyze_And_Resolve (N, Typ);
+ Scope_Suppress.Overflow_Checks_General := Svg;
+ Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ end;
+
else
declare
Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
@@ -381,6 +395,20 @@ package body Sem_Res is
Scope_Suppress := Svg;
end;
+ elsif Suppress = Overflow_Check then
+ declare
+ Svg : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_General;
+ Sva : constant Overflow_Check_Type :=
+ Scope_Suppress.Overflow_Checks_Assertions;
+ begin
+ Scope_Suppress.Overflow_Checks_General := Suppressed;
+ Scope_Suppress.Overflow_Checks_Assertions := Suppressed;
+ Analyze_And_Resolve (N);
+ Scope_Suppress.Overflow_Checks_General := Svg;
+ Scope_Suppress.Overflow_Checks_Assertions := Sva;
+ end;
+
else
declare
Svg : constant Boolean := Scope_Suppress.Suppress (Suppress);
@@ -806,7 +834,7 @@ package body Sem_Res is
N_And_Then,
N_Case_Expression,
N_Case_Statement,
- N_Conditional_Expression,
+ N_If_Expression,
N_If_Statement)
then
return False;
@@ -2314,7 +2342,7 @@ package body Sem_Res is
elsif Nkind (N) = N_Character_Literal then
Set_Etype (N, Expr_Type);
- elsif Nkind (N) = N_Conditional_Expression then
+ elsif Nkind (N) = N_If_Expression then
Set_Etype (N, Expr_Type);
-- AI05-0139-2: Expression is overloaded because type has
@@ -2716,9 +2744,6 @@ package body Sem_Res is
when N_Character_Literal
=> Resolve_Character_Literal (N, Ctx_Type);
- when N_Conditional_Expression
- => Resolve_Conditional_Expression (N, Ctx_Type);
-
when N_Expanded_Name
=> Resolve_Entity_Name (N, Ctx_Type);
@@ -2737,6 +2762,9 @@ package body Sem_Res is
when N_Identifier
=> Resolve_Entity_Name (N, Ctx_Type);
+ when N_If_Expression
+ => Resolve_If_Expression (N, Ctx_Type);
+
when N_Indexed_Component
=> Resolve_Indexed_Component (N, Ctx_Type);
@@ -4965,10 +4993,7 @@ package body Sem_Res is
("operation should be qualified or explicitly converted", N);
end if;
- -- Set overflow and division checking bit. Much cleverer code needed
- -- here eventually and perhaps the Resolve routines should be separated
- -- for the various arithmetic operations, since they will need
- -- different processing. ???
+ -- Set overflow and division checking bit
if Nkind (N) in N_Op then
if not Overflow_Checks_Suppressed (Etype (N)) then
@@ -5314,15 +5339,7 @@ package body Sem_Res is
-- Check that this is not a call to a protected procedure or entry from
-- within a protected function.
- if Ekind (Current_Scope) = E_Function
- and then Ekind (Scope (Current_Scope)) = E_Protected_Type
- and then Ekind (Nam) /= E_Function
- and then Scope (Nam) = Scope (Current_Scope)
- then
- Error_Msg_N ("within protected function, protected " &
- "object is constant", N);
- Error_Msg_N ("\cannot call operation that may modify it", N);
- end if;
+ Check_Internal_Protected_Use (N, Nam);
-- Freeze the subprogram name if not in a spec-expression. Note that we
-- freeze procedure calls as well as function calls. Procedure calls are
@@ -5896,7 +5913,10 @@ package body Sem_Res is
end;
end if;
- Analyze_Dimension (N);
+ -- Check the dimensions of the actuals in the call. For function calls,
+ -- propagate the dimensions from the returned type to N.
+
+ Analyze_Dimension_Call (N, Nam);
-- All done, evaluate call and deal with elaboration issues
@@ -5921,6 +5941,16 @@ package body Sem_Res is
Set_Etype (N, Typ);
Eval_Case_Expression (N);
+
+ -- If we still have a case expression, and overflow checks are enabled
+ -- in MINIMIZED or ELIMINATED modes, then set Do_Overflow_Check to
+ -- ensure that we handle overflow for dependent expressions.
+
+ if Nkind (N) = N_Case_Expression
+ and then Overflow_Check_Mode (Typ) in Minimized_Or_Eliminated
+ then
+ Set_Do_Overflow_Check (N);
+ end if;
end Resolve_Case_Expression;
-------------------------------
@@ -6098,64 +6128,6 @@ package body Sem_Res is
Eval_Relational_Op (N);
end Resolve_Comparison_Op;
- ------------------------------------
- -- Resolve_Conditional_Expression --
- ------------------------------------
-
- procedure Resolve_Conditional_Expression (N : Node_Id; Typ : Entity_Id) is
- Condition : constant Node_Id := First (Expressions (N));
- Then_Expr : constant Node_Id := Next (Condition);
- Else_Expr : Node_Id := Next (Then_Expr);
- Else_Typ : Entity_Id;
- Then_Typ : Entity_Id;
-
- begin
- Resolve (Condition, Any_Boolean);
- Resolve (Then_Expr, Typ);
- Then_Typ := Etype (Then_Expr);
-
- -- When the "then" and "else" expressions are of a scalar type, insert
- -- a conversion to ensure the generation of a constraint check.
-
- if Is_Scalar_Type (Then_Typ)
- and then Then_Typ /= Typ
- then
- Rewrite (Then_Expr, Convert_To (Typ, Then_Expr));
- Analyze_And_Resolve (Then_Expr, Typ);
- end if;
-
- -- If ELSE expression present, just resolve using the determined type
-
- if Present (Else_Expr) then
- Resolve (Else_Expr, Typ);
- Else_Typ := Etype (Else_Expr);
-
- if Is_Scalar_Type (Else_Typ)
- and then Else_Typ /= Typ
- then
- Rewrite (Else_Expr, Convert_To (Typ, Else_Expr));
- Analyze_And_Resolve (Else_Expr, Typ);
- end if;
-
- -- If no ELSE expression is present, root type must be Standard.Boolean
- -- and we provide a Standard.True result converted to the appropriate
- -- Boolean type (in case it is a derived boolean type).
-
- elsif Root_Type (Typ) = Standard_Boolean then
- Else_Expr :=
- Convert_To (Typ, New_Occurrence_Of (Standard_True, Sloc (N)));
- Analyze_And_Resolve (Else_Expr, Typ);
- Append_To (Expressions (N), Else_Expr);
-
- else
- Error_Msg_N ("can only omit ELSE expression in Boolean case", N);
- Append_To (Expressions (N), Error);
- end if;
-
- Set_Etype (N, Typ);
- Eval_Conditional_Expression (N);
- end Resolve_Conditional_Expression;
-
-----------------------------------------
-- Resolve_Discrete_Subtype_Indication --
-----------------------------------------
@@ -6732,6 +6704,7 @@ package body Sem_Res is
end if;
Resolve_Actuals (N, Nam);
+ Check_Internal_Protected_Use (N, Nam);
-- Create a call reference to the entry
@@ -6821,12 +6794,12 @@ package body Sem_Res is
R : constant Node_Id := Right_Opnd (N);
T : Entity_Id := Find_Unique_Type (L, R);
- procedure Check_Conditional_Expression (Cond : Node_Id);
- -- The resolution rule for conditional expressions requires that each
- -- such must have a unique type. This means that if several dependent
- -- expressions are of a non-null anonymous access type, and the context
- -- does not impose an expected type (as can be the case in an equality
- -- operation) the expression must be rejected.
+ procedure Check_If_Expression (Cond : Node_Id);
+ -- The resolution rule for if expressions requires that each such must
+ -- have a unique type. This means that if several dependent expressions
+ -- are of a non-null anonymous access type, and the context does not
+ -- impose an expected type (as can be the case in an equality operation)
+ -- the expression must be rejected.
function Find_Unique_Access_Type return Entity_Id;
-- In the case of allocators, make a last-ditch attempt to find a single
@@ -6834,27 +6807,26 @@ package body Sem_Res is
-- dubious, and of no interest to any real code, but c48008a makes it
-- all worthwhile.
- ----------------------------------
- -- Check_Conditional_Expression --
- ----------------------------------
+ -------------------------
+ -- Check_If_Expression --
+ -------------------------
- procedure Check_Conditional_Expression (Cond : Node_Id) is
+ procedure Check_If_Expression (Cond : Node_Id) is
Then_Expr : Node_Id;
Else_Expr : Node_Id;
begin
- if Nkind (Cond) = N_Conditional_Expression then
+ if Nkind (Cond) = N_If_Expression then
Then_Expr := Next (First (Expressions (Cond)));
Else_Expr := Next (Then_Expr);
if Nkind (Then_Expr) /= N_Null
and then Nkind (Else_Expr) /= N_Null
then
- Error_Msg_N
- ("cannot determine type of conditional expression", Cond);
+ Error_Msg_N ("cannot determine type of if expression", Cond);
end if;
end if;
- end Check_Conditional_Expression;
+ end Check_If_Expression;
-----------------------------
-- Find_Unique_Access_Type --
@@ -6930,9 +6902,11 @@ package body Sem_Res is
return;
end if;
- -- Conditional expressions must have a single type, and if the
- -- context does not impose one the dependent expressions cannot
- -- be anonymous access types.
+ -- If expressions must have a single type, and if the context does
+ -- not impose one the dependent expressions cannot be anonymous
+ -- access types.
+
+ -- Why no similar processing for case expressions???
elsif Ada_Version >= Ada_2012
and then Ekind_In (Etype (L), E_Anonymous_Access_Type,
@@ -6940,8 +6914,8 @@ package body Sem_Res is
and then Ekind_In (Etype (R), E_Anonymous_Access_Type,
E_Anonymous_Access_Subprogram_Type)
then
- Check_Conditional_Expression (L);
- Check_Conditional_Expression (R);
+ Check_If_Expression (L);
+ Check_If_Expression (R);
end if;
Resolve (L, T);
@@ -6952,6 +6926,7 @@ package body Sem_Res is
-- operands have equal static bounds.
if Is_Array_Type (T) then
+
-- Protect call to Matching_Static_Array_Bounds to avoid costly
-- operation if not needed.
@@ -7166,6 +7141,75 @@ package body Sem_Res is
Set_Etype (N, Typ);
end Resolve_Expression_With_Actions;
+ ---------------------------
+ -- Resolve_If_Expression --
+ ---------------------------
+
+ procedure Resolve_If_Expression (N : Node_Id; Typ : Entity_Id) is
+ Condition : constant Node_Id := First (Expressions (N));
+ Then_Expr : constant Node_Id := Next (Condition);
+ Else_Expr : Node_Id := Next (Then_Expr);
+ Else_Typ : Entity_Id;
+ Then_Typ : Entity_Id;
+
+ begin
+ Resolve (Condition, Any_Boolean);
+ Resolve (Then_Expr, Typ);
+ Then_Typ := Etype (Then_Expr);
+
+ -- When the "then" expression is of a scalar type different from the
+ -- result type, then insert a conversion to ensure the generation of
+ -- a constraint check.
+
+ if Is_Scalar_Type (Then_Typ)
+ and then Base_Type (Then_Typ) /= Base_Type (Typ)
+ then
+ Rewrite (Then_Expr, Convert_To (Typ, Then_Expr));
+ Analyze_And_Resolve (Then_Expr, Typ);
+ end if;
+
+ -- If ELSE expression present, just resolve using the determined type
+
+ if Present (Else_Expr) then
+ Resolve (Else_Expr, Typ);
+ Else_Typ := Etype (Else_Expr);
+
+ if Is_Scalar_Type (Else_Typ)
+ and then Else_Typ /= Typ
+ then
+ Rewrite (Else_Expr, Convert_To (Typ, Else_Expr));
+ Analyze_And_Resolve (Else_Expr, Typ);
+ end if;
+
+ -- If no ELSE expression is present, root type must be Standard.Boolean
+ -- and we provide a Standard.True result converted to the appropriate
+ -- Boolean type (in case it is a derived boolean type).
+
+ elsif Root_Type (Typ) = Standard_Boolean then
+ Else_Expr :=
+ Convert_To (Typ, New_Occurrence_Of (Standard_True, Sloc (N)));
+ Analyze_And_Resolve (Else_Expr, Typ);
+ Append_To (Expressions (N), Else_Expr);
+
+ else
+ Error_Msg_N ("can only omit ELSE expression in Boolean case", N);
+ Append_To (Expressions (N), Error);
+ end if;
+
+ Set_Etype (N, Typ);
+ Eval_If_Expression (N);
+
+ -- If we still have a if expression, and overflow checks are enabled in
+ -- MINIMIZED or ELIMINATED modes, then set Do_Overflow_Check to ensure
+ -- that we handle overflow for dependent expressions.
+
+ if Nkind (N) = N_If_Expression
+ and then Overflow_Check_Mode (Typ) in Minimized_Or_Eliminated
+ then
+ Set_Do_Overflow_Check (N);
+ end if;
+ end Resolve_If_Expression;
+
-------------------------------
-- Resolve_Indexed_Component --
-------------------------------
@@ -7641,10 +7685,11 @@ package body Sem_Res is
----------------------------
procedure Resolve_Set_Membership is
- Alt : Node_Id;
+ Alt : Node_Id;
+ Ltyp : constant Entity_Id := Etype (L);
begin
- Resolve (L, Etype (L));
+ Resolve (L, Ltyp);
Alt := First (Alternatives (N));
while Present (Alt) loop
@@ -7655,11 +7700,51 @@ package body Sem_Res is
if not Is_Entity_Name (Alt)
or else not Is_Type (Entity (Alt))
then
- Resolve (Alt, Etype (L));
+ Resolve (Alt, Ltyp);
end if;
Next (Alt);
end loop;
+
+ -- Check for duplicates for discrete case
+
+ if Is_Discrete_Type (Ltyp) then
+ declare
+ type Ent is record
+ Alt : Node_Id;
+ Val : Uint;
+ end record;
+
+ Alts : array (0 .. List_Length (Alternatives (N))) of Ent;
+ Nalts : Nat;
+
+ begin
+ -- Loop checking duplicates. This is quadratic, but giant sets
+ -- are unlikely in this context so it's a reasonable choice.
+
+ Nalts := 0;
+ Alt := First (Alternatives (N));
+ while Present (Alt) loop
+ if Is_Static_Expression (Alt)
+ and then (Nkind_In (Alt, N_Integer_Literal,
+ N_Character_Literal)
+ or else Nkind (Alt) in N_Has_Entity)
+ then
+ Nalts := Nalts + 1;
+ Alts (Nalts) := (Alt, Expr_Value (Alt));
+
+ for J in 1 .. Nalts - 1 loop
+ if Alts (J).Val = Alts (Nalts).Val then
+ Error_Msg_Sloc := Sloc (Alts (J).Alt);
+ Error_Msg_N ("duplicate of value given#?", Alt);
+ end if;
+ end loop;
+ end if;
+
+ Alt := Next (Alt);
+ end loop;
+ end;
+ end if;
end Resolve_Set_Membership;
-- Start of processing for Resolve_Membership_Op
@@ -9580,6 +9665,13 @@ package body Sem_Res is
then
null;
+ -- Never warn on conversion to Long_Long_Integer'Base since
+ -- that is most likely an artifact of the extended overflow
+ -- checking and comes from complex expanded code.
+
+ elsif Orig_T = Base_Type (Standard_Long_Long_Integer) then
+ null;
+
-- Here we give the redundant conversion warning. If it is an
-- entity, give the name of the entity in the message. If not,
-- just mention the expression.
@@ -9692,6 +9784,22 @@ package body Sem_Res is
end if;
end;
end if;
+
+ -- Ada 2012: if target type has predicates, the result requires a
+ -- predicate check. If the context is a call to another predicate
+ -- check we must prevent infinite recursion.
+
+ if Has_Predicates (Target_Typ) then
+ if Nkind (Parent (N)) = N_Function_Call
+ and then Present (Name (Parent (N)))
+ and then Has_Predicates (Entity (Name (Parent (N))))
+ then
+ null;
+
+ else
+ Apply_Predicate_Check (N, Target_Typ);
+ end if;
+ end if;
end Resolve_Type_Conversion;
----------------------
diff --git a/gcc/ada/sem_type.adb b/gcc/ada/sem_type.adb
index ec50247ef..0c46536e9 100644
--- a/gcc/ada/sem_type.adb
+++ b/gcc/ada/sem_type.adb
@@ -741,7 +741,6 @@ package body Sem_Type is
------------
function Covers (T1, T2 : Entity_Id) return Boolean is
-
BT1 : Entity_Id;
BT2 : Entity_Id;
diff --git a/gcc/ada/sem_util.adb b/gcc/ada/sem_util.adb
index 9d095309f..1c9eb6455 100644
--- a/gcc/ada/sem_util.adb
+++ b/gcc/ada/sem_util.adb
@@ -37,6 +37,7 @@ with Freeze; use Freeze;
with Lib; use Lib;
with Lib.Xref; use Lib.Xref;
with Nlists; use Nlists;
+with Nmake; use Nmake;
with Output; use Output;
with Opt; use Opt;
with Restrict; use Restrict;
@@ -278,6 +279,63 @@ package body Sem_Util is
return Alignment (E) * System_Storage_Unit;
end Alignment_In_Bits;
+ ---------------------------------
+ -- Append_Inherited_Subprogram --
+ ---------------------------------
+
+ procedure Append_Inherited_Subprogram (S : Entity_Id) is
+ Par : constant Entity_Id := Alias (S);
+ -- The parent subprogram
+
+ Scop : constant Entity_Id := Scope (Par);
+ -- The scope of definition of the parent subprogram
+
+ Typ : constant Entity_Id := Defining_Entity (Parent (S));
+ -- The derived type of which S is a primitive operation
+
+ Decl : Node_Id;
+ Next_E : Entity_Id;
+
+ begin
+ if Ekind (Current_Scope) = E_Package
+ and then In_Private_Part (Current_Scope)
+ and then Has_Private_Declaration (Typ)
+ and then Is_Tagged_Type (Typ)
+ and then Scop = Current_Scope
+ then
+ -- The inherited operation is available at the earliest place after
+ -- the derived type declaration ( RM 7.3.1 (6/1)). This is only
+ -- relevant for type extensions. If the parent operation appears
+ -- after the type extension, the operation is not visible.
+
+ Decl := First
+ (Visible_Declarations
+ (Specification (Unit_Declaration_Node (Current_Scope))));
+ while Present (Decl) loop
+ if Nkind (Decl) = N_Private_Extension_Declaration
+ and then Defining_Entity (Decl) = Typ
+ then
+ if Sloc (Decl) > Sloc (Par) then
+ Next_E := Next_Entity (Par);
+ Set_Next_Entity (Par, S);
+ Set_Next_Entity (S, Next_E);
+ return;
+
+ else
+ exit;
+ end if;
+ end if;
+
+ Next (Decl);
+ end loop;
+ end if;
+
+ -- If partial view is not a type extension, or it appears before the
+ -- subprogram declaration, insert normally at end of entity list.
+
+ Append_Entity (S, Current_Scope);
+ end Append_Inherited_Subprogram;
+
-----------------------------------------
-- Apply_Compile_Time_Constraint_Error --
-----------------------------------------
@@ -1191,6 +1249,50 @@ package body Sem_Util is
end if;
end Check_Implicit_Dereference;
+ ----------------------------------
+ -- Check_Internal_Protected_Use --
+ ----------------------------------
+
+ procedure Check_Internal_Protected_Use (N : Node_Id; Nam : Entity_Id) is
+ S : Entity_Id;
+ Prot : Entity_Id;
+
+ begin
+ S := Current_Scope;
+ while Present (S) loop
+ if S = Standard_Standard then
+ return;
+
+ elsif Ekind (S) = E_Function
+ and then Ekind (Scope (S)) = E_Protected_Type
+ then
+ Prot := Scope (S);
+ exit;
+ end if;
+
+ S := Scope (S);
+ end loop;
+
+ if Scope (Nam) = Prot and then Ekind (Nam) /= E_Function then
+ if Nkind (N) = N_Subprogram_Renaming_Declaration then
+ Error_Msg_N
+ ("within protected function cannot use protected "
+ & "procedure in renaming or as generic actual", N);
+
+ elsif Nkind (N) = N_Attribute_Reference then
+ Error_Msg_N
+ ("within protected function cannot take access of "
+ & " protected procedure", N);
+
+ else
+ Error_Msg_N
+ ("within protected function, protected object is constant", N);
+ Error_Msg_N
+ ("\cannot call operation that may modify it", N);
+ end if;
+ end if;
+ end Check_Internal_Protected_Use;
+
---------------------------------------
-- Check_Later_Vs_Basic_Declarations --
---------------------------------------
@@ -2206,9 +2308,9 @@ package body Sem_Util is
Msgs := False;
exit;
- -- Conditional expression
+ -- If expression
- elsif Nkind (P) = N_Conditional_Expression then
+ elsif Nkind (P) = N_If_Expression then
declare
Cond : constant Node_Id := First (Expressions (P));
Texp : constant Node_Id := Next (Cond);
@@ -2387,6 +2489,45 @@ package body Sem_Util is
return Plist;
end Copy_Parameter_List;
+ --------------------------------
+ -- Corresponding_Generic_Type --
+ --------------------------------
+
+ function Corresponding_Generic_Type (T : Entity_Id) return Entity_Id is
+ Inst : Entity_Id;
+ Gen : Entity_Id;
+ Typ : Entity_Id;
+
+ begin
+ if not Is_Generic_Actual_Type (T) then
+ return Any_Type;
+
+ else
+ Inst := Scope (T);
+
+ if Is_Wrapper_Package (Inst) then
+ Inst := Related_Instance (Inst);
+ end if;
+
+ Gen :=
+ Generic_Parent
+ (Specification (Unit_Declaration_Node (Inst)));
+
+ -- Generic actual has the same name as the corresponding formal
+
+ Typ := First_Entity (Gen);
+ while Present (Typ) loop
+ if Chars (Typ) = Chars (T) then
+ return Typ;
+ end if;
+
+ Next_Entity (Typ);
+ end loop;
+
+ return Any_Type;
+ end if;
+ end Corresponding_Generic_Type;
+
--------------------
-- Current_Entity --
--------------------
@@ -7719,10 +7860,12 @@ package body Sem_Util is
when N_Function_Call =>
return Etype (N) /= Standard_Void_Type;
- -- A reference to the stream attribute Input is a function call
+ -- Attributes 'Input and 'Result produce objects
when N_Attribute_Reference =>
- return Attribute_Name (N) = Name_Input;
+ return Attribute_Name (N) = Name_Input
+ or else
+ Attribute_Name (N) = Name_Result;
when N_Selected_Component =>
return
@@ -12100,13 +12243,15 @@ package body Sem_Util is
begin
Desc := N;
+ -- Seems dubious that case expressions are not handled here ???
+
P := Parent (N);
while Present (P) loop
if 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))
- or else (Nkind (P) = N_Conditional_Expression
+ or else (Nkind (P) = N_If_Expression
and then Desc /= First (Expressions (P)))
or else Nkind (P) = N_Exception_Handler
or else Nkind (P) = N_Selective_Accept
@@ -13477,7 +13622,9 @@ package body Sem_Util is
function Has_One_Matching_Field return Boolean;
-- Determines if Expec_Type is a record type with a single component or
-- discriminant whose type matches the found type or is one dimensional
- -- array whose component type matches the found type.
+ -- array whose component type matches the found type. In the case of
+ -- one discriminant, we ignore the variant parts. That's not accurate,
+ -- but good enough for the warning.
----------------------------
-- Has_One_Matching_Field --
@@ -13519,10 +13666,10 @@ package body Sem_Util is
if No (E) then
return False;
- elsif (Ekind (E) /= E_Discriminant
- and then Ekind (E) /= E_Component)
+ elsif not Ekind_In (E, E_Discriminant, E_Component)
or else (Chars (E) = Name_uTag
- or else Chars (E) = Name_uParent)
+ or else
+ Chars (E) = Name_uParent)
then
Next_Entity (E);
@@ -13534,7 +13681,10 @@ package body Sem_Util is
if not Covers (Etype (E), Found_Type) then
return False;
- elsif Present (Next_Entity (E)) then
+ elsif Present (Next_Entity (E))
+ and then (Ekind (E) = E_Component
+ or else Ekind (Next_Entity (E)) = E_Discriminant)
+ then
return False;
else
diff --git a/gcc/ada/sem_util.ads b/gcc/ada/sem_util.ads
index 8d1f7cfad..1b089b85e 100644
--- a/gcc/ada/sem_util.ads
+++ b/gcc/ada/sem_util.ads
@@ -28,7 +28,6 @@
with Einfo; use Einfo;
with Exp_Tss; use Exp_Tss;
with Namet; use Namet;
-with Nmake; use Nmake;
with Snames; use Snames;
with Types; use Types;
with Uintp; use Uintp;
@@ -64,6 +63,12 @@ package Sem_Util is
-- Otherwise Uint_0 is returned, indicating that the alignment of the
-- entity is not yet known to the compiler.
+ procedure Append_Inherited_Subprogram (S : Entity_Id);
+ -- If the parent of the operation is declared in the visible part of
+ -- the current scope, the inherited operation is visible even though the
+ -- derived type that inherits the operation may be completed in the private
+ -- part of the current package.
+
procedure Apply_Compile_Time_Constraint_Error
(N : Node_Id;
Msg : String;
@@ -170,6 +175,12 @@ package Sem_Util is
-- checks whether T is a reference type, and if so it adds an interprettion
-- to Expr whose type is the designated type of the reference_discriminant.
+ procedure Check_Internal_Protected_Use (N : Node_Id; Nam : Entity_Id);
+ -- Within a protected function, the current object is a constant, and
+ -- internal calls to a procedure or entry are illegal. Similarly, other
+ -- uses of a protected procedure in a renaming or a generic instantiation
+ -- in the context of a protected function are illegal (AI05-0225).
+
procedure Check_Later_Vs_Basic_Declarations
(Decls : List_Id;
During_Parsing : Boolean);
@@ -288,6 +299,12 @@ package Sem_Util is
-- create a new compatible record type. Loc is the source location assigned
-- to the created nodes.
+ function Corresponding_Generic_Type (T : Entity_Id) return Entity_Id;
+ -- If a type is a generic actual type, return the corresponding formal in
+ -- the generic parent unit. There is no direct link in the tree for this
+ -- attribute, except in the case of formal private and derived types.
+ -- Possible optimization???
+
function Current_Entity (N : Node_Id) return Entity_Id;
pragma Inline (Current_Entity);
-- Find the currently visible definition for a given identifier, that is to
@@ -1087,13 +1104,6 @@ package Sem_Util is
-- statement in Statements (HSS) that has Comes_From_Source set. If no
-- such statement exists, Empty is returned.
- function Make_Simple_Return_Statement
- (Sloc : Source_Ptr;
- Expression : Node_Id := Empty) return Node_Id
- renames Make_Return_Statement;
- -- See Sinfo. We rename Make_Return_Statement to the correct Ada 2005
- -- terminology here. Clients should use Make_Simple_Return_Statement.
-
function Matching_Static_Array_Bounds
(L_Typ : Node_Id;
R_Typ : Node_Id) return Boolean;
@@ -1101,15 +1111,6 @@ package Sem_Util is
-- same number of dimensions, and the same static bounds for each index
-- position.
- Make_Return_Statement : constant := -2 ** 33;
- -- Attempt to prevent accidental uses of Make_Return_Statement. If this
- -- and the one in Nmake are both potentially use-visible, it will cause
- -- a compilation error. Note that type and value are irrelevant.
-
- N_Return_Statement : constant := -2 ** 33;
- -- Attempt to prevent accidental uses of N_Return_Statement; similar to
- -- Make_Return_Statement above.
-
procedure Mark_Coextensions (Context_Nod : Node_Id; Root_Nod : Node_Id);
-- Given a node which designates the context of analysis and an origin in
-- the tree, traverse from Root_Nod and mark all allocators as either
diff --git a/gcc/ada/sem_warn.adb b/gcc/ada/sem_warn.adb
index e41cad4aa..34bc4582c 100644
--- a/gcc/ada/sem_warn.adb
+++ b/gcc/ada/sem_warn.adb
@@ -103,7 +103,7 @@ package body Sem_Warn is
-- and then Has_Warnings_Off (E)
-- This way if some-other-predicate is false, we avoid a false indication
- -- that a Warnings (Off,E) pragma was useful in preventing a warning.
+ -- that a Warnings (Off, E) pragma was useful in preventing a warning.
-- The second rule is that if both Has_Unmodified and Has_Warnings_Off, or
-- Has_Unreferenced and Has_Warnings_Off are called, make sure that the
@@ -472,32 +472,41 @@ package body Sem_Warn is
return Abandon;
end if;
- -- If we appear in the context of a procedure call, then also
- -- abandon, since there may be issues of non-visible side
- -- effects going on in the call.
+ -- If the condition contains a function call, we consider it may
+ -- be modified by side-effects from a procedure call. Otherwise,
+ -- we consider the condition may not be modified, although that
+ -- might happen if Variable is itself a by-reference parameter,
+ -- and the procedure called modifies the global object referred to
+ -- by Variable, but we actually prefer to issue a warning in this
+ -- odd case. Note that the case where the procedure called has
+ -- visibility over Variable is treated in another case below.
- declare
- P : Node_Id;
+ if Function_Call_Found then
+ declare
+ P : Node_Id;
- begin
- P := N;
- loop
- P := Parent (P);
- exit when P = Loop_Statement;
-
- -- Abandon if at procedure call, or something strange is
- -- going on (perhaps a node with no parent that should
- -- have one but does not?) As always, for a warning we
- -- prefer to just abandon the warning than get into the
- -- business of complaining about the tree structure here!
-
- if No (P) or else Nkind (P) = N_Procedure_Call_Statement then
- return Abandon;
- end if;
- end loop;
- end;
+ begin
+ P := N;
+ loop
+ P := Parent (P);
+ exit when P = Loop_Statement;
+
+ -- Abandon if at procedure call, or something strange is
+ -- going on (perhaps a node with no parent that should
+ -- have one but does not?) As always, for a warning we
+ -- prefer to just abandon the warning than get into the
+ -- business of complaining about the tree structure here!
+
+ if No (P)
+ or else Nkind (P) = N_Procedure_Call_Statement
+ then
+ return Abandon;
+ end if;
+ end loop;
+ end;
+ end if;
- -- Reference to variable renaming variable in question
+ -- Reference to variable renaming variable in question
elsif Is_Entity_Name (N)
and then Present (Entity (N))
@@ -509,7 +518,7 @@ package body Sem_Warn is
then
return Abandon;
- -- Call to subprogram
+ -- Call to subprogram
elsif Nkind (N) in N_Subprogram_Call then
diff --git a/gcc/ada/sinfo.adb b/gcc/ada/sinfo.adb
index d2413ad2c..32f7edaab 100644
--- a/gcc/ada/sinfo.adb
+++ b/gcc/ada/sinfo.adb
@@ -370,7 +370,7 @@ package body Sinfo is
begin
pragma Assert (False
or else NT (N).Nkind = N_Extended_Return_Statement
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
return Flag5 (N);
end By_Ref;
@@ -427,7 +427,7 @@ package body Sinfo is
(N : Node_Id) return Boolean is
begin
pragma Assert (False
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
return Flag18 (N);
end Comes_From_Extended_Return_Statement;
@@ -927,6 +927,8 @@ package body Sinfo is
pragma Assert (False
or else NT (N).Nkind in N_Op
or else NT (N).Nkind = N_Attribute_Reference
+ or else NT (N).Nkind = N_Case_Expression
+ or else NT (N).Nkind = N_If_Expression
or else NT (N).Nkind = N_Type_Conversion);
return Flag17 (N);
end Do_Overflow_Check;
@@ -956,7 +958,7 @@ package body Sinfo is
or else NT (N).Nkind = N_Extended_Return_Statement
or else NT (N).Nkind = N_Function_Call
or else NT (N).Nkind = N_Procedure_Call_Statement
- or else NT (N).Nkind = N_Return_Statement
+ or else NT (N).Nkind = N_Simple_Return_Statement
or else NT (N).Nkind = N_Type_Conversion);
return Flag13 (N);
end Do_Tag_Check;
@@ -1006,7 +1008,7 @@ package body Sinfo is
(N : Node_Id) return List_Id is
begin
pragma Assert (False
- or else NT (N).Nkind = N_Conditional_Expression);
+ or else NT (N).Nkind = N_If_Expression);
return List3 (N);
end Else_Actions;
@@ -1232,7 +1234,7 @@ package body Sinfo is
or else NT (N).Nkind = N_Pragma_Argument_Association
or else NT (N).Nkind = N_Qualified_Expression
or else NT (N).Nkind = N_Raise_Statement
- or else NT (N).Nkind = N_Return_Statement
+ or else NT (N).Nkind = N_Simple_Return_Statement
or else NT (N).Nkind = N_Type_Conversion
or else NT (N).Nkind = N_Unchecked_Expression
or else NT (N).Nkind = N_Unchecked_Type_Conversion);
@@ -1245,8 +1247,8 @@ package body Sinfo is
pragma Assert (False
or else NT (N).Nkind = N_Aggregate
or else NT (N).Nkind = N_Attribute_Reference
- or else NT (N).Nkind = N_Conditional_Expression
or else NT (N).Nkind = N_Extension_Aggregate
+ or else NT (N).Nkind = N_If_Expression
or else NT (N).Nkind = N_Indexed_Component);
return List1 (N);
end Expressions;
@@ -1743,7 +1745,7 @@ package body Sinfo is
(N : Node_Id) return Boolean is
begin
pragma Assert (False
- or else NT (N).Nkind = N_Conditional_Expression);
+ or else NT (N).Nkind = N_If_Expression);
return Flag13 (N);
end Is_Elsif;
@@ -2235,6 +2237,15 @@ package body Sinfo is
return Flag13 (N);
end No_Initialization;
+ function No_Minimize_Eliminate
+ (N : Node_Id) return Boolean is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_In
+ or else NT (N).Nkind = N_Not_In);
+ return Flag17 (N);
+ end No_Minimize_Eliminate;
+
function No_Truncation
(N : Node_Id) return Boolean is
begin
@@ -2526,7 +2537,7 @@ package body Sinfo is
or else NT (N).Nkind = N_Allocator
or else NT (N).Nkind = N_Extended_Return_Statement
or else NT (N).Nkind = N_Free_Statement
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
return Node2 (N);
end Procedure_To_Call;
@@ -2659,7 +2670,7 @@ package body Sinfo is
begin
pragma Assert (False
or else NT (N).Nkind = N_Extended_Return_Statement
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
return Node5 (N);
end Return_Statement_Entity;
@@ -2851,7 +2862,7 @@ package body Sinfo is
or else NT (N).Nkind = N_Allocator
or else NT (N).Nkind = N_Extended_Return_Statement
or else NT (N).Nkind = N_Free_Statement
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
return Node1 (N);
end Storage_Pool;
@@ -2979,7 +2990,7 @@ package body Sinfo is
(N : Node_Id) return List_Id is
begin
pragma Assert (False
- or else NT (N).Nkind = N_Conditional_Expression);
+ or else NT (N).Nkind = N_If_Expression);
return List2 (N);
end Then_Actions;
@@ -3432,7 +3443,7 @@ package body Sinfo is
begin
pragma Assert (False
or else NT (N).Nkind = N_Extended_Return_Statement
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
Set_Flag5 (N, Val);
end Set_By_Ref;
@@ -3489,7 +3500,7 @@ package body Sinfo is
(N : Node_Id; Val : Boolean := True) is
begin
pragma Assert (False
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
Set_Flag18 (N, Val);
end Set_Comes_From_Extended_Return_Statement;
@@ -3989,6 +4000,8 @@ package body Sinfo is
pragma Assert (False
or else NT (N).Nkind in N_Op
or else NT (N).Nkind = N_Attribute_Reference
+ or else NT (N).Nkind = N_Case_Expression
+ or else NT (N).Nkind = N_If_Expression
or else NT (N).Nkind = N_Type_Conversion);
Set_Flag17 (N, Val);
end Set_Do_Overflow_Check;
@@ -4018,7 +4031,7 @@ package body Sinfo is
or else NT (N).Nkind = N_Extended_Return_Statement
or else NT (N).Nkind = N_Function_Call
or else NT (N).Nkind = N_Procedure_Call_Statement
- or else NT (N).Nkind = N_Return_Statement
+ or else NT (N).Nkind = N_Simple_Return_Statement
or else NT (N).Nkind = N_Type_Conversion);
Set_Flag13 (N, Val);
end Set_Do_Tag_Check;
@@ -4068,7 +4081,7 @@ package body Sinfo is
(N : Node_Id; Val : List_Id) is
begin
pragma Assert (False
- or else NT (N).Nkind = N_Conditional_Expression);
+ or else NT (N).Nkind = N_If_Expression);
Set_List3 (N, Val); -- semantic field, no parent set
end Set_Else_Actions;
@@ -4285,7 +4298,7 @@ package body Sinfo is
or else NT (N).Nkind = N_Pragma_Argument_Association
or else NT (N).Nkind = N_Qualified_Expression
or else NT (N).Nkind = N_Raise_Statement
- or else NT (N).Nkind = N_Return_Statement
+ or else NT (N).Nkind = N_Simple_Return_Statement
or else NT (N).Nkind = N_Type_Conversion
or else NT (N).Nkind = N_Unchecked_Expression
or else NT (N).Nkind = N_Unchecked_Type_Conversion);
@@ -4298,8 +4311,8 @@ package body Sinfo is
pragma Assert (False
or else NT (N).Nkind = N_Aggregate
or else NT (N).Nkind = N_Attribute_Reference
- or else NT (N).Nkind = N_Conditional_Expression
or else NT (N).Nkind = N_Extension_Aggregate
+ or else NT (N).Nkind = N_If_Expression
or else NT (N).Nkind = N_Indexed_Component);
Set_List1_With_Parent (N, Val);
end Set_Expressions;
@@ -4796,7 +4809,7 @@ package body Sinfo is
(N : Node_Id; Val : Boolean := True) is
begin
pragma Assert (False
- or else NT (N).Nkind = N_Conditional_Expression);
+ or else NT (N).Nkind = N_If_Expression);
Set_Flag13 (N, Val);
end Set_Is_Elsif;
@@ -5288,6 +5301,15 @@ package body Sinfo is
Set_Flag13 (N, Val);
end Set_No_Initialization;
+ procedure Set_No_Minimize_Eliminate
+ (N : Node_Id; Val : Boolean := True) is
+ begin
+ pragma Assert (False
+ or else NT (N).Nkind = N_In
+ or else NT (N).Nkind = N_Not_In);
+ Set_Flag17 (N, Val);
+ end Set_No_Minimize_Eliminate;
+
procedure Set_No_Truncation
(N : Node_Id; Val : Boolean := True) is
begin
@@ -5579,7 +5601,7 @@ package body Sinfo is
or else NT (N).Nkind = N_Allocator
or else NT (N).Nkind = N_Extended_Return_Statement
or else NT (N).Nkind = N_Free_Statement
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
Set_Node2 (N, Val); -- semantic field, no parent set
end Set_Procedure_To_Call;
@@ -5712,7 +5734,7 @@ package body Sinfo is
begin
pragma Assert (False
or else NT (N).Nkind = N_Extended_Return_Statement
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
Set_Node5 (N, Val); -- semantic field, no parent set
end Set_Return_Statement_Entity;
@@ -5904,7 +5926,7 @@ package body Sinfo is
or else NT (N).Nkind = N_Allocator
or else NT (N).Nkind = N_Extended_Return_Statement
or else NT (N).Nkind = N_Free_Statement
- or else NT (N).Nkind = N_Return_Statement);
+ or else NT (N).Nkind = N_Simple_Return_Statement);
Set_Node1 (N, Val); -- semantic field, no parent set
end Set_Storage_Pool;
@@ -6032,7 +6054,7 @@ package body Sinfo is
(N : Node_Id; Val : List_Id) is
begin
pragma Assert (False
- or else NT (N).Nkind = N_Conditional_Expression);
+ or else NT (N).Nkind = N_If_Expression);
Set_List2 (N, Val); -- semantic field, no parent set
end Set_Then_Actions;
diff --git a/gcc/ada/sinfo.ads b/gcc/ada/sinfo.ads
index 560d6c24b..39e9acba8 100644
--- a/gcc/ada/sinfo.ads
+++ b/gcc/ada/sinfo.ads
@@ -668,9 +668,8 @@ package Sinfo is
-- Compile_Time_Known_Aggregate (Flag18-Sem)
-- Present in N_Aggregate nodes. Set for aggregates which can be fully
-- evaluated at compile time without raising constraint error. Such
- -- aggregates can be passed as is to Gigi without any expansion. See
- -- Exp_Aggr for the specific conditions under which an aggregate has this
- -- flag set.
+ -- aggregates can be passed as is the back end without any expansion.
+ -- See Exp_Aggr for specific conditions under which this flag gets set.
-- Componentwise_Assignment (Flag14-Sem)
-- Present in N_Assignment_Statement nodes. Set for a record assignment
@@ -824,7 +823,10 @@ package Sinfo is
-- See also the description of Do_Range_Check for this case. The only
-- attribute references which use this flag are Pred and Succ, where it
-- means that the result should be checked for going outside the base
- -- range. Note that this flag is not set for modular types.
+ -- range. Note that this flag is not set for modular types. This flag is
+ -- also set on if and case expression nodes if we are operating in either
+ -- MINIMIZED or ELIMINATED overflow checking mode (to make sure that we
+ -- properly process overflow checking for dependent expressions).
-- Do_Range_Check (Flag9-Sem)
-- This flag is set on an expression which appears in a context where a
@@ -906,12 +908,12 @@ package Sinfo is
-- boolean is required.
-- Else_Actions (List3-Sem)
- -- This field is present in conditional expression nodes. During code
+ -- This field is present in if expression nodes. During code
-- expansion we use the Insert_Actions procedure (in Exp_Util) to insert
-- actions at an appropriate place in the tree to get elaborated at the
- -- right time. For conditional expressions, we have to be sure that the
- -- actions for the Else branch are only elaborated if the condition is
- -- False. The Else_Actions field is used as a temporary parking place for
+ -- right time. For if expressions, we have to be sure that the actions
+ -- for the Else branch are only elaborated if the condition is False.
+ -- The Else_Actions field is used as a temporary parking place for
-- these actions. The final tree is always rewritten to eliminate the
-- need for this field, so in the tree passed to Gigi, this field is
-- always set to No_List.
@@ -1546,6 +1548,11 @@ package Sinfo is
-- should not be taken into account (needed for in place initialization
-- with aggregates).
+ -- No_Minimize_Eliminate (Flag17-Sem)
+ -- This flag is present in membership operator nodes (N_In/N_Not_In).
+ -- It is used to indicate that processing for extended overflow checking
+ -- modes is not required (this is used to prevent infinite recursion).
+
-- No_Truncation (Flag17-Sem)
-- Present in N_Unchecked_Type_Conversion node. This flag has an effect
-- only if the RM_Size of the source is greater than the RM_Size of the
@@ -1754,12 +1761,12 @@ package Sinfo is
-- do size validation for.
-- Then_Actions (List3-Sem)
- -- This field is present in conditional expression nodes. During code
- -- expansion we use the Insert_Actions procedure (in Exp_Util) to insert
- -- actions at an appropriate place in the tree to get elaborated at the
- -- right time. For conditional expressions, we have to be sure that the
- -- actions for the Then branch are only elaborated if the condition is
- -- True. The Then_Actions field is used as a temporary parking place for
+ -- This field is present in if expression nodes. During code expansion
+ -- we use the Insert_Actions procedure (in Exp_Util) to insert actions
+ -- at an appropriate place in the tree to get elaborated at the right
+ -- time. For if expressions, we have to be sure that the actions for
+ -- for the Then branch are only elaborated if the condition is True.
+ -- The Then_Actions field is used as a temporary parking place for
-- these actions. The final tree is always rewritten to eliminate the
-- need for this field, so in the tree passed to Gigi, this field is
-- always set to No_List.
@@ -3676,6 +3683,7 @@ package Sinfo is
-- Left_Opnd (Node2)
-- Right_Opnd (Node3)
-- Alternatives (List4) (set to No_List if only one set alternative)
+ -- No_Minimize_Eliminate (Flag17)
-- plus fields for expression
-- N_Not_In
@@ -3683,6 +3691,7 @@ package Sinfo is
-- Left_Opnd (Node2)
-- Right_Opnd (Node3)
-- Alternatives (List4) (set to No_List if only one set alternative)
+ -- No_Minimize_Eliminate (Flag17)
-- plus fields for expression
--------------------
@@ -3850,6 +3859,89 @@ package Sinfo is
-- point operands if the Treat_Fixed_As_Integer flag is set and will
-- thus treat these nodes in identical manner, ignoring small values.
+ -- Note on overflow handling: When the overflow checking mode is set to
+ -- MINIMIZED or ELIMINATED, nodes for signed arithmetic operations may
+ -- be modified to use a larger type for the operands and result. In
+ -- the case where the computed range exceeds that of Long_Long_Integer,
+ -- and we are running in ELIMINATED mode, the operator node will be
+ -- changed to be a call to the appropriate routine in System.Bignums.
+
+ ------------------------------------
+ -- 4.5.7 Conditional Expressions --
+ ------------------------------------
+
+ -- CONDITIONAL_EXPRESSION ::= IF_EXPRESSION | CASE_EXPRESSION
+
+ --------------------------
+ -- 4.5.7 If Expression --
+ ----------------------------
+
+ -- IF_EXPRESSION ::=
+ -- if CONDITION then DEPENDENT_EXPRESSION
+ -- {elsif CONDITION then DEPENDENT_EXPRESSION}
+ -- [else DEPENDENT_EXPRESSION]
+
+ -- DEPENDENT_EXPRESSION ::= EXPRESSION
+
+ -- Note: if we have (IF x1 THEN x2 ELSIF x3 THEN x4 ELSE x5) then it
+ -- is represented as (IF x1 THEN x2 ELSE (IF x3 THEN x4 ELSE x5)) and
+ -- the Is_Elsif flag is set on the inner if expression.
+
+ -- N_If_Expression
+ -- Sloc points to IF or ELSIF keyword
+ -- Expressions (List1)
+ -- Then_Actions (List2-Sem)
+ -- Else_Actions (List3-Sem)
+ -- Is_Elsif (Flag13) (set if comes from ELSIF)
+ -- Do_Overflow_Check (Flag17-Sem)
+ -- plus fields for expression
+
+ -- Expressions here is a three-element list, whose first element is the
+ -- condition, the second element is the dependent expression after THEN
+ -- and the third element is the dependent expression after the ELSE
+ -- (explicitly set to True if missing).
+
+ -- Note: the Then_Actions and Else_Actions fields are always set to
+ -- No_List in the tree passed to Gigi. These fields are used only
+ -- for temporary processing purposes in the expander.
+
+ ----------------------------
+ -- 4.5.7 Case Expression --
+ ----------------------------
+
+ -- CASE_EXPRESSION ::=
+ -- case SELECTING_EXPRESSION is
+ -- CASE_EXPRESSION_ALTERNATIVE
+ -- {CASE_EXPRESSION_ALTERNATIVE}
+
+ -- Note that the Alternatives cannot include pragmas (this contrasts
+ -- with the situation of case statements where pragmas are allowed).
+
+ -- N_Case_Expression
+ -- Sloc points to CASE
+ -- Expression (Node3) (the selecting expression)
+ -- Alternatives (List4) (the case expression alternatives)
+ -- Do_Overflow_Check (Flag17-Sem)
+
+ ----------------------------------------
+ -- 4.5.7 Case Expression Alternative --
+ ----------------------------------------
+
+ -- CASE_EXPRESSION_ALTERNATIVE ::=
+ -- when DISCRETE_CHOICE_LIST =>
+ -- DEPENDENT_EXPRESSION
+
+ -- N_Case_Expression_Alternative
+ -- Sloc points to WHEN
+ -- Actions (List1)
+ -- Discrete_Choices (List4)
+ -- Expression (Node3)
+
+ -- Note: The Actions field temporarily holds any actions associated with
+ -- evaluation of the Expression. During expansion of the case expression
+ -- these actions are wrapped into an N_Expressions_With_Actions node
+ -- replacing the original expression.
+
---------------------------------
-- 4.5.9 Quantified Expression --
---------------------------------
@@ -4290,6 +4382,14 @@ package Sinfo is
-- Note: Exception_Junk is set for the wrapping blocks created during
-- local raise optimization (Exp_Ch11.Expand_Local_Exception_Handlers).
+ -- Note: from a control flow viewpoint, a block statement defines an
+ -- extended basic block, i.e. the entry of the block dominates every
+ -- statement in the sequence. When generating new statements with
+ -- exception handlers in the expander at the end of a sequence that
+ -- comes from source code, it can be necessary to wrap them all in a
+ -- block statement in order to expose the implicit control flow to
+ -- gigi and thus prevent it from issuing bogus control flow warnings.
+
-- N_Block_Statement
-- Sloc points to DECLARE or BEGIN
-- Identifier (Node1) block direct name (set to Empty if not present)
@@ -4699,10 +4799,6 @@ package Sinfo is
-- 6.5 Return Statement --
---------------------------
- -- RETURN_STATEMENT ::= return [EXPRESSION]; -- Ada 95
-
- -- In Ada 2005, we have:
-
-- SIMPLE_RETURN_STATEMENT ::= return [EXPRESSION];
-- EXTENDED_RETURN_STATEMENT ::=
@@ -4713,11 +4809,12 @@ package Sinfo is
-- RETURN_SUBTYPE_INDICATION ::= SUBTYPE_INDICATION | ACCESS_DEFINITION
- -- So in Ada 2005, RETURN_STATEMENT is no longer a nonterminal, but
- -- "return statement" is defined in 6.5 to mean a
- -- SIMPLE_RETURN_STATEMENT or an EXTENDED_RETURN_STATEMENT.
+ -- 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
+ -- versions of Ada.
- -- N_Return_Statement
+ -- N_Simple_Return_Statement
-- Sloc points to RETURN
-- Return_Statement_Entity (Node5-Sem)
-- Expression (Node3) (set to Empty if no expression present)
@@ -4727,12 +4824,6 @@ package Sinfo is
-- By_Ref (Flag5-Sem)
-- Comes_From_Extended_Return_Statement (Flag18-Sem)
- -- N_Return_Statement represents a simple_return_statement, and is
- -- renamed to be N_Simple_Return_Statement below. Clients should refer
- -- to N_Simple_Return_Statement. We retain N_Return_Statement because
- -- that's how gigi knows it. See also renaming of Make_Return_Statement
- -- as Make_Simple_Return_Statement in Sem_Util.
-
-- Note: Return_Statement_Entity points to an E_Return_Statement
-- If a range check is required, then Do_Range_Check is set on the
@@ -6846,88 +6937,6 @@ package Sinfo is
-- reconstructed tree printed by Sprint, and the node descriptions here
-- show this syntax.
- -- Note: Case_Expression and Conditional_Expression is in this section for
- -- now, since they are extensions. We will move them to their appropriate
- -- places when they are officially approved as extensions (and then we will
- -- know what the exact grammar and place in the Reference Manual is!)
-
- ---------------------
- -- Case Expression --
- ---------------------
-
- -- CASE_EXPRESSION ::=
- -- case EXPRESSION is
- -- CASE_EXPRESSION_ALTERNATIVE
- -- {CASE_EXPRESSION_ALTERNATIVE}
-
- -- Note that the Alternatives cannot include pragmas (this contrasts
- -- with the situation of case statements where pragmas are allowed).
-
- -- N_Case_Expression
- -- Sloc points to CASE
- -- Expression (Node3)
- -- Alternatives (List4)
-
- ---------------------------------
- -- Case Expression Alternative --
- ---------------------------------
-
- -- CASE_STATEMENT_ALTERNATIVE ::=
- -- when DISCRETE_CHOICE_LIST =>
- -- EXPRESSION
-
- -- N_Case_Expression_Alternative
- -- Sloc points to WHEN
- -- Actions (List1)
- -- Discrete_Choices (List4)
- -- Expression (Node3)
-
- -- Note: The Actions field temporarily holds any actions associated with
- -- evaluation of the Expression. During expansion of the case expression
- -- these actions are wrapped into an N_Expressions_With_Actions node
- -- replacing the original expression.
-
- ----------------------------
- -- Conditional Expression --
- ----------------------------
-
- -- This node is used to represent an expression corresponding to the
- -- C construct (condition ? then-expression : else_expression), where
- -- Expressions is a three element list, whose first expression is the
- -- condition, and whose second and third expressions are the then and
- -- else expressions respectively.
-
- -- Note: the Then_Actions and Else_Actions fields are always set to
- -- No_List in the tree passed to Gigi. These fields are used only
- -- for temporary processing purposes in the expander.
-
- -- The Ada language does not permit conditional expressions, however
- -- this is under discussion as a possible extension by the ARG, and we
- -- have implemented a form of this capability in GNAT under control of
- -- the -gnatX switch. The syntax is:
-
- -- CONDITIONAL_EXPRESSION ::=
- -- if EXPRESSION then EXPRESSION
- -- {elsif EXPRESSION then EXPRESSION}
- -- [else EXPRESSION]
-
- -- And we add the additional constructs
-
- -- PRIMARY ::= ( CONDITIONAL_EXPRESSION )
- -- PRAGMA_ARGUMENT_ASSOCIATION ::= CONDITIONAL_EXPRESSION
-
- -- Note: if we have (IF x1 THEN x2 ELSIF x3 THEN x4 ELSE x5) then it
- -- is represented as (IF x1 THEN x2 ELSE (IF x3 THEN x4 ELSE x5)) and
- -- the Is_Elsif flag is set on the inner conditional expression.
-
- -- N_Conditional_Expression
- -- Sloc points to IF or ELSIF keyword
- -- Expressions (List1)
- -- Then_Actions (List2-Sem)
- -- Else_Actions (List3-Sem)
- -- Is_Elsif (Flag13) (set if comes from ELSIF)
- -- plus fields for expression
-
--------------
-- Contract --
--------------
@@ -7610,12 +7619,6 @@ package Sinfo is
N_And_Then,
N_Or_Else,
- -- N_Subexpr, N_Has_Etype
-
- N_Conditional_Expression,
- N_Explicit_Dereference,
- N_Expression_With_Actions,
-
-- N_Subexpr, N_Has_Etype, N_Subprogram_Call
N_Function_Call,
@@ -7623,6 +7626,9 @@ package Sinfo is
-- N_Subexpr, N_Has_Etype
+ N_Explicit_Dereference,
+ N_Expression_With_Actions,
+ N_If_Expression,
N_Indexed_Component,
N_Integer_Literal,
N_Null,
@@ -7770,7 +7776,7 @@ package Sinfo is
N_Null_Statement,
N_Raise_Statement,
N_Requeue_Statement,
- N_Return_Statement, -- renamed as N_Simple_Return_Statement below
+ N_Simple_Return_Statement,
N_Extended_Return_Statement,
N_Selective_Accept,
N_Timed_Entry_Call,
@@ -8771,6 +8777,9 @@ package Sinfo is
function No_Initialization
(N : Node_Id) return Boolean; -- Flag13
+ function No_Minimize_Eliminate
+ (N : Node_Id) return Boolean; -- Flag17
+
function No_Truncation
(N : Node_Id) return Boolean; -- Flag17
@@ -9743,6 +9752,9 @@ package Sinfo is
procedure Set_No_Initialization
(N : Node_Id; Val : Boolean := True); -- Flag13
+ procedure Set_No_Minimize_Eliminate
+ (N : Node_Id; Val : Boolean := True); -- Flag17
+
procedure Set_No_Truncation
(N : Node_Id; Val : Boolean := True); -- Flag17
@@ -10921,7 +10933,7 @@ package Sinfo is
4 => False, -- Next_Named_Actual (Node4-Sem)
5 => False), -- unused
- N_Return_Statement =>
+ N_Simple_Return_Statement =>
(1 => False, -- Storage_Pool (Node1-Sem)
2 => False, -- Procedure_To_Call (Node2-Sem)
3 => True, -- Expression (Node3)
@@ -11551,7 +11563,7 @@ package Sinfo is
4 => True, -- Pragmas_Before (List4)
5 => False), -- unused
- N_Conditional_Expression =>
+ N_If_Expression =>
(1 => True, -- Expressions (List1)
2 => False, -- Then_Actions (List2-Sem)
3 => False, -- Else_Actions (List3-Sem)
@@ -11994,6 +12006,7 @@ package Sinfo is
pragma Inline (No_Elaboration_Check);
pragma Inline (No_Entities_Ref_In_Spec);
pragma Inline (No_Initialization);
+ pragma Inline (No_Minimize_Eliminate);
pragma Inline (No_Truncation);
pragma Inline (Null_Present);
pragma Inline (Null_Exclusion_Present);
@@ -12314,6 +12327,7 @@ package Sinfo is
pragma Inline (Set_No_Elaboration_Check);
pragma Inline (Set_No_Entities_Ref_In_Spec);
pragma Inline (Set_No_Initialization);
+ pragma Inline (Set_No_Minimize_Eliminate);
pragma Inline (Set_No_Truncation);
pragma Inline (Set_Null_Present);
pragma Inline (Set_Null_Exclusion_Present);
@@ -12405,18 +12419,4 @@ package Sinfo is
pragma Inline (Set_Was_Originally_Stub);
pragma Inline (Set_Withed_Body);
- --------------
- -- Synonyms --
- --------------
-
- -- These synonyms are to aid in transition, they should eventually be
- -- removed when all remaining references to the obsolete name are gone.
-
- N_Simple_Return_Statement : constant Node_Kind := N_Return_Statement;
- -- Rename N_Return_Statement to be N_Simple_Return_Statement. Clients
- -- should refer to N_Simple_Return_Statement.
-
- N_Parameterized_Expression : constant Node_Kind := N_Expression_Function;
- -- Old name for expression functions (used during Ada 2012 transition)
-
end Sinfo;
diff --git a/gcc/ada/sinput-c.adb b/gcc/ada/sinput-c.adb
index aebdcacdd..4ad212b43 100644
--- a/gcc/ada/sinput-c.adb
+++ b/gcc/ada/sinput-c.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -178,9 +178,10 @@ package body Sinput.C is
Full_Debug_Name => Path_Id,
Full_File_Name => Path_Id,
Full_Ref_Name => Path_Id,
+ Instance => No_Instance_Id,
Identifier_Casing => Unknown,
+ Inlined_Call => No_Location,
Inlined_Body => False,
- Instantiation => No_Location,
Keyword_Casing => Unknown,
Last_Source_Line => 1,
License => Unknown,
diff --git a/gcc/ada/sinput-l.adb b/gcc/ada/sinput-l.adb
index 52f3a713b..59d2aed4f 100644
--- a/gcc/ada/sinput-l.adb
+++ b/gcc/ada/sinput-l.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -38,6 +38,8 @@ with Prep; use Prep;
with Prepcomp; use Prepcomp;
with Scans; use Scans;
with Scn; use Scn;
+with Sem_Aux; use Sem_Aux;
+with Sem_Util; use Sem_Util;
with Sinfo; use Sinfo;
with Snames; use Snames;
with System; use System;
@@ -138,127 +140,191 @@ package body Sinput.L is
Source_File.Append (Source_File.Table (Xold));
Xnew := Source_File.Last;
- Source_File.Table (Xnew).Inlined_Body := Inlined_Body;
- Source_File.Table (Xnew).Instantiation := Sloc (Inst_Node);
- Source_File.Table (Xnew).Template := Xold;
+ declare
+ Sold : Source_File_Record renames Source_File.Table (Xold);
+ Snew : Source_File_Record renames Source_File.Table (Xnew);
- -- Now we need to compute the new values of Source_First, Source_Last
- -- and adjust the source file pointer to have the correct virtual
- -- origin for the new range of values.
+ Inst_Spec : Node_Id;
- Source_File.Table (Xnew).Source_First :=
- Source_File.Table (Xnew - 1).Source_Last + 1;
- A.Adjust := Source_File.Table (Xnew).Source_First - A.Lo;
- Source_File.Table (Xnew).Source_Last := A.Hi + A.Adjust;
+ begin
+ Snew.Inlined_Body := Inlined_Body;
+ Snew.Template := Xold;
- Set_Source_File_Index_Table (Xnew);
+ -- For a genuine generic instantiation, assign new instance id.
+ -- For inlined bodies, we retain that of the template, but we
+ -- save the call location.
- Source_File.Table (Xnew).Sloc_Adjust :=
- Source_File.Table (Xold).Sloc_Adjust - A.Adjust;
+ if Inlined_Body then
+ Snew.Inlined_Call := Sloc (Inst_Node);
- if Debug_Flag_L then
- Write_Eol;
- Write_Str ("*** Create instantiation source for ");
+ else
- if Nkind (Dnod) in N_Proper_Body
- and then Was_Originally_Stub (Dnod)
- then
- Write_Str ("subunit ");
+ -- If the spec has been instantiated already, and we are now
+ -- creating the instance source for the corresponding body now,
+ -- retrieve the instance id that was assigned to the spec, which
+ -- corresponds to the same instantiation sloc.
+
+ Inst_Spec := Instance_Spec (Inst_Node);
+ if Present (Inst_Spec) then
+ declare
+ Inst_Spec_Ent : Entity_Id;
+ -- Instance spec entity
+
+ Inst_Spec_Sloc : Source_Ptr;
+ -- Virtual sloc of the spec instance source
+
+ Inst_Spec_Inst_Id : Instance_Id;
+ -- Instance id assigned to the instance spec
+
+ begin
+ Inst_Spec_Ent := Defining_Entity (Inst_Spec);
+
+ -- For a subprogram instantiation, we want the subprogram
+ -- instance, not the wrapper package.
+
+ if Present (Related_Instance (Inst_Spec_Ent)) then
+ Inst_Spec_Ent := Related_Instance (Inst_Spec_Ent);
+ end if;
+
+ -- The specification of the instance entity has a virtual
+ -- sloc within the instance sloc range.
+ -- ??? But the Unit_Declaration_Node has the sloc of the
+ -- instantiation, which is somewhat of an oddity.
+
+ Inst_Spec_Sloc :=
+ Sloc (Specification (Unit_Declaration_Node
+ (Inst_Spec_Ent)));
+ Inst_Spec_Inst_Id :=
+ Source_File.Table
+ (Get_Source_File_Index (Inst_Spec_Sloc)).Instance;
+
+ pragma Assert
+ (Sloc (Inst_Node) = Instances.Table (Inst_Spec_Inst_Id));
+ Snew.Instance := Inst_Spec_Inst_Id;
+ end;
- elsif Ekind (Template_Id) = E_Generic_Package then
- if Nkind (Dnod) = N_Package_Body then
- Write_Str ("body of package ");
else
- Write_Str ("spec of package ");
+ Instances.Append (Sloc (Inst_Node));
+ Snew.Instance := Instances.Last;
end if;
+ end if;
- elsif Ekind (Template_Id) = E_Function then
- Write_Str ("body of function ");
+ -- Now we need to compute the new values of Source_First,
+ -- Source_Last and adjust the source file pointer to have the
+ -- correct virtual origin for the new range of values.
- elsif Ekind (Template_Id) = E_Procedure then
- Write_Str ("body of procedure ");
+ Snew.Source_First := Source_File.Table (Xnew - 1).Source_Last + 1;
+ A.Adjust := Snew.Source_First - A.Lo;
+ Snew.Source_Last := A.Hi + A.Adjust;
- elsif Ekind (Template_Id) = E_Generic_Function then
- Write_Str ("spec of function ");
+ Set_Source_File_Index_Table (Xnew);
- elsif Ekind (Template_Id) = E_Generic_Procedure then
- Write_Str ("spec of procedure ");
+ Snew.Sloc_Adjust := Sold.Sloc_Adjust - A.Adjust;
- elsif Ekind (Template_Id) = E_Package_Body then
- Write_Str ("body of package ");
+ if Debug_Flag_L then
+ Write_Eol;
+ Write_Str ("*** Create instantiation source for ");
- else pragma Assert (Ekind (Template_Id) = E_Subprogram_Body);
+ if Nkind (Dnod) in N_Proper_Body
+ and then Was_Originally_Stub (Dnod)
+ then
+ Write_Str ("subunit ");
- if Nkind (Dnod) = N_Procedure_Specification then
- Write_Str ("body of procedure ");
- else
+ elsif Ekind (Template_Id) = E_Generic_Package then
+ if Nkind (Dnod) = N_Package_Body then
+ Write_Str ("body of package ");
+ else
+ Write_Str ("spec of package ");
+ end if;
+
+ elsif Ekind (Template_Id) = E_Function then
Write_Str ("body of function ");
+
+ elsif Ekind (Template_Id) = E_Procedure then
+ Write_Str ("body of procedure ");
+
+ elsif Ekind (Template_Id) = E_Generic_Function then
+ Write_Str ("spec of function ");
+
+ elsif Ekind (Template_Id) = E_Generic_Procedure then
+ Write_Str ("spec of procedure ");
+
+ elsif Ekind (Template_Id) = E_Package_Body then
+ Write_Str ("body of package ");
+
+ else pragma Assert (Ekind (Template_Id) = E_Subprogram_Body);
+
+ if Nkind (Dnod) = N_Procedure_Specification then
+ Write_Str ("body of procedure ");
+ else
+ Write_Str ("body of function ");
+ end if;
end if;
- end if;
- Write_Name (Chars (Template_Id));
- Write_Eol;
+ Write_Name (Chars (Template_Id));
+ Write_Eol;
- Write_Str (" new source index = ");
- Write_Int (Int (Xnew));
- Write_Eol;
+ Write_Str (" new source index = ");
+ Write_Int (Int (Xnew));
+ Write_Eol;
- Write_Str (" copying from file name = ");
- Write_Name (File_Name (Xold));
- Write_Eol;
+ Write_Str (" copying from file name = ");
+ Write_Name (File_Name (Xold));
+ Write_Eol;
- Write_Str (" old source index = ");
- Write_Int (Int (Xold));
- Write_Eol;
+ Write_Str (" old source index = ");
+ Write_Int (Int (Xold));
+ Write_Eol;
- Write_Str (" old lo = ");
- Write_Int (Int (A.Lo));
- Write_Eol;
+ Write_Str (" old lo = ");
+ Write_Int (Int (A.Lo));
+ Write_Eol;
- Write_Str (" old hi = ");
- Write_Int (Int (A.Hi));
- Write_Eol;
+ Write_Str (" old hi = ");
+ Write_Int (Int (A.Hi));
+ Write_Eol;
- Write_Str (" new lo = ");
- Write_Int (Int (Source_File.Table (Xnew).Source_First));
- Write_Eol;
+ Write_Str (" new lo = ");
+ Write_Int (Int (Snew.Source_First));
+ Write_Eol;
- Write_Str (" new hi = ");
- Write_Int (Int (Source_File.Table (Xnew).Source_Last));
- Write_Eol;
+ Write_Str (" new hi = ");
+ Write_Int (Int (Snew.Source_Last));
+ Write_Eol;
- Write_Str (" adjustment factor = ");
- Write_Int (Int (A.Adjust));
- Write_Eol;
+ Write_Str (" adjustment factor = ");
+ Write_Int (Int (A.Adjust));
+ Write_Eol;
- Write_Str (" instantiation location: ");
- Write_Location (Sloc (Inst_Node));
- Write_Eol;
- end if;
+ Write_Str (" instantiation location: ");
+ Write_Location (Sloc (Inst_Node));
+ Write_Eol;
+ end if;
- -- For a given character in the source, a higher subscript will be used
- -- to access the instantiation, which means that the virtual origin must
- -- have a corresponding lower value. We compute this new origin by
- -- taking the address of the appropriate adjusted element in the old
- -- array. Since this adjusted element will be at a negative subscript,
- -- we must suppress checks.
+ -- For a given character in the source, a higher subscript will be
+ -- used to access the instantiation, which means that the virtual
+ -- origin must have a corresponding lower value. We compute this new
+ -- origin by taking the address of the appropriate adjusted element
+ -- in the old array. Since this adjusted element will be at a
+ -- negative subscript, we must suppress checks.
- declare
- pragma Suppress (All_Checks);
+ declare
+ pragma Suppress (All_Checks);
- pragma Warnings (Off);
- -- This unchecked conversion is aliasing safe, since it is never used
- -- to create improperly aliased pointer values.
+ pragma Warnings (Off);
+ -- This unchecked conversion is aliasing safe, since it is never
+ -- used to create improperly aliased pointer values.
- function To_Source_Buffer_Ptr is new
- Unchecked_Conversion (Address, Source_Buffer_Ptr);
+ function To_Source_Buffer_Ptr is new
+ Unchecked_Conversion (Address, Source_Buffer_Ptr);
- pragma Warnings (On);
+ pragma Warnings (On);
- begin
- Source_File.Table (Xnew).Source_Text :=
- To_Source_Buffer_Ptr
- (Source_File.Table (Xold).Source_Text (-A.Adjust)'Address);
+ begin
+ Snew.Source_Text :=
+ To_Source_Buffer_Ptr
+ (Sold.Source_Text (-A.Adjust)'Address);
+ end;
end;
end Create_Instantiation_Source;
@@ -433,9 +499,10 @@ package body Sinput.L is
Full_Debug_Name => Osint.Full_Source_Name,
Full_File_Name => Osint.Full_Source_Name,
Full_Ref_Name => Osint.Full_Source_Name,
+ Instance => No_Instance_Id,
Identifier_Casing => Unknown,
+ Inlined_Call => No_Location,
Inlined_Body => False,
- Instantiation => No_Location,
Keyword_Casing => Unknown,
Last_Source_Line => 1,
License => Unknown,
diff --git a/gcc/ada/sinput.adb b/gcc/ada/sinput.adb
index 5e1ac44b6..29be59ac6 100644
--- a/gcc/ada/sinput.adb
+++ b/gcc/ada/sinput.adb
@@ -477,8 +477,26 @@ package body Sinput is
First_Time_Around := True;
Source_File.Init;
+
+ Instances.Init;
+ Instances.Append (No_Location);
+ pragma Assert (Instances.Last = No_Instance_Id);
end Initialize;
+ -------------------
+ -- Instantiation --
+ -------------------
+
+ function Instantiation (S : SFI) return Source_Ptr is
+ SIE : Source_File_Record renames Source_File.Table (S);
+ begin
+ if SIE.Inlined_Body then
+ return SIE.Inlined_Call;
+ else
+ return Instances.Table (SIE.Instance);
+ end if;
+ end Instantiation;
+
-------------------------
-- Instantiation_Depth --
-------------------------
@@ -511,6 +529,17 @@ package body Sinput is
return Instantiation (Get_Source_File_Index (S));
end Instantiation_Location;
+ --------------------------
+ -- Iterate_On_Instances --
+ --------------------------
+
+ procedure Iterate_On_Instances is
+ begin
+ for J in 1 .. Instances.Last loop
+ Process (J, Instances.Table (J));
+ end loop;
+ end Iterate_On_Instances;
+
----------------------
-- Last_Source_File --
----------------------
@@ -852,7 +881,7 @@ package body Sinput is
Tmp1 : Source_Buffer_Ptr;
begin
- if S.Instantiation /= No_Location then
+ if S.Instance /= No_Instance_Id then
null;
else
@@ -887,9 +916,10 @@ package body Sinput is
Source_Cache_First := 1;
Source_Cache_Last := 0;
- -- Read in source file table
+ -- Read in source file table and instance table
Source_File.Tree_Read;
+ Instances.Tree_Read;
-- The pointers we read in there for the source buffer and lines
-- table pointers are junk. We now read in the actual data that
@@ -904,7 +934,7 @@ package body Sinput is
-- we share the data for the generic template entry. Since the
-- template always occurs first, we can safely refer to its data.
- if S.Instantiation /= No_Location then
+ if S.Instance /= No_Instance_Id then
declare
ST : Source_File_Record renames
Source_File.Table (S.Template);
@@ -1004,6 +1034,7 @@ package body Sinput is
procedure Tree_Write is
begin
Source_File.Tree_Write;
+ Instances.Tree_Write;
-- The pointers we wrote out there for the source buffer and lines
-- table pointers are junk, we now write out the actual data that
@@ -1018,7 +1049,7 @@ package body Sinput is
-- shared with the generic template. When the tree is read, the
-- pointers must be set, but no extra data needs to be written.
- if S.Instantiation /= No_Location then
+ if S.Instance /= No_Instance_Id then
null;
-- For the normal case, write out the data of the tables
@@ -1131,6 +1162,11 @@ package body Sinput is
return Source_File.Table (S).Debug_Source_Name;
end Debug_Source_Name;
+ function Instance (S : SFI) return Instance_Id is
+ begin
+ return Source_File.Table (S).Instance;
+ end Instance;
+
function File_Name (S : SFI) return File_Name_Type is
begin
return Source_File.Table (S).File_Name;
@@ -1171,10 +1207,10 @@ package body Sinput is
return Source_File.Table (S).Inlined_Body;
end Inlined_Body;
- function Instantiation (S : SFI) return Source_Ptr is
+ function Inlined_Call (S : SFI) return Source_Ptr is
begin
- return Source_File.Table (S).Instantiation;
- end Instantiation;
+ return Source_File.Table (S).Inlined_Call;
+ end Inlined_Call;
function Keyword_Casing (S : SFI) return Casing_Type is
begin
diff --git a/gcc/ada/sinput.ads b/gcc/ada/sinput.ads
index 32aab9d39..f678ff629 100644
--- a/gcc/ada/sinput.ads
+++ b/gcc/ada/sinput.ads
@@ -83,6 +83,9 @@ package Sinput is
Preproc);
-- Source file with preprocessing commands to be preprocessed
+ type Instance_Id is new Nat;
+ No_Instance_Id : constant Instance_Id;
+
----------------------------
-- Source License Control --
----------------------------
@@ -198,6 +201,12 @@ package Sinput is
-- Only processing in Sprint that generates this file is permitted to
-- set this field.
+ -- Instance : Instance_Id (read-only)
+ -- For entries corresponding to a generic instantiation, unique
+ -- identifier denoting the full chain of nested instantiations. Set to
+ -- No_Instance_Id for the case of a normal, non-instantiation entry.
+ -- See below for details on the handling of generic instantiations.
+
-- License : License_Type;
-- License status of source file
@@ -249,16 +258,16 @@ package Sinput is
-- This value is used for formatting of error messages, and also is used
-- in the detection of keywords misused as identifiers.
- -- Instantiation : Source_Ptr;
- -- Source file location of the instantiation if this source file entry
- -- represents a generic instantiation. Set to No_Location for the case
- -- of a normal non-instantiation entry. See section below for details.
+ -- Inlined_Call : Source_Ptr;
+ -- Source file location of the subprogram call if this source file entry
+ -- represents an inlined body. Set to No_Location otherwise.
-- This field is read-only for clients.
-- Inlined_Body : Boolean;
-- This can only be set True if Instantiation has a value other than
-- No_Location. If true it indicates that the instantiation is actually
-- an instance of an inlined body.
+ -- ??? Redundant, always equal to (Inlined_Call /= No_Location)
-- Template : Source_File_Index; (read-only)
-- Source file index of the source file containing the template if this
@@ -289,7 +298,8 @@ package Sinput is
function Full_Ref_Name (S : SFI) return File_Name_Type;
function Identifier_Casing (S : SFI) return Casing_Type;
function Inlined_Body (S : SFI) return Boolean;
- function Instantiation (S : SFI) return Source_Ptr;
+ function Inlined_Call (S : SFI) return Source_Ptr;
+ function Instance (S : SFI) return Instance_Id;
function Keyword_Casing (S : SFI) return Casing_Type;
function Last_Source_Line (S : SFI) return Physical_Line_Number;
function License (S : SFI) return License_Type;
@@ -408,17 +418,31 @@ package Sinput is
-- to point to the same text, because of the virtual origin pointers used
-- in the source table.
- -- The Instantiation field of this source file index entry, usually set
- -- to No_Source_File, instead contains the Sloc of the instantiation. In
- -- the case of nested instantiations, this Sloc may itself refer to an
- -- instantiation, so the complete chain can be traced.
+ -- The Instantiation_Id field of this source file index entry, set
+ -- to No_Instance_Id for normal entries, instead contains a value that
+ -- uniquely identifies a particular instantiation, and the associated
+ -- entry in the Instances table. The source location of the instantiation
+ -- can be retrieved using function Instantiation below. In the case of
+ -- nested instantiations, the Instances table can be used to trace the
+ -- complete chain of nested instantiations.
- -- Two routines are used to build these special entries in the source
- -- file table. Create_Instantiation_Source is first called to build
+ -- Two routines are used to build the special instance entries in the
+ -- source file table. Create_Instantiation_Source is first called to build
-- the virtual source table entry for the instantiation, and then the
-- Sloc values in the copy are adjusted using Adjust_Instantiation_Sloc.
-- See child unit Sinput.L for details on these two routines.
+ generic
+ with procedure Process (Id : Instance_Id; Inst_Sloc : Source_Ptr);
+ procedure Iterate_On_Instances;
+ -- Execute Process for each entry in the instance table
+
+ function Instantiation (S : SFI) return Source_Ptr;
+ -- For a source file entry that represents an inlined body, source location
+ -- of the inlined call. Otherwise, for a source file entry that represents
+ -- a generic instantiation, source location of the instantiation. Returns
+ -- No_Location in all other cases.
+
-----------------
-- Global Data --
-----------------
@@ -722,25 +746,37 @@ package Sinput is
private
pragma Inline (File_Name);
- pragma Inline (First_Mapped_Line);
pragma Inline (Full_File_Name);
- pragma Inline (Identifier_Casing);
- pragma Inline (Instantiation);
- pragma Inline (Keyword_Casing);
- pragma Inline (Last_Source_Line);
- pragma Inline (Last_Source_File);
+ pragma Inline (File_Type);
+ pragma Inline (Reference_Name);
+ pragma Inline (Full_Ref_Name);
+ pragma Inline (Debug_Source_Name);
+ pragma Inline (Full_Debug_Name);
+ pragma Inline (Instance);
pragma Inline (License);
pragma Inline (Num_SRef_Pragmas);
- pragma Inline (Num_Source_Files);
- pragma Inline (Num_Source_Lines);
- pragma Inline (Reference_Name);
- pragma Inline (Set_Keyword_Casing);
- pragma Inline (Set_Identifier_Casing);
+ pragma Inline (First_Mapped_Line);
+ pragma Inline (Source_Text);
pragma Inline (Source_First);
pragma Inline (Source_Last);
- pragma Inline (Source_Text);
- pragma Inline (Template);
pragma Inline (Time_Stamp);
+ pragma Inline (Source_Checksum);
+ pragma Inline (Last_Source_Line);
+ pragma Inline (Keyword_Casing);
+ pragma Inline (Identifier_Casing);
+ pragma Inline (Inlined_Call);
+ pragma Inline (Inlined_Body);
+ pragma Inline (Template);
+ pragma Inline (Unit);
+
+ pragma Inline (Set_Keyword_Casing);
+ pragma Inline (Set_Identifier_Casing);
+
+ pragma Inline (Last_Source_File);
+ pragma Inline (Num_Source_Files);
+ pragma Inline (Num_Source_Lines);
+
+ No_Instance_Id : constant Instance_Id := 0;
-------------------------
-- Source_Lines Tables --
@@ -781,6 +817,7 @@ private
Full_Debug_Name : File_Name_Type;
Full_File_Name : File_Name_Type;
Full_Ref_Name : File_Name_Type;
+ Instance : Instance_Id;
Num_SRef_Pragmas : Nat;
First_Mapped_Line : Logical_Line_Number;
Source_Text : Source_Buffer_Ptr;
@@ -788,11 +825,11 @@ private
Source_Last : Source_Ptr;
Source_Checksum : Word;
Last_Source_Line : Physical_Line_Number;
- Instantiation : Source_Ptr;
Template : Source_File_Index;
Unit : Unit_Number_Type;
Time_Stamp : Time_Stamp_Type;
File_Type : Type_Of_File;
+ Inlined_Call : Source_Ptr;
Inlined_Body : Boolean;
License : License_Type;
Keyword_Casing : Casing_Type;
@@ -839,17 +876,18 @@ private
Full_Debug_Name at 12 range 0 .. 31;
Full_File_Name at 16 range 0 .. 31;
Full_Ref_Name at 20 range 0 .. 31;
+ Instance at 48 range 0 .. 31;
Num_SRef_Pragmas at 24 range 0 .. 31;
First_Mapped_Line at 28 range 0 .. 31;
Source_First at 32 range 0 .. 31;
Source_Last at 36 range 0 .. 31;
Source_Checksum at 40 range 0 .. 31;
Last_Source_Line at 44 range 0 .. 31;
- Instantiation at 48 range 0 .. 31;
Template at 52 range 0 .. 31;
Unit at 56 range 0 .. 31;
Time_Stamp at 60 range 0 .. 8 * Time_Stamp_Length - 1;
File_Type at 74 range 0 .. 7;
+ Inlined_Call at 88 range 0 .. 31;
Inlined_Body at 75 range 0 .. 7;
License at 76 range 0 .. 7;
Keyword_Casing at 77 range 0 .. 7;
@@ -860,12 +898,12 @@ private
-- The following fields are pointers, so we have to specialize their
-- lengths using pointer size, obtained above as Standard'Address_Size.
- Source_Text at 88 range 0 .. AS - 1;
- Lines_Table at 88 range AS .. AS * 2 - 1;
- Logical_Lines_Table at 88 range AS * 2 .. AS * 3 - 1;
+ Source_Text at 92 range 0 .. AS - 1;
+ Lines_Table at 92 range AS .. AS * 2 - 1;
+ Logical_Lines_Table at 92 range AS * 2 .. AS * 3 - 1;
end record;
- for Source_File_Record'Size use 88 * 8 + AS * 3;
+ for Source_File_Record'Size use 92 * 8 + AS * 3;
-- This ensures that we did not leave out any fields
package Source_File is new Table.Table (
@@ -876,6 +914,17 @@ private
Table_Increment => Alloc.Source_File_Increment,
Table_Name => "Source_File");
+ -- Auxiliary table containing source location of instantiations. Index 0
+ -- is used for code that does not come from an instance.
+
+ package Instances is new Table.Table (
+ Table_Component_Type => Source_Ptr,
+ Table_Index_Type => Instance_Id,
+ Table_Low_Bound => 0,
+ Table_Initial => Alloc.Source_File_Initial,
+ Table_Increment => Alloc.Source_File_Increment,
+ Table_Name => "Instances");
+
-----------------
-- Subprograms --
-----------------
diff --git a/gcc/ada/snames.ads-tmpl b/gcc/ada/snames.ads-tmpl
index d0c20153b..167d11074 100644
--- a/gcc/ada/snames.ads-tmpl
+++ b/gcc/ada/snames.ads-tmpl
@@ -408,6 +408,7 @@ package Snames is
Name_No_Strict_Aliasing : constant Name_Id := N + $; -- GNAT
Name_Normalize_Scalars : constant Name_Id := N + $;
Name_Optimize_Alignment : constant Name_Id := N + $; -- GNAT
+ Name_Overflow_Checks : constant Name_Id := N + $; -- GNAT
Name_Persistent_BSS : constant Name_Id := N + $; -- GNAT
Name_Polling : constant Name_Id := N + $; -- GNAT
Name_Priority_Specific_Dispatching : constant Name_Id := N + $; -- Ada 05
@@ -651,6 +652,7 @@ package Snames is
Name_As_Is : constant Name_Id := N + $;
Name_Assertion : constant Name_Id := N + $;
+ Name_Assertions : constant Name_Id := N + $;
Name_Attribute_Name : constant Name_Id := N + $;
Name_Body_File_Name : constant Name_Id := N + $;
Name_Boolean_Entry_Barriers : constant Name_Id := N + $;
@@ -658,6 +660,8 @@ package Snames is
Name_By_Entry : constant Name_Id := N + $;
Name_By_Protected_Procedure : constant Name_Id := N + $;
Name_Casing : constant Name_Id := N + $;
+ Name_Check_All : constant Name_Id := N + $;
+ Name_Checked : constant Name_Id := N + $;
Name_Code : constant Name_Id := N + $;
Name_Component : constant Name_Id := N + $;
Name_Component_Size_4 : constant Name_Id := N + $;
@@ -667,6 +671,7 @@ package Snames is
Name_Disable : constant Name_Id := N + $;
Name_Dot_Replacement : constant Name_Id := N + $;
Name_Dynamic : constant Name_Id := N + $;
+ Name_Eliminated : constant Name_Id := N + $;
Name_Ensures : constant Name_Id := N + $;
Name_Entity : constant Name_Id := N + $;
Name_Entry_Count : constant Name_Id := N + $;
@@ -676,6 +681,7 @@ package Snames is
Name_Form : constant Name_Id := N + $;
Name_G_Float : constant Name_Id := N + $;
Name_Gcc : constant Name_Id := N + $;
+ Name_General : constant Name_Id := N + $;
Name_Gnat : constant Name_Id := N + $;
Name_GPL : constant Name_Id := N + $;
Name_IEEE_Float : constant Name_Id := N + $;
@@ -689,6 +695,7 @@ package Snames is
Name_Max_Size : constant Name_Id := N + $;
Name_Mechanism : constant Name_Id := N + $;
Name_Message : constant Name_Id := N + $;
+ Name_Minimized : constant Name_Id := N + $;
Name_Mixedcase : constant Name_Id := N + $;
Name_Mode : constant Name_Id := N + $;
Name_Modified_GPL : constant Name_Id := N + $;
@@ -727,6 +734,7 @@ package Snames is
Name_Static : constant Name_Id := N + $;
Name_Stack_Size : constant Name_Id := N + $;
Name_Subunit_File_Name : constant Name_Id := N + $;
+ Name_Suppressed : constant Name_Id := N + $;
Name_Task_Stack_Size_Default : constant Name_Id := N + $;
Name_Task_Type : constant Name_Id := N + $;
Name_Time_Slicing_Enabled : constant Name_Id := N + $;
@@ -1208,6 +1216,7 @@ package Snames is
Name_Leading_Required_Switches : constant Name_Id := N + $;
Name_Leading_Switches : constant Name_Id := N + $;
Name_Lib_Subdir : constant Name_Id := N + $;
+ Name_Link_Lib_Subdir : constant Name_Id := N + $;
Name_Library : constant Name_Id := N + $;
Name_Library_Ali_Dir : constant Name_Id := N + $;
Name_Library_Auto_Init : constant Name_Id := N + $;
@@ -1655,6 +1664,7 @@ package Snames is
Pragma_No_Strict_Aliasing,
Pragma_Normalize_Scalars,
Pragma_Optimize_Alignment,
+ Pragma_Overflow_Checks,
Pragma_Persistent_BSS,
Pragma_Polling,
Pragma_Priority_Specific_Dispatching,
diff --git a/gcc/ada/sprint.adb b/gcc/ada/sprint.adb
index 17aca3b83..0eee5d540 100644
--- a/gcc/ada/sprint.adb
+++ b/gcc/ada/sprint.adb
@@ -1320,27 +1320,6 @@ package body Sprint is
Sprint_Indented_List (Else_Statements (Node));
Write_Indent_Str ("end select;");
- when N_Conditional_Expression =>
- declare
- Condition : constant Node_Id := First (Expressions (Node));
- Then_Expr : constant Node_Id := Next (Condition);
-
- begin
- Write_Str_With_Col_Check_Sloc ("(if ");
- Sprint_Node (Condition);
- Write_Str_With_Col_Check (" then ");
-
- -- Defense against junk here!
-
- if Present (Then_Expr) then
- Sprint_Node (Then_Expr);
- Write_Str_With_Col_Check (" else ");
- Sprint_Node (Next (Then_Expr));
- end if;
-
- Write_Char (')');
- end;
-
when N_Constrained_Array_Definition =>
Write_Str_With_Col_Check_Sloc ("array ");
Sprint_Paren_Comma_List (Discrete_Subtype_Definitions (Node));
@@ -1978,6 +1957,27 @@ package body Sprint is
Set_Debug_Sloc;
Write_Id (Node);
+ when N_If_Expression =>
+ declare
+ Condition : constant Node_Id := First (Expressions (Node));
+ Then_Expr : constant Node_Id := Next (Condition);
+
+ begin
+ Write_Str_With_Col_Check_Sloc ("(if ");
+ Sprint_Node (Condition);
+ Write_Str_With_Col_Check (" then ");
+
+ -- Defense against junk here!
+
+ if Present (Then_Expr) then
+ Sprint_Node (Then_Expr);
+ Write_Str_With_Col_Check (" else ");
+ Sprint_Node (Next (Then_Expr));
+ end if;
+
+ Write_Char (')');
+ end;
+
when N_If_Statement =>
Write_Indent_Str_Sloc ("if ");
Sprint_Node (Condition (Node));
diff --git a/gcc/ada/sprint.ads b/gcc/ada/sprint.ads
index a44b9ed16..173d14867 100644
--- a/gcc/ada/sprint.ads
+++ b/gcc/ada/sprint.ads
@@ -48,7 +48,6 @@ package Sprint is
-- Allocator new xxx [storage_pool = xxx]
-- Cleanup action at end procedure name;
- -- Conditional expression (if expr then expr else expr)
-- Conversion wi Float_Truncate target^(source)
-- Convert wi Conversion_OK target?(source)
-- Convert wi Rounded_Result target@(source)
diff --git a/gcc/ada/style.ads b/gcc/ada/style.ads
index 9f9f32a93..b52a8fb12 100644
--- a/gcc/ada/style.ads
+++ b/gcc/ada/style.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -155,6 +155,11 @@ package Style is
-- check the line length (Len is the length of the current line). Note that
-- the terminator may be the EOF character.
+ procedure Check_Not_In
+ renames Style_Inst.Check_Not_In;
+ -- Called with Scan_Ptr pointing to an IN token, and Prev_Token_Ptr
+ -- pointing to a NOT token. Used to check proper layout of NOT IN.
+
procedure Check_Pragma_Name
renames Style_Inst.Check_Pragma_Name;
-- The current token is a pragma identifier. Check that it is spelled
@@ -185,8 +190,8 @@ package Style is
procedure Check_Xtra_Parens (Loc : Source_Ptr)
renames Style_Inst.Check_Xtra_Parens;
- -- Called after scanning a conditional expression that has at least one
- -- level of parentheses around the entire expression.
+ -- Called after scanning an if, case or quantified expression that has at
+ -- least one level of parentheses around the entire expression.
function Mode_In_Check return Boolean
renames Style_Inst.Mode_In_Check;
diff --git a/gcc/ada/styleg.adb b/gcc/ada/styleg.adb
index 7cb4d823a..c6743942a 100644
--- a/gcc/ada/styleg.adb
+++ b/gcc/ada/styleg.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -764,6 +764,24 @@ package body Styleg is
end if;
end Check_Line_Terminator;
+ ------------------
+ -- Check_Not_In --
+ ------------------
+
+ -- In check tokens mode, only one space between NOT and IN
+
+ procedure Check_Not_In is
+ begin
+ if Style_Check_Tokens then
+ if Source (Token_Ptr - 1) /= ' '
+ or else Token_Ptr - Prev_Token_Ptr /= 4
+ then -- CODEFIX?
+ Error_Msg
+ ("(style) single space must separate NOT and IN", Token_Ptr - 1);
+ end if;
+ end if;
+ end Check_Not_In;
+
--------------------------
-- Check_No_Space_After --
--------------------------
diff --git a/gcc/ada/styleg.ads b/gcc/ada/styleg.ads
index 954a03359..06e55341b 100644
--- a/gcc/ada/styleg.ads
+++ b/gcc/ada/styleg.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2010, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -117,6 +117,10 @@ package Styleg is
-- the current line, used to check for appropriate line terminator usage.
-- The parameter Len is the length of the current line.
+ procedure Check_Not_In;
+ -- Called with Scan_Ptr pointing to an IN token, and Prev_Token_Ptr
+ -- pointing to a NOT token. Used to check proper layout of NOT IN.
+
procedure Check_Pragma_Name;
-- The current token is a pragma identifier. Check that it is spelled
-- properly (i.e. with an appropriate casing convention).
@@ -147,8 +151,8 @@ package Styleg is
-- Called after scanning a vertical bar to check spacing
procedure Check_Xtra_Parens (Loc : Source_Ptr);
- -- Called after scanning a conditional expression that has at least one
- -- level of parentheses around the entire expression.
+ -- Called after scanning an if, case, or quantified expression that has at
+ -- least one level of parentheses around the entire expression.
function Mode_In_Check return Boolean;
pragma Inline (Mode_In_Check);
diff --git a/gcc/ada/stylesw.ads b/gcc/ada/stylesw.ads
index fc6f5ef13..26fa48097 100644
--- a/gcc/ada/stylesw.ads
+++ b/gcc/ada/stylesw.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -255,6 +255,8 @@ package Stylesw is
--
-- A unary plus or minus may not be followed by a space
--
+ -- There must be one blank (and no other white space) between NOT and IN
+ --
-- A vertical bar must be surrounded by spaces
--
-- Note that a requirement that a token be preceded by a space is met by
@@ -266,8 +268,8 @@ package Stylesw is
Style_Check_Xtra_Parens : Boolean := False;
-- This can be set True by using the -gnatyx switch. If true, then it is
- -- not allowed to enclose entire conditional expressions in parentheses
- -- (C style).
+ -- not allowed to enclose entire expressions in tests in parentheses
+ -- (C style), e.g. if (x = y) then ... is not allowed.
Style_Max_Line_Length : Int := 0;
-- Value used to check maximum line length. Gets reset as a result of
diff --git a/gcc/ada/switch-c.adb b/gcc/ada/switch-c.adb
index 4815c0973..2a96c06d1 100644
--- a/gcc/ada/switch-c.adb
+++ b/gcc/ada/switch-c.adb
@@ -33,6 +33,7 @@ with Osint; use Osint;
with Opt; use Opt;
with Validsw; use Validsw;
with Stylesw; use Stylesw;
+with Ttypes; use Ttypes;
with Warnsw; use Warnsw;
with Ada.Unchecked_Deallocation;
@@ -50,6 +51,10 @@ package body Switch.C is
new Ada.Unchecked_Deallocation (String_List, String_List_Access);
-- Avoid using System.Strings.Free, which also frees the designated strings
+ function Get_Overflow_Mode (C : Character) return Overflow_Check_Type;
+ -- Given a digit in the range 0 .. 3, returns the corresponding value of
+ -- Overflow_Check_Type. Raises Program_Error if C is outside this range.
+
function Switch_Subsequently_Cancelled
(C : String;
Args : String_List;
@@ -72,7 +77,6 @@ package body Switch.C is
declare
New_Symbol_Definitions : constant String_List_Access :=
new String_List (1 .. 2 * Preprocessing_Symbol_Last);
-
begin
New_Symbol_Definitions (Preprocessing_Symbol_Defs'Range) :=
Preprocessing_Symbol_Defs.all;
@@ -86,6 +90,37 @@ package body Switch.C is
new String'(Def);
end Add_Symbol_Definition;
+ -----------------------
+ -- Get_Overflow_Mode --
+ -----------------------
+
+ function Get_Overflow_Mode (C : Character) return Overflow_Check_Type is
+ begin
+ case C is
+ when '0' =>
+ return Suppressed;
+
+ when '1' =>
+ return Checked;
+
+ when '2' =>
+ return Minimized;
+
+ -- Eliminated allowed only if Long_Long_Integer is 64 bits (since
+ -- the current implementation of System.Bignums assumes this).
+
+ when '3' =>
+ if Standard_Long_Long_Integer_Size /= 64 then
+ Bad_Switch ("-gnato3 not implemented for this configuration");
+ else
+ return Eliminated;
+ end if;
+
+ when others =>
+ raise Program_Error;
+ end case;
+ end Get_Overflow_Mode;
+
-----------------------------
-- Scan_Front_End_Switches --
-----------------------------
@@ -128,9 +163,8 @@ package body Switch.C is
-- Handle switches that do not start with -gnat
- if Ptr + 3 > Max
- or else Switch_Chars (Ptr .. Ptr + 3) /= "gnat"
- then
+ if Ptr + 3 > Max or else Switch_Chars (Ptr .. Ptr + 3) /= "gnat" then
+
-- There are two front-end switches that do not start with -gnat:
-- -I, --RTS
@@ -381,6 +415,12 @@ package body Switch.C is
Enable_Switch_Storing;
Ptr := Ptr + 1;
+ -- -gnateA (aliasing checks on parameters)
+
+ when 'A' =>
+ Ptr := Ptr + 1;
+ Check_Aliasing_Of_Parameters := True;
+
-- -gnatec (configuration pragmas)
when 'c' =>
@@ -567,6 +607,22 @@ package body Switch.C is
when 'P' =>
Treat_Categorization_Errors_As_Warnings := True;
+ -- -gnateS (generate SCO information)
+
+ -- Include Source Coverage Obligation information in ALI
+ -- files for the benefit of source coverage analysis tools
+ -- (xcov).
+
+ when 'S' =>
+ Generate_SCO := True;
+ Ptr := Ptr + 1;
+
+ -- -gnateV (validity checks on parameters)
+
+ when 'V' =>
+ Ptr := Ptr + 1;
+ Check_Validity_Of_Parameters := True;
+
-- -gnatez (final delimiter of explicit switches)
-- All switches that come after -gnatez have been added by
@@ -578,16 +634,6 @@ package body Switch.C is
Disable_Switch_Storing;
Ptr := Ptr + 1;
- -- -gnateS (generate SCO information)
-
- -- Include Source Coverage Obligation information in ALI
- -- files for the benefit of source coverage analysis tools
- -- (xcov).
-
- when 'S' =>
- Generate_SCO := True;
- Ptr := Ptr + 1;
-
-- All other -gnate? switches are unassigned
when others =>
@@ -755,10 +801,39 @@ package body Switch.C is
when 'o' =>
Ptr := Ptr + 1;
- Suppress_Options.Suppress (Overflow_Check) := False;
- Suppress_Options.Overflow_Checks_General := Check_All;
- Suppress_Options.Overflow_Checks_Assertions := Check_All;
- Opt.Enable_Overflow_Checks := True;
+
+ -- Case of no digits after the -gnato
+
+ if Ptr > Max or else Switch_Chars (Ptr) not in '0' .. '3' then
+ Suppress_Options.Overflow_Checks_General := Checked;
+ Suppress_Options.Overflow_Checks_Assertions := Checked;
+
+ -- At least one digit after the -gnato
+
+ else
+ -- Handle first digit after -gnato
+
+ Suppress_Options.Overflow_Checks_General :=
+ Get_Overflow_Mode (Switch_Chars (Ptr));
+ Ptr := Ptr + 1;
+
+ -- Only one digit after -gnato, set assertions mode to
+ -- be the same as general mode.
+
+ if Ptr > Max
+ or else Switch_Chars (Ptr) not in '0' .. '3'
+ then
+ Suppress_Options.Overflow_Checks_Assertions :=
+ Suppress_Options.Overflow_Checks_General;
+
+ -- Process second digit after -gnato
+
+ else
+ Suppress_Options.Overflow_Checks_Assertions :=
+ Get_Overflow_Mode (Switch_Chars (Ptr));
+ Ptr := Ptr + 1;
+ end if;
+ end if;
-- Processing for O switch
@@ -792,14 +867,13 @@ package body Switch.C is
then
Suppress_Options.Suppress (J) := True;
end if;
-
- Suppress_Options.Overflow_Checks_General := Suppress;
- Suppress_Options.Overflow_Checks_Assertions := Suppress;
end loop;
- Validity_Checks_On := False;
- Opt.Suppress_Checks := True;
- Opt.Enable_Overflow_Checks := False;
+ Suppress_Options.Overflow_Checks_General := Suppressed;
+ Suppress_Options.Overflow_Checks_Assertions := Suppressed;
+
+ Validity_Checks_On := False;
+ Opt.Suppress_Checks := True;
end if;
-- Processing for P switch
diff --git a/gcc/ada/switch-m.adb b/gcc/ada/switch-m.adb
index d082c905f..0d769dc09 100644
--- a/gcc/ada/switch-m.adb
+++ b/gcc/ada/switch-m.adb
@@ -236,9 +236,9 @@ package body Switch.M is
-- One-letter switches
when 'a' | 'A' | 'b' | 'B' | 'c' | 'C' | 'E' | 'f' |
- 'F' | 'g' | 'h' | 'H' | 'I' | 'L' | 'N' | 'o' |
- 'p' | 'P' | 'q' | 'Q' | 'r' | 's' | 'S' | 't' |
- 'u' | 'U' | 'v' | 'x' | 'X' | 'Z' =>
+ 'F' | 'g' | 'h' | 'H' | 'I' | 'L' | 'N' | 'p' |
+ 'P' | 'q' | 'Q' | 'r' | 's' | 'S' | 't' | 'u' |
+ 'U' | 'v' | 'x' | 'X' | 'Z' =>
Storing (First_Stored) := C;
Add_Switch_Component
(Storing (Storing'First .. First_Stored));
@@ -441,6 +441,32 @@ package body Switch.M is
Add_Switch_Component
(Storing (Storing'First .. Last_Stored));
+ -- -gnato may be -gnatox or -gnatoxx, with x=0/1/2/3
+
+ when 'o' =>
+ Last_Stored := First_Stored;
+ Storing (Last_Stored) := 'o';
+ Ptr := Ptr + 1;
+
+ if Ptr <= Max
+ and then Switch_Chars (Ptr) in '0' .. '3'
+ then
+ Last_Stored := Last_Stored + 1;
+ Storing (Last_Stored) := Switch_Chars (Ptr);
+ Ptr := Ptr + 1;
+
+ if Ptr <= Max
+ and then Switch_Chars (Ptr) in '0' .. '3'
+ then
+ Last_Stored := Last_Stored + 1;
+ Storing (Last_Stored) := Switch_Chars (Ptr);
+ Ptr := Ptr + 1;
+ end if;
+ end if;
+
+ Add_Switch_Component
+ (Storing (Storing'First .. Last_Stored));
+
-- -gnatR may be followed by '0', '1', '2' or '3',
-- then by 's'
diff --git a/gcc/ada/switch.ads b/gcc/ada/switch.ads
index 5f02ba2a1..9a01384b6 100644
--- a/gcc/ada/switch.ads
+++ b/gcc/ada/switch.ads
@@ -128,6 +128,7 @@ private
procedure Bad_Switch (Switch : Character);
procedure Bad_Switch (Switch : String);
+ pragma No_Return (Bad_Switch);
-- Fail with an appropriate message when a switch is not recognized
end Switch;
diff --git a/gcc/ada/system-mingw.ads b/gcc/ada/system-mingw.ads
index dfb485208..ad64a84df 100644
--- a/gcc/ada/system-mingw.ads
+++ b/gcc/ada/system-mingw.ads
@@ -132,6 +132,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/system-solaris-sparcv9.ads b/gcc/ada/system-solaris-sparcv9.ads
index 6c059244e..a7db8dfab 100644
--- a/gcc/ada/system-solaris-sparcv9.ads
+++ b/gcc/ada/system-solaris-sparcv9.ads
@@ -132,6 +132,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/system-vms_64.ads b/gcc/ada/system-vms_64.ads
index 946f0341d..aa4fa3750 100644
--- a/gcc/ada/system-vms_64.ads
+++ b/gcc/ada/system-vms_64.ads
@@ -150,6 +150,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/tbuild.adb b/gcc/ada/tbuild.adb
index a9a7757fc..3343d7c81 100644
--- a/gcc/ada/tbuild.adb
+++ b/gcc/ada/tbuild.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -129,6 +129,15 @@ package body Tbuild is
end if;
end Convert_To;
+ ----------------------------
+ -- Convert_To_And_Rewrite --
+ ----------------------------
+
+ procedure Convert_To_And_Rewrite (Typ : Entity_Id; Expr : Node_Id) is
+ begin
+ Rewrite (Expr, Convert_To (Typ, Expr));
+ end Convert_To_And_Rewrite;
+
------------------
-- Discard_List --
------------------
diff --git a/gcc/ada/tbuild.ads b/gcc/ada/tbuild.ads
index 0ece7bd52..0feebe70c 100644
--- a/gcc/ada/tbuild.ads
+++ b/gcc/ada/tbuild.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -48,6 +48,12 @@ package Tbuild is
-- Exp. This means that it is safe to replace a node by a Convert_To
-- of itself to some other type.
+ procedure Convert_To_And_Rewrite (Typ : Entity_Id; Expr : Node_Id);
+ pragma Inline (Convert_To_And_Rewrite);
+ -- Like the function, except that there is an extra step of calling
+ -- Rewrite on the Expr node and replacing it with the converted result.
+ -- As noted above, this is safe, because Relocate_Node is called.
+
procedure Discard_Node (N : Node_Or_Entity_Id);
pragma Inline (Discard_Node);
-- This is a dummy procedure that simply returns and does nothing. It is
diff --git a/gcc/ada/types.ads b/gcc/ada/types.ads
index 03370cff6..277bfd551 100644
--- a/gcc/ada/types.ads
+++ b/gcc/ada/types.ads
@@ -706,51 +706,63 @@ package Types is
-- The following provides precise details on the mode used to check
-- intermediate overflows in expressions for signed integer arithmetic.
- type Overflow_Check_Type is
- (Suppress,
- -- Intermediate overflow suppressed. If an arithmetic operation creates
+ type Overflow_Check_Type is (
+ Not_Set,
+ -- Dummy value used during initialization process to show that the
+ -- corresponding value has not yet been initialized.
+
+ Suppressed,
+ -- Overflow checking is suppressed. If an arithmetic operation creates
-- an overflow, no exception is raised, and the program is erroneous.
- Check_All,
- -- All intermediate operations are checked. If the result of any
- -- arithmetic operation gives a result outside the range of the base
- -- type, then a Constraint_Error exception is raised.
+ Checked,
+ -- All operations, including all intermediate operations are checked.
+ -- If the result of any arithmetic operation gives a result outside the
+ -- range of the base type, then a Constraint_Error exception is raised.
- Minimize,
+ Minimized,
-- Where appropriate, arithmetic operations are performed with an
- -- extended range, using Long_Long_Integer if necessary. As long as
- -- the result fits in this extended range, then no exception is raised
- -- and computation continues with the extended result. The final value
- -- of an expression must fit in the base type of the whole expression.
- -- If an intermediate result is outside the range of Long_Long_Integer
- -- then a Constraint_Error exception is raised.
-
- Eliminate);
+ -- extended range, using Long_Long_Integer if necessary. As long as the
+ -- result fits in this extended range, then no exception is raised and
+ -- computation continues with the extended result. The final value of an
+ -- expression must fit in the base type of the whole expression. If an
+ -- intermediate result is outside the range of Long_Long_Integer then a
+ -- Constraint_Error exception is raised.
+
+ Eliminated);
-- In this mode arbitrary precision arithmetic is used as needed to
- -- ensure that it is impossible for intermediate arithmetic to cause
- -- an overflow. Again the final value of an expression must fit in
- -- the base type of the whole expression.
+ -- ensure that it is impossible for intermediate arithmetic to cause an
+ -- overflow. Again the final value of an expression must fit in the base
+ -- type of the whole expression.
+
+ subtype Minimized_Or_Eliminated is
+ Overflow_Check_Type range Minimized .. Eliminated;
+ subtype Suppressed_Or_Checked is
+ Overflow_Check_Type range Suppressed .. Checked;
+ -- Define subtypes so that clients don't need to know ordering. Note that
+ -- Overflow_Check_Type is not marked as an ordered enumeration type.
-- The following structure captures the state of check suppression or
-- activation at a particular point in the program execution.
type Suppress_Record is record
Suppress : Suppress_Array;
- -- Indicates suppression status of each possible check
+ -- Indicates suppression status of each possible check. Note: there
+ -- is an entry for Overflow_Check in this array, but it is never used.
+ -- Instead we use the more detailed information in the two components
+ -- that follow this one (Overflow_Checks_General/Assertions).
Overflow_Checks_General : Overflow_Check_Type;
- -- This field is relevant only if Suppress (Overflow_Check) is False.
- -- It indicates the mode of overflow checking to be applied to general
- -- expressions outside assertions.
+ -- This field indicates the mode of overflow checking to be applied to
+ -- general expressions outside assertions.
Overflow_Checks_Assertions : Overflow_Check_Type;
- -- This field is relevant only if Suppress (Overflow_Check) is False.
- -- It indicates the mode of overflow checking to be applied to any
- -- expressions occuring inside assertions.
+ -- This field indicates the mode of overflow checking to be applied to
+ -- any expression occuring inside assertions.
end record;
Suppress_All : constant Suppress_Record :=
- ((others => True), Suppress, Suppress);
+ ((others => True), Suppressed, Suppressed);
-- Constant used to initialize Suppress_Record value to all suppressed.
-----------------------------------
diff --git a/gcc/ada/types.h b/gcc/ada/types.h
index 4e29447f8..a0f28910d 100644
--- a/gcc/ada/types.h
+++ b/gcc/ada/types.h
@@ -6,7 +6,7 @@
* *
* C Header File *
* *
- * Copyright (C) 1992-2011, Free Software Foundation, Inc. *
+ * Copyright (C) 1992-2012, 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- *
@@ -130,6 +130,9 @@ typedef Text_Ptr Source_Ptr;
/* Used for Sloc in all nodes in the representation of package Standard. */
#define Standard_Location -2
+/* Instance identifiers */
+typedef Nat Instance_Id;
+
/* Type used for union of all possible ID values covering all ranges */
typedef int Union_Id;
diff --git a/gcc/ada/ug_words b/gcc/ada/ug_words
index 29c4ee0f2..a3ca96292 100644
--- a/gcc/ada/ug_words
+++ b/gcc/ada/ug_words
@@ -88,6 +88,7 @@ gcc -c ^ GNAT COMPILE
-gnatn2 ^ /INLINE=PRAGMA_LEVEL_2
-gnatN ^ /INLINE=FULL
-gnato ^ /CHECKS=OVERFLOW
+-gnato?? ^ /OVERFLOW_CHECKS=??
-gnatp ^ /CHECKS=SUPPRESS_ALL
-gnat-p ^ /CHECKS=UNSUPPRESS_ALL
-gnatP ^ /POLLING
diff --git a/gcc/ada/uintp.ads b/gcc/ada/uintp.ads
index 41c6ff570..b730f4487 100644
--- a/gcc/ada/uintp.ads
+++ b/gcc/ada/uintp.ads
@@ -248,9 +248,9 @@ package Uintp is
-- not in Char_Code range.
function Num_Bits (Input : Uint) return Nat;
- -- Approximate number of binary bits in given universal integer.
- -- This function is used for capacity checks, and it can be one
- -- bit off without affecting its usage.
+ -- Approximate number of binary bits in given universal integer. This
+ -- function is used for capacity checks, and it can be one bit off
+ -- without affecting its usage.
---------------------
-- Output Routines --
@@ -258,8 +258,8 @@ package Uintp is
type UI_Format is (Hex, Decimal, Auto);
-- Used to determine whether UI_Image/UI_Write output is in hexadecimal
- -- or decimal format. Auto, the default setting, lets the routine make
- -- a decision based on the value.
+ -- or decimal format. Auto, the default setting, lets the routine make a
+ -- decision based on the value.
UI_Image_Max : constant := 48; -- Enough for a 128-bit number
UI_Image_Buffer : String (1 .. UI_Image_Max);
@@ -271,8 +271,8 @@ package Uintp is
-- followed by the value in UI_Image_Buffer. The form of the value is an
-- integer literal in either decimal (no base) or hexadecimal (base 16)
-- format. If Hex is True on entry, then hex mode is forced, otherwise
- -- UI_Image makes a guess at which output format is more convenient. The
- -- value must fit in UI_Image_Buffer. If necessary, the result is an
+ -- UI_Image makes a guess at which output format is more convenient.
+ -- The value must fit in UI_Image_Buffer. If necessary, the result is an
-- approximation of the proper value, using an exponential format. The
-- image of No_Uint is output as a single question mark.
@@ -280,9 +280,9 @@ package Uintp is
-- Writes a representation of Uint, consisting of a possible minus sign,
-- followed by the value to the output file. The form of the value is an
-- integer literal in either decimal (no base) or hexadecimal (base 16)
- -- format as appropriate. UI_Format shows which format to use. Auto,
- -- the default, asks UI_Write to make a guess at which output format
- -- will be more convenient to read.
+ -- format as appropriate. UI_Format shows which format to use. Auto, the
+ -- default, asks UI_Write to make a guess at which output format will be
+ -- more convenient to read.
procedure pid (Input : Uint);
pragma Export (Ada, pid);
@@ -355,11 +355,11 @@ package Uintp is
-- Mark/Release Processing --
-----------------------------
- -- The space used by Uint data is not automatically reclaimed. However,
- -- a mark-release regime is implemented which allows storage to be
- -- released back to a previously noted mark. This is used for example
- -- when doing comparisons, where only intermediate results get stored
- -- that do not need to be saved for future use.
+ -- The space used by Uint data is not automatically reclaimed. However, a
+ -- mark-release regime is implemented which allows storage to be released
+ -- back to a previously noted mark. This is used for example when doing
+ -- comparisons, where only intermediate results get stored that do not
+ -- need to be saved for future use.
type Save_Mark is private;
@@ -370,18 +370,16 @@ package Uintp is
-- Release storage allocated since mark was noted
procedure Release_And_Save (M : Save_Mark; UI : in out Uint);
- -- Like Release, except that the given Uint value (which is typically
- -- among the data being released) is recopied after the release, so
- -- that it is the most recent item, and UI is updated to point to
- -- its copied location.
+ -- Like Release, except that the given Uint value (which is typically among
+ -- the data being released) is recopied after the release, so that it is
+ -- the most recent item, and UI is updated to point to its copied location.
procedure Release_And_Save (M : Save_Mark; UI1, UI2 : in out Uint);
-- Like Release, except that the given Uint values (which are typically
- -- among the data being released) are recopied after the release, so
- -- that they are the most recent items, and UI1 and UI2 are updated if
- -- necessary to point to the copied locations. This routine is careful
- -- to do things in the right order, so that the values do not clobber
- -- one another.
+ -- among the data being released) are recopied after the release, so that
+ -- they are the most recent items, and UI1 and UI2 are updated if necessary
+ -- to point to the copied locations. This routine is careful to do things
+ -- in the right order, so that the values do not clobber one another.
-----------------------------------
-- Representation of Uint Values --
@@ -499,15 +497,14 @@ private
type UI_Vector is array (Pos range <>) of Int;
-- Vector containing the integer values of a Uint value
- -- Note: An earlier version of this package used pointers of arrays
- -- of Ints (dynamically allocated) for the Uint type. The change
- -- leads to a few less natural idioms used throughout this code, but
- -- eliminates all uses of the heap except for the table package itself.
- -- For example, Uint parameters are often converted to UI_Vectors for
- -- internal manipulation. This is done by creating the local UI_Vector
- -- using the function N_Digits on the Uint to find the size needed for
- -- the vector, and then calling Init_Operand to copy the values out
- -- of the table into the vector.
+ -- Note: An earlier version of this package used pointers of arrays of Ints
+ -- (dynamically allocated) for the Uint type. The change leads to a few
+ -- less natural idioms used throughout this code, but eliminates all uses
+ -- of the heap except for the table package itself. For example, Uint
+ -- parameters are often converted to UI_Vectors for internal manipulation.
+ -- This is done by creating the local UI_Vector using the function N_Digits
+ -- on the Uint to find the size needed for the vector, and then calling
+ -- Init_Operand to copy the values out of the table into the vector.
type Uint_Entry is record
Length : Pos;
diff --git a/gcc/ada/usage.adb b/gcc/ada/usage.adb
index 59a5899a6..2f8580703 100644
--- a/gcc/ada/usage.adb
+++ b/gcc/ada/usage.adb
@@ -167,6 +167,11 @@ begin
Write_Switch_Char ("Dnn");
Write_Line ("Debug expanded generated code (max line length = nn)");
+ -- Line for -gnateA switch
+
+ Write_Switch_Char ("eA");
+ Write_Line ("Aliasing checks on subprogram parameters");
+
-- Line for -gnatec switch
Write_Switch_Char ("ec=?");
@@ -227,6 +232,11 @@ begin
Write_Switch_Char ("eS");
Write_Line ("Generate SCO (Source Coverage Obligation) information");
+ -- Line for -gnateV switch
+
+ Write_Switch_Char ("eV");
+ Write_Line ("Validity checks on subprogram parameters");
+
-- Line for -gnatE switch
Write_Switch_Char ("E");
@@ -309,7 +319,15 @@ begin
-- Line for -gnato switch
Write_Switch_Char ("o");
- Write_Line ("Enable overflow checking (off by default)");
+ Write_Line ("Enable overflow checking mode to CHECKED (off by default)");
+
+ -- Line for -gnato? switch
+
+ Write_Switch_Char ("o?");
+ Write_Line ("Set SUPPRESSED/CHECKED/MINIMIZED/ELIMINATED (?=0/1/2/3) mode");
+
+ Write_Switch_Char ("o??");
+ Write_Line ("Set mode for general/assertion expressions separately");
-- Line for -gnatO switch
diff --git a/gcc/ada/validsw.adb b/gcc/ada/validsw.adb
index 1c7d5cfc6..b37825ed4 100644
--- a/gcc/ada/validsw.adb
+++ b/gcc/ada/validsw.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2007, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2012, 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- --
@@ -174,12 +174,12 @@ package body Validsw is
when 'E' =>
Validity_Check_Components := False;
- when 'I' =>
- Validity_Check_In_Params := False;
-
when 'F' =>
Validity_Check_Floating_Point := False;
+ when 'I' =>
+ Validity_Check_In_Params := False;
+
when 'M' =>
Validity_Check_In_Out_Params := False;
diff --git a/gcc/ada/validsw.ads b/gcc/ada/validsw.ads
index f24bc8782..afc4fa55a 100644
--- a/gcc/ada/validsw.ads
+++ b/gcc/ada/validsw.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 2001-2008, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2012, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
diff --git a/gcc/ada/vms_data.ads b/gcc/ada/vms_data.ads
index 80c6eaf64..c33bb8f71 100644
--- a/gcc/ada/vms_data.ads
+++ b/gcc/ada/vms_data.ads
@@ -1347,12 +1347,13 @@ package VMS_Data is
-- if the /CHECKS qualifier is not present on the
-- command line. Same as /NOCHECKS.
--
- -- OVERFLOW Enables overflow checking for integer operations and
- -- checks for access before elaboration on subprogram
- -- calls. This causes GNAT to generate slower and larger
- -- executable programs by adding code to check for both
- -- overflow and division by zero (resulting in raising
- -- "Constraint_Error" as required by Ada semantics).
+ -- OVERFLOW Enables overflow checking in CHECKED mode for integer
+ -- operations and checks for access before elaboration
+ -- on subprogram calls. This causes GNAT to generate
+ -- slower and larger executable programs by adding code
+ -- to check for both overflow and division by zero
+ -- (resulting in raising "Constraint_Error" as required
+ -- by Ada semantics).
-- Similarly, GNAT does not generate elaboration check
-- by default, and you must specify this keyword to
-- enable them.
@@ -2108,6 +2109,24 @@ package VMS_Data is
-- file xyz.adb is compiled with -gnatl=.lst, then the output is written
-- to file xyz.adb_lst.
+ S_GCC_Overflo : aliased constant S := "/OVERFLOW_CHECKS=#" &
+ "-gnato#";
+ -- /OVERFLOW_CHECKS=nn
+ --
+ -- Set default overflow cheecking mode. If nn is a single digit, in the
+ -- range 0-3, it sets the overflow checking mode for all expressions,
+ -- including those outside and within assertions. The meaning of nnn is:
+ --
+ -- 0 suppress overflow checks (SUPPRESSED)
+ -- 1 all intermediate overflows checked (CHECKED)
+ -- 2 minimize intermediate overflows (MINIMIZED)
+ -- 3 eliminate intermediate overflows (ELIMINATED)
+ --
+ -- Otherwise nn can be two digits, both 0-3, and in this case the first
+ -- digit sets the mode (using the above code) for expressions outside an
+ -- assertion, and the second digit sets the mode for expressions within
+ -- an assertion.
+
S_GCC_Pointer : aliased constant S := "/POINTER_SIZE=" &
"64 " &
"-mmalloc64 " &
@@ -3622,6 +3641,7 @@ package VMS_Data is
S_GCC_NoWarnP 'Access,
S_GCC_Opt 'Access,
S_GCC_OptX 'Access,
+ S_GCC_Overflo 'Access,
S_GCC_Pointer 'Access,
S_GCC_Polling 'Access,
S_GCC_Project 'Access,
diff --git a/gcc/ada/xoscons.adb b/gcc/ada/xoscons.adb
index c740aa253..90d1b2d4d 100644
--- a/gcc/ada/xoscons.adb
+++ b/gcc/ada/xoscons.adb
@@ -387,7 +387,7 @@ procedure XOSCons is
Info.Value_Len := Info.Text_Value'Length;
end if;
- if Info.Constant_Name.all = "sizeof_unsigned_int" then
+ if Info.Constant_Name.all = "SIZEOF_unsigned_int" then
Size_Of_Unsigned_Int :=
8 * Integer (Info.Int_Value.Abs_Value);
end if;
diff --git a/gcc/ada/xsnamest.adb b/gcc/ada/xsnamest.adb
index a3f8ec3ee..a22eec02a 100644
--- a/gcc/ada/xsnamest.adb
+++ b/gcc/ada/xsnamest.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2011, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2012, 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- --
@@ -120,6 +120,10 @@ procedure XSnamesT is
-- Build the definition for the current macro (Names are integers
-- offset to N, while other items are enumeration values).
+ ----------------
+ -- Make_Value --
+ ----------------
+
function Make_Value (V : Integer) return String is
begin
if S = Name then
@@ -129,6 +133,8 @@ procedure XSnamesT is
end if;
end Make_Value;
+ -- Start of processing for Output_Header_Line
+
begin
-- Skip all the #define for S-prefixed symbols in the header.
-- Of course we are making implicit assumptions:
@@ -223,10 +229,11 @@ begin
Output_Header_Line (Prag);
end if;
else
- Oval := Lpad (V (Val), 3, '0');
if Match (Name0, "Last_") then
Oval := Lpad (V (Val - 1), 3, '0');
+ else
+ Oval := Lpad (V (Val), 3, '0');
end if;
Put_Line
diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index 9eb5e71c9..0c331fb4c 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -127,10 +127,6 @@ DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LIST, ATTR_PURE, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LEAF_LIST, ATTR_PURE, \
ATTR_NULL, ATTR_NOTHROW_LEAF_LIST)
-DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NOVOPS_LIST, ATTR_NOVOPS, \
- ATTR_NULL, ATTR_PURE_NOTHROW_LIST)
-DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NOVOPS_LEAF_LIST, ATTR_NOVOPS,\
- ATTR_NULL, ATTR_PURE_NOTHROW_LEAF_LIST)
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LEAF_LIST, ATTR_NORETURN,\
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 8493ca41b..69000bcfc 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -163,7 +163,7 @@ along with GCC; see the file COPYING3. If not see
memory. */
#undef ATTR_MATHFN_FPROUNDING
#define ATTR_MATHFN_FPROUNDING (flag_rounding_math ? \
- ATTR_PURE_NOTHROW_NOVOPS_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST)
+ ATTR_PURE_NOTHROW_LEAF_LIST : ATTR_CONST_NOTHROW_LEAF_LIST)
/* Define an attribute list for math functions that are normally
"impure" because some of them may write into global memory for
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index c26014ec4..0d112cfe7 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,7 +1,13 @@
+2012-10-04 Arnaud Charlet <charlet@adacore.com>
+
+ * c-ada-spec.c (print_ada_declaration): Remove handling of TDF_RAW.
+ * c.opt (-fdump-ada-spec, -fdump-ada-spec-slim): Move switch definition
+ out of dumpfile.h.
+
2012-09-25 Dehao Chen <dehao@google.com>
PR middle-end/54645
- * c-family/c-pch.c (c_common_read_pch): Rebuild the location_adhoc_data
+ * c-pch.c (c_common_read_pch): Rebuild the location_adhoc_data
map when read in the pch.
2012-09-18 Arnaud Charlet <charlet@adacore.com>
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index e7225162e..4f38a63ad 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -2535,7 +2535,6 @@ print_ada_declaration (pretty_printer *buffer, tree t, tree type,
int is_class = false;
tree name = TYPE_NAME (TREE_TYPE (t));
tree decl_name = DECL_NAME (t);
- bool dump_internal = get_dump_file_info (TDI_ada)->flags & TDF_RAW;
tree orig = NULL_TREE;
if (cpp_check && cpp_check (t, IS_TEMPLATE))
@@ -2705,8 +2704,7 @@ print_ada_declaration (pretty_printer *buffer, tree t, tree type,
}
else
{
- if (!dump_internal
- && TREE_CODE (t) == VAR_DECL
+ if (TREE_CODE (t) == VAR_DECL
&& decl_name
&& *IDENTIFIER_POINTER (decl_name) == '_')
return 0;
@@ -2796,8 +2794,7 @@ print_ada_declaration (pretty_printer *buffer, tree t, tree type,
/* If this function has an entry in the dispatch table, we cannot
omit it. */
- if (!dump_internal && !DECL_VINDEX (t)
- && *IDENTIFIER_POINTER (decl_name) == '_')
+ if (!DECL_VINDEX (t) && *IDENTIFIER_POINTER (decl_name) == '_')
{
if (IDENTIFIER_POINTER (decl_name)[1] == '_')
return 0;
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 9298e3d81..cefe92d9e 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -45,7 +45,6 @@ never after.
/* Usage of TREE_LANG_FLAG_?:
0: IDENTIFIER_MARKED (used by search routines).
- DECL_PRETTY_FUNCTION_P (in VAR_DECL)
C_MAYBE_CONST_EXPR_INT_OPERANDS (in C_MAYBE_CONST_EXPR, for C)
1: C_DECLARED_LABEL_FLAG (in LABEL_DECL)
STATEMENT_LIST_STMT_EXPR (in STATEMENT_LIST)
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 6aa53a577..b02c51532 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -799,6 +799,14 @@ fdollars-in-identifiers
C ObjC C++ ObjC++
Permit '$' as an identifier character
+fdump-ada-spec
+C ObjC C++ ObjC++ RejectNegative Var(flag_dump_ada_spec)
+Write all declarations as Ada code transitively
+
+fdump-ada-spec-slim
+C ObjC C++ ObjC++ RejectNegative Var(flag_dump_ada_spec_slim)
+Write all declarations as Ada code for the given file only
+
felide-constructors
C++ ObjC++ Var(flag_elide_constructors) Init(1)
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 6aed2c3de..257b752cc 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,13 @@
+2012-10-04 Arnaud Charlet <charlet@adacore.com>
+
+ * c-decl.c (c_write_global_declarations): Fix handling of
+ -fdump-ada-spec*.
+
+2012-09-30 Sharad Singhai <singhai@google.com>
+
+ * c-decl.c (c_write_global_declarations): Use a different method
+ to determine if the dump has ben initialized.
+
2012-09-14 Joseph Myers <joseph@codesourcery.com>
PR c/54552
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index d4c7b1f87..a4a8108d2 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -10079,10 +10079,10 @@ c_write_global_declarations (void)
gcc_assert (!current_scope);
/* Handle -fdump-ada-spec[-slim]. */
- if (dump_enabled_p (TDI_ada))
+ if (flag_dump_ada_spec || flag_dump_ada_spec_slim)
{
/* Build a table of files to generate specs for */
- if (get_dump_file_info (TDI_ada)->flags & TDF_SLIM)
+ if (flag_dump_ada_spec_slim)
collect_source_ref (main_input_filename);
else
for_each_global_decl (collect_source_ref_cb);
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 0e9accecf..6e7b7c4fa 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1731,7 +1731,7 @@ cgraph_set_const_flag (struct cgraph_node *node, bool readonly, bool looping)
static bool
cgraph_set_pure_flag_1 (struct cgraph_node *node, void *data)
{
- /* Static pureructors and destructors without a side effect can be
+ /* Static constructors and destructors without a side effect can be
optimized out. */
if (data && !((size_t)data & 2))
{
diff --git a/gcc/common.opt b/gcc/common.opt
index 31b6210f9..6de670b8a 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -141,9 +141,6 @@ bool use_gnu_debug_info_extensions
Variable
unsigned int initial_max_fld_align = TARGET_DEFAULT_PACK_STRUCT
-Variable
-enum vect_verbosity_levels user_vect_verbosity_level = MAX_VERBOSITY_LEVEL
-
; Type of stack check.
Variable
enum stack_check_type flag_stack_check = NO_STACK_CHECK
@@ -1536,6 +1533,14 @@ fomit-frame-pointer
Common Report Var(flag_omit_frame_pointer) Optimization
When possible do not generate stack frames
+fopt-info
+Common Report Var(flag_opt_info) Optimization
+Enable all optimization info dumps on stderr
+
+fopt-info-
+Common Joined RejectNegative Var(common_deferred_options) Defer
+-fopt-info[-<type>=filename] Dump compiler optimization details
+
foptimize-register-move
Common Report Var(flag_regmove) Optimization
Do the full register move optimization pass
@@ -1649,6 +1654,10 @@ fprofile-values
Common Report Var(flag_profile_values)
Insert code to profile values of expressions
+fprofile-report
+Common Report Var(profile_report)
+Report on consistency of profile
+
frandom-seed
Common Var(common_deferred_options) Defer
@@ -2195,6 +2204,10 @@ ftree-vectorize
Common Report Var(flag_tree_vectorize) Optimization
Enable loop vectorization on trees
+ftree-vectorizer-verbose=
+Common RejectNegative Joined UInteger Var(common_deferred_options) Defer
+-ftree-vectorizer-verbose=<number> This switch is deprecated. Use -fopt-info instead.
+
ftree-slp-vectorize
Common Report Var(flag_tree_slp_vectorize) Init(2) Optimization
Enable basic block vectorization (SLP) on trees
@@ -2207,10 +2220,6 @@ ftree-vect-loop-version
Common Report Var(flag_tree_vect_loop_version) Init(1) Optimization
Enable loop versioning when doing loop vectorization on trees
-ftree-vectorizer-verbose=
-Common RejectNegative Joined UInteger
--ftree-vectorizer-verbose=<number> Set the verbosity level of the vectorizer
-
ftree-scev-cprop
Common Report Var(flag_tree_scev_cprop) Init(1) Optimization
Enable copy propagation of scalar-evolution information.
diff --git a/gcc/config.gcc b/gcc/config.gcc
index d5cdfe357..ae2b5e4d6 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -716,6 +716,11 @@ case ${target} in
*-*-openbsd2.*|*-*-openbsd3.[012])
tm_defines="${tm_defines} HAS_LIBC_R=1" ;;
esac
+ case ${target} in
+ *-*-openbsd4.[3-9]|*-*-openbsd[5-9]*)
+ default_use_cxa_atexit=yes
+ ;;
+ esac
;;
*-*-rtems*)
case ${enable_threads} in
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 284860e9e..19424b688 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -395,7 +395,7 @@
;; Secondary input reload from non-generic 16-bit address spaces
(define_insn "reload_in<mode>"
[(set (match_operand:MOVMODE 0 "register_operand" "=r")
- (match_operand:MOVMODE 1 "memory_operand" "m"))
+ (match_operand:MOVMODE 1 "flash_operand" "m"))
(clobber (match_operand:QI 2 "d_register_operand" "=d"))]
;; Fixme: The insn condition must not test the address space.
;; Because the gen tools refuse to generate insns for address spaces
@@ -4167,13 +4167,13 @@
"reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 3) (const_int 0))]
-{
- unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
- unsigned int high_off = subreg_highpart_offset (QImode, HImode);
+ {
+ unsigned int low_off = subreg_lowpart_offset (QImode, HImode);
+ unsigned int high_off = subreg_highpart_offset (QImode, HImode);
- operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
- operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
-})
+ operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, low_off);
+ operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, high_off);
+ })
(define_insn_and_split "zero_extendqipsi2"
[(set (match_operand:PSI 0 "register_operand" "=r")
@@ -4198,13 +4198,13 @@
"reload_completed"
[(set (match_dup 2) (zero_extend:HI (match_dup 1)))
(set (match_dup 3) (const_int 0))]
-{
- unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
- unsigned int high_off = subreg_highpart_offset (HImode, SImode);
+ {
+ unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
+ unsigned int high_off = subreg_highpart_offset (HImode, SImode);
- operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
- operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
-})
+ operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
+ operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
+ })
(define_insn_and_split "zero_extendhipsi2"
[(set (match_operand:PSI 0 "register_operand" "=r")
@@ -4248,13 +4248,13 @@
"reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 3) (const_int 0))]
-{
- unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
- unsigned int high_off = subreg_highpart_offset (HImode, SImode);
+ {
+ unsigned int low_off = subreg_lowpart_offset (HImode, SImode);
+ unsigned int high_off = subreg_highpart_offset (HImode, SImode);
- operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
- operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
-})
+ operands[2] = simplify_gen_subreg (HImode, operands[0], SImode, low_off);
+ operands[3] = simplify_gen_subreg (HImode, operands[0], SImode, high_off);
+ })
(define_insn_and_split "zero_extendpsisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
@@ -4277,13 +4277,13 @@
"reload_completed"
[(set (match_dup 2) (zero_extend:SI (match_dup 1)))
(set (match_dup 3) (const_int 0))]
-{
- unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
- unsigned int high_off = subreg_highpart_offset (SImode, DImode);
+ {
+ unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
+ unsigned int high_off = subreg_highpart_offset (SImode, DImode);
- operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
- operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
-})
+ operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
+ operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
+ })
(define_insn_and_split "zero_extendhidi2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -4293,13 +4293,13 @@
"reload_completed"
[(set (match_dup 2) (zero_extend:SI (match_dup 1)))
(set (match_dup 3) (const_int 0))]
-{
- unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
- unsigned int high_off = subreg_highpart_offset (SImode, DImode);
+ {
+ unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
+ unsigned int high_off = subreg_highpart_offset (SImode, DImode);
- operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
- operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
-})
+ operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
+ operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
+ })
(define_insn_and_split "zero_extendsidi2"
[(set (match_operand:DI 0 "register_operand" "=r")
@@ -4309,13 +4309,13 @@
"reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 3) (const_int 0))]
-{
- unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
- unsigned int high_off = subreg_highpart_offset (SImode, DImode);
+ {
+ unsigned int low_off = subreg_lowpart_offset (SImode, DImode);
+ unsigned int high_off = subreg_highpart_offset (SImode, DImode);
- operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
- operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
-})
+ operands[2] = simplify_gen_subreg (SImode, operands[0], DImode, low_off);
+ operands[3] = simplify_gen_subreg (SImode, operands[0], DImode, high_off);
+ })
;;<=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=><=>
;; compare
diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md
index 04587ae49..fc4ca03de 100644
--- a/gcc/config/avr/predicates.md
+++ b/gcc/config/avr/predicates.md
@@ -72,6 +72,13 @@
(not (match_test "avr_load_libgcc_p (op)"))
(not (match_test "avr_mem_memx_p (op)"))))
+;; Return 1 if OP is a memory operand in one of the __flash* address spaces
+(define_predicate "flash_operand"
+ (and (match_operand 0 "memory_operand")
+ (match_test "Pmode == mode")
+ (ior (match_test "!MEM_P (op)")
+ (match_test "avr_mem_flash_p (op)"))))
+
;; Return 1 if OP is the zero constant for MODE.
(define_predicate "const0_operand"
(and (match_code "const_int,const_fixed,const_double")
diff --git a/gcc/config/darwin-c.c b/gcc/config/darwin-c.c
index a642f66c4..8e48c3057 100644
--- a/gcc/config/darwin-c.c
+++ b/gcc/config/darwin-c.c
@@ -267,7 +267,7 @@ static struct framework_header framework_header_dirs[] = {
static char *
framework_construct_pathname (const char *fname, cpp_dir *dir)
{
- char *buf;
+ const char *buf;
size_t fname_len, frname_len;
cpp_dir *fast_dir;
char *frname;
@@ -344,7 +344,7 @@ find_subframework_file (const char *fname, const char *pname)
{
char *sfrname;
const char *dot_framework = ".framework/";
- char *bufptr;
+ const char *bufptr;
int sfrname_len, i, fname_len;
struct cpp_dir *fast_dir;
static struct cpp_dir subframe_dir;
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index 54c92d16b..5a9f50a9f 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -2623,7 +2623,7 @@ darwin_assemble_visibility (tree decl, int vis)
{
if (vis == VISIBILITY_DEFAULT)
;
- else if (vis == VISIBILITY_HIDDEN)
+ else if (vis == VISIBILITY_HIDDEN || vis == VISIBILITY_INTERNAL)
{
fputs ("\t.private_extern ", asm_out_file);
assemble_name (asm_out_file,
@@ -2631,7 +2631,7 @@ darwin_assemble_visibility (tree decl, int vis)
fputs ("\n", asm_out_file);
}
else
- warning (OPT_Wattributes, "internal and protected visibility attributes "
+ warning (OPT_Wattributes, "protected visibility attribute "
"not supported in this configuration; ignored");
}
diff --git a/gcc/config/h8300/h8300.c b/gcc/config/h8300/h8300.c
index 38a922898..7ec13264a 100644
--- a/gcc/config/h8300/h8300.c
+++ b/gcc/config/h8300/h8300.c
@@ -1,6 +1,6 @@
/* Subroutines for insn-output.c for Renesas H8/300.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by Steve Chamberlain (sac@cygnus.com),
Jim Wilson (wilson@cygnus.com), and Doug Evans (dje@cygnus.com).
@@ -1244,7 +1244,7 @@ h8300_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
*total = 0;
return true;
}
- if (-4 <= n || n <= 4)
+ if (-4 <= n && n <= 4)
{
switch ((int) n)
{
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index bda4e0222..36d80b1e6 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -390,6 +390,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
unsigned int has_hle = 0, has_rtm = 0;
unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0;
unsigned int has_rdseed = 0, has_prfchw = 0, has_adx = 0;
+ unsigned int has_osxsave = 0;
bool arch;
@@ -431,6 +432,7 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_sse4_1 = ecx & bit_SSE4_1;
has_sse4_2 = ecx & bit_SSE4_2;
has_avx = ecx & bit_AVX;
+ has_osxsave = ecx & bit_OSXSAVE;
has_cmpxchg16b = ecx & bit_CMPXCHG16B;
has_movbe = ecx & bit_MOVBE;
has_popcnt = ecx & bit_POPCNT;
@@ -460,6 +462,27 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_adx = ebx & bit_ADX;
}
+ /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */
+#define XCR_XFEATURE_ENABLED_MASK 0x0
+#define XSTATE_FP 0x1
+#define XSTATE_SSE 0x2
+#define XSTATE_YMM 0x4
+ if (has_osxsave)
+ asm (".byte 0x0f; .byte 0x01; .byte 0xd0"
+ : "=a" (eax), "=d" (edx)
+ : "c" (XCR_XFEATURE_ENABLED_MASK));
+
+ /* Check if SSE and YMM states are supported. */
+ if (!has_osxsave
+ || (eax & (XSTATE_SSE | XSTATE_YMM)) != (XSTATE_SSE | XSTATE_YMM))
+ {
+ has_avx = 0;
+ has_avx2 = 0;
+ has_fma = 0;
+ has_fma4 = 0;
+ has_xop = 0;
+ }
+
/* Check cpuid level of extended features. */
__cpuid (0x80000000, ext_level, ebx, ecx, edx);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index de9c68718..c10e49458 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -17520,9 +17520,16 @@ ix86_dep_by_shift_count_body (const_rtx set_body, const_rtx use_body)
rtx shift_count = XEXP (shift_rtx, 1);
/* Return true if shift count is dest of SET_BODY. */
- if (REG_P (shift_count)
- && true_regnum (set_dest) == true_regnum (shift_count))
- return true;
+ if (REG_P (shift_count))
+ {
+ /* Add check since it can be invoked before register
+ allocation in pre-reload schedule. */
+ if (reload_completed
+ && true_regnum (set_dest) == true_regnum (shift_count))
+ return true;
+ else if (REGNO(set_dest) == REGNO(shift_count))
+ return true;
+ }
}
return false;
@@ -24278,7 +24285,10 @@ ia32_multipass_dfa_lookahead (void)
/* Generally, we want haifa-sched:max_issue() to look ahead as far
as many instructions can be executed on a cycle, i.e.,
issue_rate. I wonder why tuning for many CPUs does not do this. */
- return ix86_issue_rate ();
+ if (reload_completed)
+ return ix86_issue_rate ();
+ /* Don't use lookahead for pre-reload schedule to save compile time. */
+ return 0;
default:
return 0;
@@ -24311,6 +24321,9 @@ ix86_sched_reorder(FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
/* Do reodering for Atom only. */
if (ix86_tune != PROCESSOR_ATOM)
return issue_rate;
+ /* Do not perform ready list reodering for pre-reload schedule pass. */
+ if (!reload_completed)
+ return issue_rate;
/* Nothing to do if ready list contains only 1 instruction. */
if (n_ready <= 1)
return issue_rate;
@@ -24393,7 +24406,198 @@ ix86_sched_reorder(FILE *dump, int sched_verbose, rtx *ready, int *pn_ready,
return issue_rate;
}
-
+static bool
+ix86_class_likely_spilled_p (reg_class_t);
+
+/* Returns true if lhs of insn is HW function argument register and set up
+ is_spilled to true if it is likely spilled HW register. */
+static bool
+insn_is_function_arg (rtx insn, bool* is_spilled)
+{
+ rtx dst;
+
+ if (!NONDEBUG_INSN_P (insn))
+ return false;
+ insn = PATTERN (insn);
+ if (GET_CODE (insn) == PARALLEL)
+ insn = XVECEXP (insn, 0, 0);
+ if (GET_CODE (insn) != SET)
+ return false;
+ dst = SET_DEST (insn);
+ if (REG_P (dst) && HARD_REGISTER_P (dst)
+ && ix86_function_arg_regno_p (REGNO (dst)))
+ {
+ /* Is it likely spilled HW register? */
+ if (!TEST_HARD_REG_BIT (fixed_reg_set, REGNO (dst))
+ && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dst))))
+ *is_spilled = true;
+ return true;
+ }
+ return false;
+}
+
+/* Add output dependencies for chain of function adjacent arguments if only
+ there is a move to likely spilled HW register. Return first argument
+ if at least one dependence was added or NULL otherwise. */
+static rtx
+add_parameter_dependencies (rtx call, rtx head)
+{
+ rtx insn;
+ rtx last = call;
+ rtx first_arg = NULL;
+ bool is_spilled = false;
+
+ /* Find nearest to call argument passing instruction. */
+ while (true)
+ {
+ last = PREV_INSN (last);
+ if (last == head)
+ return NULL;
+ if (!NONDEBUG_INSN_P (last))
+ continue;
+ if (insn_is_function_arg (last, &is_spilled))
+ break;
+ return NULL;
+ }
+
+ first_arg = last;
+ while (true)
+ {
+ insn = PREV_INSN (last);
+ if (!INSN_P (insn))
+ break;
+ if (insn == head)
+ break;
+ if (!NONDEBUG_INSN_P (insn))
+ {
+ last = insn;
+ continue;
+ }
+ if (insn_is_function_arg (insn, &is_spilled))
+ {
+ /* Add output depdendence between two function arguments if chain
+ of output arguments contains likely spilled HW registers. */
+ if (is_spilled)
+ add_dependence (last, insn, REG_DEP_OUTPUT);
+ first_arg = last = insn;
+ }
+ else
+ break;
+ }
+ if (!is_spilled)
+ return NULL;
+ return first_arg;
+}
+
+/* Add output or anti dependency from insn to first_arg to restrict its code
+ motion. */
+static void
+avoid_func_arg_motion (rtx first_arg, rtx insn)
+{
+ rtx set;
+ rtx tmp;
+
+ set = single_set (insn);
+ if (!set)
+ return;
+ tmp = SET_DEST (set);
+ if (REG_P (tmp))
+ {
+ /* Add output dependency to the first function argument. */
+ add_dependence (first_arg, insn, REG_DEP_OUTPUT);
+ return;
+ }
+ /* Add anti dependency. */
+ add_dependence (first_arg, insn, REG_DEP_ANTI);
+}
+
+/* Avoid cross block motion of function argument through adding dependency
+ from the first non-jump instruction in bb. */
+static void
+add_dependee_for_func_arg (rtx arg, basic_block bb)
+{
+ rtx insn = BB_END (bb);
+
+ while (insn)
+ {
+ if (NONDEBUG_INSN_P (insn) && NONJUMP_INSN_P (insn))
+ {
+ rtx set = single_set (insn);
+ if (set)
+ {
+ avoid_func_arg_motion (arg, insn);
+ return;
+ }
+ }
+ if (insn == BB_HEAD (bb))
+ return;
+ insn = PREV_INSN (insn);
+ }
+}
+
+/* Hook for pre-reload schedule - avoid motion of function arguments
+ passed in likely spilled HW registers. */
+static void
+ix86_dependencies_evaluation_hook (rtx head, rtx tail)
+{
+ rtx insn;
+ rtx first_arg = NULL;
+ if (reload_completed)
+ return;
+ for (insn = tail; insn != head; insn = PREV_INSN (insn))
+ if (INSN_P (insn) && CALL_P (insn))
+ {
+ first_arg = add_parameter_dependencies (insn, head);
+ if (first_arg)
+ {
+ /* Check if first argument has dependee out of its home block. */
+ sd_iterator_def sd_it1;
+ dep_t dep1;
+ FOR_EACH_DEP (first_arg, SD_LIST_BACK, sd_it1, dep1)
+ {
+ rtx dee;
+ dee = DEP_PRO (dep1);
+ if (!NONDEBUG_INSN_P (dee))
+ continue;
+ if (BLOCK_FOR_INSN (dee) != BLOCK_FOR_INSN (first_arg))
+ /* Must add dependee for first argument in dee's block. */
+ add_dependee_for_func_arg (first_arg, BLOCK_FOR_INSN (dee));
+ }
+ insn = first_arg;
+ }
+ }
+ else if (first_arg)
+ avoid_func_arg_motion (first_arg, insn);
+}
+
+/* Hook for pre-reload schedule - set priority of moves from likely spilled
+ HW registers to maximum, to schedule them at soon as possible. These are
+ moves from function argument registers at the top of the function entry
+ and moves from function return value registers after call. */
+static int
+ix86_adjust_priority (rtx insn, int priority)
+{
+ rtx set;
+
+ if (reload_completed)
+ return priority;
+
+ if (!NONDEBUG_INSN_P (insn))
+ return priority;
+
+ set = single_set (insn);
+ if (set)
+ {
+ rtx tmp = SET_SRC (set);
+ if (REG_P (tmp)
+ && HARD_REGISTER_P (tmp)
+ && !TEST_HARD_REG_BIT (fixed_reg_set, REGNO (tmp))
+ && ix86_class_likely_spilled_p (REGNO_REG_CLASS (REGNO (tmp))))
+ return current_sched_info->sched_max_insns_priority;
+ }
+
+ return priority;
+}
/* Model decoder of Core 2/i7.
Below hooks for multipass scheduling (see haifa-sched.c:max_issue)
@@ -24606,27 +24810,32 @@ ix86_sched_init_global (FILE *dump ATTRIBUTE_UNUSED,
case PROCESSOR_CORE2_64:
case PROCESSOR_COREI7_32:
case PROCESSOR_COREI7_64:
- targetm.sched.dfa_post_advance_cycle
- = core2i7_dfa_post_advance_cycle;
- targetm.sched.first_cycle_multipass_init
- = core2i7_first_cycle_multipass_init;
- targetm.sched.first_cycle_multipass_begin
- = core2i7_first_cycle_multipass_begin;
- targetm.sched.first_cycle_multipass_issue
- = core2i7_first_cycle_multipass_issue;
- targetm.sched.first_cycle_multipass_backtrack
- = core2i7_first_cycle_multipass_backtrack;
- targetm.sched.first_cycle_multipass_end
- = core2i7_first_cycle_multipass_end;
- targetm.sched.first_cycle_multipass_fini
- = core2i7_first_cycle_multipass_fini;
-
- /* Set decoder parameters. */
- core2i7_secondary_decoder_max_insn_size = 8;
- core2i7_ifetch_block_size = 16;
- core2i7_ifetch_block_max_insns = 6;
- break;
-
+ /* Do not perform multipass scheduling for pre-reload schedule
+ to save compile time. */
+ if (reload_completed)
+ {
+ targetm.sched.dfa_post_advance_cycle
+ = core2i7_dfa_post_advance_cycle;
+ targetm.sched.first_cycle_multipass_init
+ = core2i7_first_cycle_multipass_init;
+ targetm.sched.first_cycle_multipass_begin
+ = core2i7_first_cycle_multipass_begin;
+ targetm.sched.first_cycle_multipass_issue
+ = core2i7_first_cycle_multipass_issue;
+ targetm.sched.first_cycle_multipass_backtrack
+ = core2i7_first_cycle_multipass_backtrack;
+ targetm.sched.first_cycle_multipass_end
+ = core2i7_first_cycle_multipass_end;
+ targetm.sched.first_cycle_multipass_fini
+ = core2i7_first_cycle_multipass_fini;
+
+ /* Set decoder parameters. */
+ core2i7_secondary_decoder_max_insn_size = 8;
+ core2i7_ifetch_block_size = 16;
+ core2i7_ifetch_block_max_insns = 6;
+ break;
+ }
+ /* ... Fall through ... */
default:
targetm.sched.dfa_post_advance_cycle = NULL;
targetm.sched.first_cycle_multipass_init = NULL;
@@ -39687,6 +39896,10 @@ ix86_enum_va_list (int idx, const char **pname, tree *ptree)
#define TARGET_SCHED_REASSOCIATION_WIDTH ix86_reassociation_width
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER ix86_sched_reorder
+#undef TARGET_SCHED_ADJUST_PRIORITY
+#define TARGET_SCHED_ADJUST_PRIORITY ix86_adjust_priority
+#undef TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK
+#define TARGET_SCHED_DEPENDENCIES_EVALUATION_HOOK ix86_dependencies_evaluation_hook
/* The size of the dispatch window is the total number of bytes of
object code allowed in a window. */
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 31be33ede..5f67831a8 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -3597,72 +3597,6 @@
;; logical-and instructions
-;; "anddi3" is mainly here to help combine().
-(define_insn "anddi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
- (and:DI (match_operand:DI 1 "general_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "dn,don")))]
- "!TARGET_COLDFIRE"
-{
- CC_STATUS_INIT;
- /* We can get CONST_DOUBLE, but also const1_rtx etc. */
- if (CONSTANT_P (operands[2]))
- {
- rtx hi, lo;
-
- split_double (operands[2], &hi, &lo);
-
- switch (INTVAL (hi))
- {
- case 0 :
- output_asm_insn ("clr%.l %0", operands);
- break;
- case -1 :
- break;
- default :
- {
- rtx xoperands[3];
-
- xoperands[0] = operands[0];
- xoperands[2] = hi;
- output_asm_insn (output_andsi3 (xoperands), xoperands);
- }
- }
- if (GET_CODE (operands[0]) == REG)
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- else
- operands[0] = adjust_address (operands[0], SImode, 4);
- switch (INTVAL (lo))
- {
- case 0 :
- output_asm_insn ("clr%.l %0", operands);
- break;
- case -1 :
- break;
- default :
- {
- rtx xoperands[3];
-
- xoperands[0] = operands[0];
- xoperands[2] = lo;
- output_asm_insn (output_andsi3 (xoperands), xoperands);
- }
- }
- return "";
- }
- if (GET_CODE (operands[0]) != REG)
- {
- operands[1] = adjust_address (operands[0], SImode, 4);
- return "and%.l %2,%0\;and%.l %R2,%1";
- }
- if (GET_CODE (operands[2]) != REG)
- {
- operands[1] = adjust_address (operands[2], SImode, 4);
- return "and%.l %2,%0\;and%.l %1,%R0";
- }
- return "and%.l %2,%0\;and%.l %R2,%R0";
-})
-
;; Prevent AND from being made with sp. This doesn't exist in the machine
;; and reload will cause inefficient code. Since sp is a FIXED_REG, we
;; can't allocate pseudos into it.
@@ -3780,76 +3714,6 @@
return "or%.w %1,%0";
})
-;; "iordi3" is mainly here to help combine().
-(define_insn "iordi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=o,d")
- (ior:DI (match_operand:DI 1 "general_operand" "%0,0")
- (match_operand:DI 2 "general_operand" "dn,don")))]
- "!TARGET_COLDFIRE"
-{
- CC_STATUS_INIT;
- /* We can get CONST_DOUBLE, but also const1_rtx etc. */
- if (CONSTANT_P (operands[2]))
- {
- rtx hi, lo;
-
- split_double (operands[2], &hi, &lo);
-
- switch (INTVAL (hi))
- {
- case 0 :
- break;
- case -1 :
- /* FIXME : a scratch register would be welcome here if operand[0]
- is not a register */
- output_asm_insn ("move%.l #-1,%0", operands);
- break;
- default :
- {
- rtx xoperands[3];
-
- xoperands[0] = operands[0];
- xoperands[2] = hi;
- output_asm_insn (output_iorsi3 (xoperands), xoperands);
- }
- }
- if (GET_CODE (operands[0]) == REG)
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- else
- operands[0] = adjust_address (operands[0], SImode, 4);
- switch (INTVAL (lo))
- {
- case 0 :
- break;
- case -1 :
- /* FIXME : a scratch register would be welcome here if operand[0]
- is not a register */
- output_asm_insn ("move%.l #-1,%0", operands);
- break;
- default :
- {
- rtx xoperands[3];
-
- xoperands[0] = operands[0];
- xoperands[2] = lo;
- output_asm_insn (output_iorsi3 (xoperands), xoperands);
- }
- }
- return "";
- }
- if (GET_CODE (operands[0]) != REG)
- {
- operands[1] = adjust_address (operands[0], SImode, 4);
- return "or%.l %2,%0\;or%.l %R2,%1";
- }
- if (GET_CODE (operands[2]) != REG)
- {
- operands[1] = adjust_address (operands[2], SImode, 4);
- return "or%.l %2,%0\;or%.l %1,%R0";
- }
- return "or%.l %2,%0\;or%.l %R2,%R0";
-})
-
(define_expand "iorsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(ior:SI (match_operand:SI 1 "general_operand" "")
@@ -3957,79 +3821,6 @@
;; xor instructions
-;; "xordi3" is mainly here to help combine().
-(define_insn "xordi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=od")
- (xor:DI (match_operand:DI 1 "general_operand" "%0")
- (match_operand:DI 2 "general_operand" "dn")))]
- "!TARGET_COLDFIRE"
-{
- CC_STATUS_INIT;
- /* We can get CONST_DOUBLE, but also const1_rtx etc. */
-
- if (CONSTANT_P (operands[2]))
- {
- rtx hi, lo;
-
- split_double (operands[2], &hi, &lo);
-
- switch (INTVAL (hi))
- {
- case 0 :
- break;
- case -1 :
- output_asm_insn ("not%.l %0", operands);
- break;
- default :
- /* FIXME : a scratch register would be welcome here if
- -128 <= INTVAL (hi) < -1 */
- {
- rtx xoperands[3];
-
- xoperands[0] = operands[0];
- xoperands[2] = hi;
- output_asm_insn (output_xorsi3 (xoperands), xoperands);
- }
- }
- if (GET_CODE (operands[0]) == REG)
- operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- else
- operands[0] = adjust_address (operands[0], SImode, 4);
- switch (INTVAL (lo))
- {
- case 0 :
- break;
- case -1 :
- output_asm_insn ("not%.l %0", operands);
- break;
- default :
- /* FIXME : a scratch register would be welcome here if
- -128 <= INTVAL (lo) < -1 */
- operands[2] = lo;
- /* FIXME : this should be merged with xorsi3 */
- {
- rtx xoperands[3];
-
- xoperands[0] = operands[0];
- xoperands[2] = lo;
- output_asm_insn (output_xorsi3 (xoperands), xoperands);
- }
- }
- return "";
- }
- if (GET_CODE (operands[0]) != REG)
- {
- operands[1] = adjust_address (operands[0], SImode, 4);
- return "eor%.l %2,%0\;eor%.l %R2,%1";
- }
- if (GET_CODE (operands[2]) != REG)
- {
- operands[1] = adjust_address (operands[2], SImode, 4);
- return "eor%.l %2,%0\;eor%.l %1,%R0";
- }
- return "eor%.l %2,%0\;eor%.l %R2,%R0";
-})
-
(define_expand "xorsi3"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(xor:SI (match_operand:SI 1 "general_operand" "")
@@ -4498,23 +4289,6 @@
;; one complement instructions
-;; "one_cmpldi2" is mainly here to help combine().
-(define_insn "one_cmpldi2"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=dm")
- (not:DI (match_operand:DI 1 "general_operand" "0")))]
- "!TARGET_COLDFIRE"
-{
- CC_STATUS_INIT;
- if (GET_CODE (operands[0]) == REG)
- operands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC
- || GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
- operands[1] = operands[0];
- else
- operands[1] = adjust_address (operands[0], SImode, 4);
- return "not%.l %1\;not%.l %0";
-})
-
(define_expand "one_cmplsi2"
[(set (match_operand:SI 0 "nonimmediate_operand" "")
(not:SI (match_operand:SI 1 "general_operand" "")))]
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 2584bc76c..708d6bb94 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -173,6 +173,25 @@ enum mips_call_type {
MIPS_CALL_EPILOGUE
};
+/* Controls the conditions under which certain instructions are split.
+
+ SPLIT_IF_NECESSARY
+ Only perform splits that are necessary for correctness
+ (because no unsplit version exists).
+
+ SPLIT_FOR_SPEED
+ Perform splits that are necessary for correctness or
+ beneficial for code speed.
+
+ SPLIT_FOR_SIZE
+ Perform splits that are necessary for correctness or
+ beneficial for code size. */
+enum mips_split_type {
+ SPLIT_IF_NECESSARY,
+ SPLIT_FOR_SPEED,
+ SPLIT_FOR_SIZE
+};
+
extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_context,
enum mips_symbol_type *);
extern int mips_regno_mode_ok_for_base_p (int, enum machine_mode, bool);
@@ -212,8 +231,10 @@ extern int m16_simm8_8 (rtx, enum machine_mode);
extern int m16_nsimm8_8 (rtx, enum machine_mode);
extern rtx mips_subword (rtx, bool);
-extern bool mips_split_64bit_move_p (rtx, rtx);
-extern void mips_split_doubleword_move (rtx, rtx);
+extern bool mips_split_move_p (rtx, rtx, enum mips_split_type);
+extern void mips_split_move (rtx, rtx, enum mips_split_type);
+extern bool mips_split_move_insn_p (rtx, rtx, rtx);
+extern void mips_split_move_insn (rtx, rtx, rtx);
extern const char *mips_output_move (rtx, rtx);
extern bool mips_cfun_has_cprestore_slot_p (void);
extern bool mips_cprestore_address_p (rtx, bool);
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index d37a2f432..4073a15d0 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -265,6 +265,24 @@ static const char *const mips_fp_conditions[] = {
MIPS_FP_CONDITIONS (STRINGIFY)
};
+/* Tuning information that is automatically derived from other sources
+ (such as the scheduler). */
+static struct {
+ /* The architecture and tuning settings that this structure describes. */
+ enum processor arch;
+ enum processor tune;
+
+ /* True if this structure describes MIPS16 settings. */
+ bool mips16_p;
+
+ /* True if the structure has been initialized. */
+ bool initialized_p;
+
+ /* True if "MULT $0, $0" is preferable to "MTLO $0; MTHI $0"
+ when optimizing for speed. */
+ bool fast_mult_zero_zero_p;
+} mips_tuning_info;
+
/* Information about a function's frame layout. */
struct GTY(()) mips_frame_info {
/* The size of the frame in bytes. */
@@ -2395,11 +2413,11 @@ mips_load_store_insns (rtx mem, rtx insn)
mode = GET_MODE (mem);
/* Try to prove that INSN does not need to be split. */
- might_split_p = true;
- if (GET_MODE_BITSIZE (mode) == 64)
+ might_split_p = GET_MODE_SIZE (mode) > UNITS_PER_WORD;
+ if (might_split_p)
{
set = single_set (insn);
- if (set && !mips_split_64bit_move_p (SET_DEST (set), SET_SRC (set)))
+ if (set && !mips_split_move_insn_p (SET_DEST (set), SET_SRC (set), insn))
might_split_p = false;
}
@@ -2441,6 +2459,18 @@ mips_emit_move (rtx dest, rtx src)
: emit_move_insn_1 (dest, src));
}
+/* Emit a move from SRC to DEST, splitting compound moves into individual
+ instructions. SPLIT_TYPE is the type of split to perform. */
+
+static void
+mips_emit_move_or_split (rtx dest, rtx src, enum mips_split_type split_type)
+{
+ if (mips_split_move_p (dest, src, split_type))
+ mips_split_move (dest, src, split_type);
+ else
+ mips_emit_move (dest, src);
+}
+
/* Emit an instruction of the form (set TARGET (CODE OP0)). */
static void
@@ -3527,6 +3557,17 @@ mips_set_reg_reg_cost (enum machine_mode mode)
}
}
+/* Return the cost of an operand X that can be trucated for free.
+ SPEED says whether we're optimizing for size or speed. */
+
+static int
+mips_truncated_op_cost (rtx x, bool speed)
+{
+ if (GET_CODE (x) == TRUNCATE)
+ x = XEXP (x, 0);
+ return set_src_cost (x, speed);
+}
+
/* Implement TARGET_RTX_COSTS. */
static bool
@@ -3907,12 +3948,13 @@ mips_rtx_costs (rtx x, int code, int outer_code, int opno ATTRIBUTE_UNUSED,
case ZERO_EXTEND:
if (outer_code == SET
&& ISA_HAS_BADDU
- && (GET_CODE (XEXP (x, 0)) == TRUNCATE
- || GET_CODE (XEXP (x, 0)) == SUBREG)
&& GET_MODE (XEXP (x, 0)) == QImode
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == PLUS)
+ && GET_CODE (XEXP (x, 0)) == PLUS)
{
- *total = set_src_cost (XEXP (XEXP (x, 0), 0), speed);
+ rtx plus = XEXP (x, 0);
+ *total = (COSTS_N_INSNS (1)
+ + mips_truncated_op_cost (XEXP (plus, 0), speed)
+ + mips_truncated_op_cost (XEXP (plus, 1), speed));
return true;
}
*total = mips_zero_extend_cost (mode, XEXP (x, 0));
@@ -4107,39 +4149,60 @@ mips_subword (rtx op, bool high_p)
return simplify_gen_subreg (word_mode, op, mode, byte);
}
-/* Return true if a 64-bit move from SRC to DEST should be split into two. */
+/* Return true if SRC should be moved into DEST using "MULT $0, $0".
+ SPLIT_TYPE is the condition under which moves should be split. */
+
+static bool
+mips_mult_move_p (rtx dest, rtx src, enum mips_split_type split_type)
+{
+ return ((split_type != SPLIT_FOR_SPEED
+ || mips_tuning_info.fast_mult_zero_zero_p)
+ && src == const0_rtx
+ && REG_P (dest)
+ && GET_MODE_SIZE (GET_MODE (dest)) == 2 * UNITS_PER_WORD
+ && (ISA_HAS_DSP_MULT
+ ? ACC_REG_P (REGNO (dest))
+ : MD_REG_P (REGNO (dest))));
+}
+
+/* Return true if a move from SRC to DEST should be split into two.
+ SPLIT_TYPE describes the split condition. */
bool
-mips_split_64bit_move_p (rtx dest, rtx src)
+mips_split_move_p (rtx dest, rtx src, enum mips_split_type split_type)
{
- if (TARGET_64BIT)
+ /* Check whether the move can be done using some variant of MULT $0,$0. */
+ if (mips_mult_move_p (dest, src, split_type))
return false;
/* FPR-to-FPR moves can be done in a single instruction, if they're
allowed at all. */
- if (FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
+ unsigned int size = GET_MODE_SIZE (GET_MODE (dest));
+ if (size == 8 && FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
return false;
/* Check for floating-point loads and stores. */
- if (ISA_HAS_LDC1_SDC1)
+ if (size == 8 && ISA_HAS_LDC1_SDC1)
{
if (FP_REG_RTX_P (dest) && MEM_P (src))
return false;
if (FP_REG_RTX_P (src) && MEM_P (dest))
return false;
}
- return true;
+
+ /* Otherwise split all multiword moves. */
+ return size > UNITS_PER_WORD;
}
-/* Split a doubleword move from SRC to DEST. On 32-bit targets,
- this function handles 64-bit moves for which mips_split_64bit_move_p
- holds. For 64-bit targets, this function handles 128-bit moves. */
+/* Split a move from SRC to DEST, given that mips_split_move_p holds.
+ SPLIT_TYPE describes the split condition. */
void
-mips_split_doubleword_move (rtx dest, rtx src)
+mips_split_move (rtx dest, rtx src, enum mips_split_type split_type)
{
rtx low_dest;
+ gcc_checking_assert (mips_split_move_p (dest, src, split_type));
if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src))
{
if (!TARGET_64BIT && GET_MODE (dest) == DImode)
@@ -4194,6 +4257,41 @@ mips_split_doubleword_move (rtx dest, rtx src)
}
}
}
+
+/* Return the split type for instruction INSN. */
+
+static enum mips_split_type
+mips_insn_split_type (rtx insn)
+{
+ basic_block bb = BLOCK_FOR_INSN (insn);
+ if (bb)
+ {
+ if (optimize_bb_for_speed_p (bb))
+ return SPLIT_FOR_SPEED;
+ else
+ return SPLIT_FOR_SIZE;
+ }
+ /* Once CFG information has been removed, we should trust the optimization
+ decisions made by previous passes and only split where necessary. */
+ return SPLIT_IF_NECESSARY;
+}
+
+/* Return true if a move from SRC to DEST in INSN should be split. */
+
+bool
+mips_split_move_insn_p (rtx dest, rtx src, rtx insn)
+{
+ return mips_split_move_p (dest, src, mips_insn_split_type (insn));
+}
+
+/* Split a move from SRC to DEST in INSN, given that mips_split_move_insn_p
+ holds. */
+
+void
+mips_split_move_insn (rtx dest, rtx src, rtx insn)
+{
+ mips_split_move (dest, src, mips_insn_split_type (insn));
+}
/* Return the appropriate instructions to move SRC into DEST. Assume
that SRC is operand 1 and DEST is operand 0. */
@@ -4211,7 +4309,7 @@ mips_output_move (rtx dest, rtx src)
mode = GET_MODE (dest);
dbl_p = (GET_MODE_SIZE (mode) == 8);
- if (dbl_p && mips_split_64bit_move_p (dest, src))
+ if (mips_split_move_p (dest, src, SPLIT_IF_NECESSARY))
return "#";
if ((src_code == REG && GP_REG_P (REGNO (src)))
@@ -4222,6 +4320,14 @@ mips_output_move (rtx dest, rtx src)
if (GP_REG_P (REGNO (dest)))
return "move\t%0,%z1";
+ if (mips_mult_move_p (dest, src, SPLIT_IF_NECESSARY))
+ {
+ if (ISA_HAS_DSP_MULT)
+ return "mult\t%q0,%.,%.";
+ else
+ return "mult\t%.,%.";
+ }
+
/* Moves to HI are handled by special .md insns. */
if (REGNO (dest) == LO_REGNUM)
return "mtlo\t%z1";
@@ -10432,10 +10538,7 @@ mips_save_reg (rtx reg, rtx mem)
{
rtx x1, x2;
- if (mips_split_64bit_move_p (mem, reg))
- mips_split_doubleword_move (mem, reg);
- else
- mips_emit_move (mem, reg);
+ mips_emit_move_or_split (mem, reg, SPLIT_IF_NECESSARY);
x1 = mips_frame_set (mips_subword (mem, false),
mips_subword (reg, false));
@@ -14895,10 +14998,15 @@ struct mips_sim {
static void
mips_sim_reset (struct mips_sim *state)
{
+ curr_state = state->dfa_state;
+
state->time = 0;
state->insns_left = state->issue_rate;
memset (&state->last_set, 0, sizeof (state->last_set));
- state_reset (state->dfa_state);
+ state_reset (curr_state);
+
+ targetm.sched.init (0, false, 0);
+ advance_state (curr_state);
}
/* Initialize STATE before its first use. DFA_STATE points to an
@@ -14907,6 +15015,12 @@ mips_sim_reset (struct mips_sim *state)
static void
mips_sim_init (struct mips_sim *state, state_t dfa_state)
{
+ if (targetm.sched.init_dfa_pre_cycle_insn)
+ targetm.sched.init_dfa_pre_cycle_insn ();
+
+ if (targetm.sched.init_dfa_post_cycle_insn)
+ targetm.sched.init_dfa_post_cycle_insn ();
+
state->issue_rate = mips_issue_rate ();
state->dfa_state = dfa_state;
mips_sim_reset (state);
@@ -14917,9 +15031,11 @@ mips_sim_init (struct mips_sim *state, state_t dfa_state)
static void
mips_sim_next_cycle (struct mips_sim *state)
{
+ curr_state = state->dfa_state;
+
state->time++;
state->insns_left = state->issue_rate;
- state_transition (state->dfa_state, 0);
+ advance_state (curr_state);
}
/* Advance simulation state STATE until instruction INSN can read
@@ -15025,8 +15141,11 @@ mips_sim_record_set (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
static void
mips_sim_issue_insn (struct mips_sim *state, rtx insn)
{
- state_transition (state->dfa_state, insn);
- state->insns_left--;
+ curr_state = state->dfa_state;
+
+ state_transition (curr_state, insn);
+ state->insns_left = targetm.sched.variable_issue (0, false, insn,
+ state->insns_left);
mips_sim_insn = insn;
note_stores (PATTERN (insn), mips_sim_record_set, state);
@@ -15077,6 +15196,109 @@ mips_sim_finish_insn (struct mips_sim *state, rtx insn)
break;
}
}
+
+/* Use simulator state STATE to calculate the execution time of
+ instruction sequence SEQ. */
+
+static unsigned int
+mips_seq_time (struct mips_sim *state, rtx seq)
+{
+ mips_sim_reset (state);
+ for (rtx insn = seq; insn; insn = NEXT_INSN (insn))
+ {
+ mips_sim_wait_insn (state, insn);
+ mips_sim_issue_insn (state, insn);
+ }
+ return state->time;
+}
+
+/* Return the execution-time cost of mips_tuning_info.fast_mult_zero_zero_p
+ setting SETTING, using STATE to simulate instruction sequences. */
+
+static unsigned int
+mips_mult_zero_zero_cost (struct mips_sim *state, bool setting)
+{
+ mips_tuning_info.fast_mult_zero_zero_p = setting;
+ start_sequence ();
+
+ enum machine_mode dword_mode = TARGET_64BIT ? TImode : DImode;
+ rtx hilo = gen_rtx_REG (dword_mode, MD_REG_FIRST);
+ mips_emit_move_or_split (hilo, const0_rtx, SPLIT_FOR_SPEED);
+
+ /* If the target provides mulsidi3_32bit then that's the most likely
+ consumer of the result. Test for bypasses. */
+ if (dword_mode == DImode && HAVE_maddsidi4)
+ {
+ rtx gpr = gen_rtx_REG (SImode, GP_REG_FIRST + 4);
+ emit_insn (gen_maddsidi4 (hilo, gpr, gpr, hilo));
+ }
+
+ unsigned int time = mips_seq_time (state, get_insns ());
+ end_sequence ();
+ return time;
+}
+
+/* Check the relative speeds of "MULT $0,$0" and "MTLO $0; MTHI $0"
+ and set up mips_tuning_info.fast_mult_zero_zero_p accordingly.
+ Prefer MULT -- which is shorter -- in the event of a tie. */
+
+static void
+mips_set_fast_mult_zero_zero_p (struct mips_sim *state)
+{
+ if (TARGET_MIPS16)
+ /* No MTLO or MTHI available. */
+ mips_tuning_info.fast_mult_zero_zero_p = true;
+ else
+ {
+ unsigned int true_time = mips_mult_zero_zero_cost (state, true);
+ unsigned int false_time = mips_mult_zero_zero_cost (state, false);
+ mips_tuning_info.fast_mult_zero_zero_p = (true_time <= false_time);
+ }
+}
+
+/* Set up costs based on the current architecture and tuning settings. */
+
+static void
+mips_set_tuning_info (void)
+{
+ if (mips_tuning_info.initialized_p
+ && mips_tuning_info.arch == mips_arch
+ && mips_tuning_info.tune == mips_tune
+ && mips_tuning_info.mips16_p == TARGET_MIPS16)
+ return;
+
+ mips_tuning_info.arch = mips_arch;
+ mips_tuning_info.tune = mips_tune;
+ mips_tuning_info.mips16_p = TARGET_MIPS16;
+ mips_tuning_info.initialized_p = true;
+
+ dfa_start ();
+
+ struct mips_sim state;
+ mips_sim_init (&state, alloca (state_size ()));
+
+ mips_set_fast_mult_zero_zero_p (&state);
+
+ dfa_finish ();
+}
+
+/* Implement TARGET_EXPAND_TO_RTL_HOOK. */
+
+static void
+mips_expand_to_rtl_hook (void)
+{
+ /* We need to call this at a point where we can safely create sequences
+ of instructions, so TARGET_OVERRIDE_OPTIONS is too early. We also
+ need to call it at a point where the DFA infrastructure is not
+ already in use, so we can't just call it lazily on demand.
+
+ At present, mips_tuning_info is only needed during post-expand
+ RTL passes such as split_insns, so this hook should be early enough.
+ We may need to move the call elsewhere if mips_tuning_info starts
+ to be used for other things (such as rtx_costs, or expanders that
+ could be called during gimple optimization). */
+ mips_set_tuning_info ();
+}
/* The VR4130 pipeline issues aligned pairs of instructions together,
but it stalls the second instruction if it depends on the first.
@@ -17748,6 +17970,8 @@ mips_expand_vec_minmax (rtx target, rtx op0, rtx op1,
#undef TARGET_PREFERRED_RELOAD_CLASS
#define TARGET_PREFERRED_RELOAD_CLASS mips_preferred_reload_class
+#undef TARGET_EXPAND_TO_RTL_HOOK
+#define TARGET_EXPAND_TO_RTL_HOOK mips_expand_to_rtl_hook
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START mips_file_start
#undef TARGET_ASM_FILE_START_FILE_DIRECTIVE
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 86d2c55c5..570e78510 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -204,7 +204,7 @@
;; the split instructions; in some cases, it is more appropriate for the
;; scheduling type to be "multi" instead.
(define_attr "move_type"
- "unknown,load,fpload,store,fpstore,mtc,mfc,mtlo,mflo,move,fmove,
+ "unknown,load,fpload,store,fpstore,mtc,mfc,mtlo,mflo,imul,move,fmove,
const,constN,signext,ext_ins,logical,arith,sll0,andi,loadpool,
shift_shift"
(const_string "unknown"))
@@ -369,6 +369,7 @@
(eq_attr "move_type" "mflo") (const_string "mflo")
;; These types of move are always single insns.
+ (eq_attr "move_type" "imul") (const_string "imul")
(eq_attr "move_type" "fmove") (const_string "fmove")
(eq_attr "move_type" "loadpool") (const_string "load")
(eq_attr "move_type" "signext") (const_string "signext")
@@ -1293,32 +1294,20 @@
;; Combiner patterns for unsigned byte-add.
-(define_insn "*baddu_si_eb"
+(define_insn "*baddu_si"
[(set (match_operand:SI 0 "register_operand" "=d")
(zero_extend:SI
- (subreg:QI
- (plus:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")) 3)))]
- "ISA_HAS_BADDU && BYTES_BIG_ENDIAN"
- "baddu\\t%0,%1,%2"
- [(set_attr "alu_type" "add")])
-
-(define_insn "*baddu_si_el"
- [(set (match_operand:SI 0 "register_operand" "=d")
- (zero_extend:SI
- (subreg:QI
- (plus:SI (match_operand:SI 1 "register_operand" "d")
- (match_operand:SI 2 "register_operand" "d")) 0)))]
- "ISA_HAS_BADDU && !BYTES_BIG_ENDIAN"
+ (plus:QI (match_operand:QI 1 "register_operand" "d")
+ (match_operand:QI 2 "register_operand" "d"))))]
+ "ISA_HAS_BADDU"
"baddu\\t%0,%1,%2"
[(set_attr "alu_type" "add")])
(define_insn "*baddu_di<mode>"
[(set (match_operand:GPR 0 "register_operand" "=d")
(zero_extend:GPR
- (truncate:QI
- (plus:DI (match_operand:DI 1 "register_operand" "d")
- (match_operand:DI 2 "register_operand" "d")))))]
+ (plus:QI (truncate:QI (match_operand:DI 1 "register_operand" "d"))
+ (truncate:QI (match_operand:DI 2 "register_operand" "d")))))]
"ISA_HAS_BADDU && TARGET_64BIT"
"baddu\\t%0,%1,%2"
[(set_attr "alu_type" "add")])
@@ -4254,14 +4243,17 @@
(set_attr "mode" "<MODE>")])
(define_insn "*movdi_32bit"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d,*f,*f,*d,*m,*B*C*D,*B*C*D,*d,*m")
- (match_operand:DI 1 "move_operand" "d,i,m,d,*J*d,*a,*J*d,*m,*f,*f,*d,*m,*B*C*D,*B*C*D"))]
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d,*f,*f,*d,*m,*B*C*D,*B*C*D,*d,*m")
+ (match_operand:DI 1 "move_operand" "d,i,m,d,*J,*d,*a,*J*d,*m,*f,*f,*d,*m,*B*C*D,*B*C*D"))]
"!TARGET_64BIT && !TARGET_MIPS16
&& (register_operand (operands[0], DImode)
|| reg_or_0_operand (operands[1], DImode))"
{ return mips_output_move (operands[0], operands[1]); }
- [(set_attr "move_type" "move,const,load,store,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
- (set_attr "mode" "DI")])
+ [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo,mtc,fpload,mfc,fpstore,mtc,fpload,mfc,fpstore")
+ (set (attr "mode")
+ (if_then_else (eq_attr "move_type" "imul")
+ (const_string "SI")
+ (const_string "DI")))])
(define_insn "*movdi_32bit_mips16"
[(set (match_operand:DI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
@@ -4707,15 +4699,18 @@
})
(define_insn "*movti"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*d")
- (match_operand:TI 1 "move_operand" "d,i,m,dJ,*d*J,*a"))]
+ [(set (match_operand:TI 0 "nonimmediate_operand" "=d,d,d,m,*a,*a,*d")
+ (match_operand:TI 1 "move_operand" "d,i,m,dJ,*J,*d,*a"))]
"TARGET_64BIT
&& !TARGET_MIPS16
&& (register_operand (operands[0], TImode)
|| reg_or_0_operand (operands[1], TImode))"
- "#"
- [(set_attr "move_type" "move,const,load,store,mtlo,mflo")
- (set_attr "mode" "TI")])
+ { return mips_output_move (operands[0], operands[1]); }
+ [(set_attr "move_type" "move,const,load,store,imul,mtlo,mflo")
+ (set (attr "mode")
+ (if_then_else (eq_attr "move_type" "imul")
+ (const_string "SI")
+ (const_string "TI")))])
(define_insn "*movti_mips16"
[(set (match_operand:TI 0 "nonimmediate_operand" "=d,y,d,d,d,d,m,*d")
@@ -4765,21 +4760,20 @@
(define_split
[(set (match_operand:MOVE64 0 "nonimmediate_operand")
(match_operand:MOVE64 1 "move_operand"))]
- "reload_completed && !TARGET_64BIT
- && mips_split_64bit_move_p (operands[0], operands[1])"
+ "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
[(const_int 0)]
{
- mips_split_doubleword_move (operands[0], operands[1]);
+ mips_split_move_insn (operands[0], operands[1], curr_insn);
DONE;
})
(define_split
[(set (match_operand:MOVE128 0 "nonimmediate_operand")
(match_operand:MOVE128 1 "move_operand"))]
- "TARGET_64BIT && reload_completed"
+ "reload_completed && mips_split_move_insn_p (operands[0], operands[1], insn)"
[(const_int 0)]
{
- mips_split_doubleword_move (operands[0], operands[1]);
+ mips_split_move_insn (operands[0], operands[1], curr_insn);
DONE;
})
diff --git a/gcc/config/mmix/mmix.c b/gcc/config/mmix/mmix.c
index d5d72dfdc..26668e76d 100644
--- a/gcc/config/mmix/mmix.c
+++ b/gcc/config/mmix/mmix.c
@@ -2499,19 +2499,9 @@ mmix_output_shiftvalue_op_from_str (FILE *stream,
static void
mmix_output_octa (FILE *stream, HOST_WIDEST_INT value, int do_begin_end)
{
- /* Snipped from final.c:output_addr_const. We need to avoid the
- presumed universal "0x" prefix. We can do it by replacing "0x" with
- "#0" here; we must avoid a space in the operands and no, the zero
- won't cause the number to be assumed in octal format. */
- char hex_format[sizeof (HOST_WIDEST_INT_PRINT_HEX)];
-
if (do_begin_end)
fprintf (stream, "\tOCTA ");
- strcpy (hex_format, HOST_WIDEST_INT_PRINT_HEX);
- hex_format[0] = '#';
- hex_format[1] = '0';
-
/* Provide a few alternative output formats depending on the number, to
improve legibility of assembler output. */
if ((value < (HOST_WIDEST_INT) 0 && value > (HOST_WIDEST_INT) -10000)
@@ -2520,8 +2510,13 @@ mmix_output_octa (FILE *stream, HOST_WIDEST_INT value, int do_begin_end)
else if (value > (HOST_WIDEST_INT) 0
&& value < ((HOST_WIDEST_INT) 1 << 31) * 2)
fprintf (stream, "#%x", (unsigned int) value);
- else
- fprintf (stream, hex_format, value);
+ else if (sizeof (HOST_WIDE_INT) == sizeof (HOST_WIDEST_INT))
+ /* We need to avoid the not-so-universal "0x" prefix; we need the
+ pure hex-digits together with the mmixal "#" hex prefix. */
+ fprintf (stream, "#" HOST_WIDE_INT_PRINT_HEX_PURE,
+ (HOST_WIDE_INT) value);
+ else /* Need to avoid the hex output; there's no ...WIDEST...HEX_PURE. */
+ fprintf (stream, HOST_WIDEST_INT_PRINT_UNSIGNED, value);
if (do_begin_end)
fprintf (stream, "\n");
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index 8a7e6858c..80c40f504 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -2881,15 +2881,17 @@
[(set_attr "type" "store")
(set_attr "length" "4")])
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (plus:HI (match_operand:HI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "J")))]
+(define_insn "addhi3"
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (plus:HI (match_operand:HI 1 "register_operand" "%r,r")
+ (match_operand:HI 2 "arith14_operand" "r,J")))]
""
- "ldo %2(%1),%0"
- [(set_attr "type" "binary")
+ "@
+ {addl|add,l} %1,%2,%0
+ ldo %2(%1),%0"
+ [(set_attr "type" "binary,binary")
(set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4")])
+ (set_attr "length" "4,4")])
(define_expand "movqi"
[(set (match_operand:QI 0 "general_operand" "")
@@ -5621,22 +5623,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(and:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "and_operand" "")))]
- ""
- "
-{
- /* Both operands must be register operands. */
- if (!TARGET_64BIT && !register_operand (operands[2], DImode))
- FAIL;
-}")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI (match_operand:DI 1 "register_operand" "%r")
- (match_operand:DI 2 "register_operand" "r")))]
- "!TARGET_64BIT"
- "and %1,%2,%0\;and %R1,%R2,%R0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
+ "TARGET_64BIT"
+ "")
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r,r")
@@ -5662,15 +5650,6 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
(match_operand:DI 2 "register_operand" "r")))]
- "!TARGET_64BIT"
- "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
- (match_operand:DI 2 "register_operand" "r")))]
"TARGET_64BIT"
"andcm %2,%1,%0"
[(set_attr "type" "binary")
@@ -5689,22 +5668,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(ior:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_cint_ior_operand" "")))]
- ""
- "
-{
- /* Both operands must be register operands. */
- if (!TARGET_64BIT && !register_operand (operands[2], DImode))
- FAIL;
-}")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ior:DI (match_operand:DI 1 "register_operand" "%r")
- (match_operand:DI 2 "register_operand" "r")))]
- "!TARGET_64BIT"
- "or %1,%2,%0\;or %R1,%R2,%R0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
+ "TARGET_64BIT"
+ "")
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r,r")
@@ -5754,19 +5719,8 @@
[(set (match_operand:DI 0 "register_operand" "")
(xor:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "register_operand" "")))]
- ""
- "
-{
-}")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (xor:DI (match_operand:DI 1 "register_operand" "%r")
- (match_operand:DI 2 "register_operand" "r")))]
- "!TARGET_64BIT"
- "xor %1,%2,%0\;xor %R1,%R2,%R0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
+ "TARGET_64BIT"
+ "")
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 96026bdc5..1384a819b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -58,6 +58,7 @@
#include "tm-constrs.h"
#include "opts.h"
#include "tree-vectorizer.h"
+#include "dumpfile.h"
#if TARGET_XCOFF
#include "xcoffout.h" /* get declarations of xcoff_*_section_name */
#endif
@@ -2445,21 +2446,34 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_cpu_index = cpu_index = main_target_opt->x_rs6000_cpu_index;
have_cpu = true;
}
+ else if (implicit_cpu)
+ {
+ rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (implicit_cpu);
+ have_cpu = true;
+ }
else
{
- const char *default_cpu =
- (implicit_cpu ? implicit_cpu
- : (TARGET_POWERPC64 ? "powerpc64" : "powerpc"));
-
+ const char *default_cpu = (TARGET_POWERPC64 ? "powerpc64" : "powerpc");
rs6000_cpu_index = cpu_index = rs6000_cpu_name_lookup (default_cpu);
- have_cpu = implicit_cpu != 0;
+ have_cpu = false;
}
gcc_assert (cpu_index >= 0);
- target_flags &= ~set_masks;
- target_flags |= (processor_target_table[cpu_index].target_enable
- & set_masks);
+ /* If we have a cpu, either through an explicit -mcpu=<xxx> or if the
+ compiler was configured with --with-cpu=<xxx>, replace all of the ISA bits
+ with those from the cpu, except for options that were explicitly set. If
+ we don't have a cpu, do not override the target bits set in
+ TARGET_DEFAULT. */
+ if (have_cpu)
+ {
+ target_flags &= ~set_masks;
+ target_flags |= (processor_target_table[cpu_index].target_enable
+ & set_masks);
+ }
+ else
+ target_flags |= (processor_target_table[cpu_index].target_enable
+ & ~target_flags_explicit);
if (rs6000_tune_index >= 0)
tune_index = rs6000_tune_index;
@@ -2725,10 +2739,6 @@ rs6000_option_override_internal (bool global_init_p)
else
rs6000_altivec_abi = 1;
}
-
- /* Enable VRSAVE for AltiVec ABI, unless explicitly overridden. */
- if (!global_options_set.x_TARGET_ALTIVEC_VRSAVE)
- TARGET_ALTIVEC_VRSAVE = rs6000_altivec_abi;
}
/* Set the Darwin64 ABI as default for 64-bit Darwin.
@@ -3518,11 +3528,11 @@ rs6000_density_test (rs6000_cost_data *data)
&& vec_cost + not_vec_cost > DENSITY_SIZE_THRESHOLD)
{
data->cost[vect_body] = vec_cost * (100 + DENSITY_PENALTY) / 100;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump,
- "density %d%%, cost %d exceeds threshold, penalizing "
- "loop body cost by %d%%", density_pct,
- vec_cost + not_vec_cost, DENSITY_PENALTY);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "density %d%%, cost %d exceeds threshold, penalizing "
+ "loop body cost by %d%%", density_pct,
+ vec_cost + not_vec_cost, DENSITY_PENALTY);
}
}
@@ -14677,17 +14687,6 @@ print_operand (FILE *file, rtx x, int code)
{
/* %a is output_address. */
- case 'A':
- /* If X is a constant integer whose low-order 5 bits are zero,
- write 'l'. Otherwise, write 'r'. This is a kludge to fix a bug
- in the AIX assembler where "sri" with a zero shift count
- writes a trash instruction. */
- if (GET_CODE (x) == CONST_INT && (INTVAL (x) & 31) == 0)
- putc ('l', file);
- else
- putc ('r', file);
- return;
-
case 'b':
/* If constant, low-order 16 bits of constant, unsigned.
Otherwise, write normally. */
@@ -17842,7 +17841,8 @@ rs6000_stack_info (void)
else
info_ptr->spe_gp_size = 0;
- if (TARGET_ALTIVEC_ABI)
+ /* Set VRSAVE register if it is saved and restored. */
+ if (TARGET_ALTIVEC_ABI && TARGET_ALTIVEC_VRSAVE)
info_ptr->vrsave_mask = compute_vrsave_mask ();
else
info_ptr->vrsave_mask = 0;
@@ -28284,6 +28284,7 @@ rs6000_code_end (void)
TREE_PUBLIC (decl) = 1;
TREE_STATIC (decl) = 1;
+#if RS6000_WEAK
if (USE_HIDDEN_LINKONCE)
{
DECL_COMDAT_GROUP (decl) = DECL_ASSEMBLER_NAME (decl);
@@ -28296,6 +28297,7 @@ rs6000_code_end (void)
ASM_DECLARE_FUNCTION_NAME (asm_out_file, name, decl);
}
else
+#endif
{
switch_to_section (text_section);
ASM_OUTPUT_LABEL (asm_out_file, name);
diff --git a/gcc/config/rs6000/t-rs6000 b/gcc/config/rs6000/t-rs6000
index 8acc3399c..a96c0d2a7 100644
--- a/gcc/config/rs6000/t-rs6000
+++ b/gcc/config/rs6000/t-rs6000
@@ -26,7 +26,7 @@ rs6000.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(OBSTACK_H) $(TREE_H) $(EXPR_H) $(OPTABS_H) except.h function.h \
output.h dbxout.h $(BASIC_BLOCK_H) toplev.h $(GGC_H) $(HASHTAB_H) \
$(TM_P_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h reload.h gt-rs6000.h \
- cfgloop.h $(OPTS_H) $(COMMON_TARGET_H)
+ cfgloop.h $(OPTS_H) $(COMMON_TARGET_H) dumpfile.h
rs6000-c.o: $(srcdir)/config/rs6000/rs6000-c.c \
$(srcdir)/config/rs6000/rs6000-protos.h \
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index 43676d125..5d31eac97 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -1256,6 +1256,41 @@ rx_conditional_register_usage (void)
}
}
+struct decl_chain
+{
+ tree fndecl;
+ struct decl_chain * next;
+};
+
+/* Stack of decls for which we have issued warnings. */
+static struct decl_chain * warned_decls = NULL;
+
+static void
+add_warned_decl (tree fndecl)
+{
+ struct decl_chain * warned = (struct decl_chain *) xmalloc (sizeof * warned);
+
+ warned->fndecl = fndecl;
+ warned->next = warned_decls;
+ warned_decls = warned;
+}
+
+/* Returns TRUE if FNDECL is on our list of warned about decls. */
+
+static bool
+already_warned (tree fndecl)
+{
+ struct decl_chain * warned;
+
+ for (warned = warned_decls;
+ warned != NULL;
+ warned = warned->next)
+ if (warned->fndecl == fndecl)
+ return true;
+
+ return false;
+}
+
/* Perform any actions necessary before starting to compile FNDECL.
For the RX we use this to make sure that we have the correct
set of register masks selected. If FNDECL is NULL then we are
@@ -1288,6 +1323,24 @@ rx_set_current_function (tree fndecl)
target_reinit ();
}
+ if (current_is_fast_interrupt && rx_warn_multiple_fast_interrupts)
+ {
+ /* We do not warn about the first fast interrupt routine that
+ we see. Instead we just push it onto the stack. */
+ if (warned_decls == NULL)
+ add_warned_decl (fndecl);
+
+ /* Otherwise if this fast interrupt is one for which we have
+ not already issued a warning, generate one and then push
+ it onto the stack as well. */
+ else if (! already_warned (fndecl))
+ {
+ warning (0, "multiple fast interrupt routines seen: %qE and %qE",
+ fndecl, warned_decls->fndecl);
+ add_warned_decl (fndecl);
+ }
+ }
+
rx_previous_fndecl = fndecl;
}
diff --git a/gcc/config/rx/rx.opt b/gcc/config/rx/rx.opt
index 76c2f61c7..f0a57b1fa 100644
--- a/gcc/config/rx/rx.opt
+++ b/gcc/config/rx/rx.opt
@@ -118,3 +118,9 @@ Specifies whether interrupt functions should save and restore the accumulator re
mpid
Target Mask(PID)
Enables Position-Independent-Data (PID) mode.
+
+;---------------------------------------------------
+
+mwarn-multiple-fast-interrupts
+Target Report Var(rx_warn_multiple_fast_interrupts) Init(1) Warning
+Warn when multiple, different, fast interrupt handlers are in the compilation unit.
diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c
index 3f3ace526..bcbb2d445 100644
--- a/gcc/config/s390/s390.c
+++ b/gcc/config/s390/s390.c
@@ -1580,6 +1580,7 @@ s390_option_override (void)
break;
case PROCESSOR_2097_Z10:
s390_cost = &z10_cost;
+ break;
case PROCESSOR_2817_Z196:
s390_cost = &z196_cost;
break;
diff --git a/gcc/config/sh/linux.h b/gcc/config/sh/linux.h
index 904a7823b..e3fec2f54 100644
--- a/gcc/config/sh/linux.h
+++ b/gcc/config/sh/linux.h
@@ -138,11 +138,16 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_INIT_LIBFUNCS sh_init_sync_libfuncs
#undef SUBTARGET_OVERRIDE_OPTIONS
-#define SUBTARGET_OVERRIDE_OPTIONS \
- do \
- { \
- /* Defaulting to -msoft-atomic. */ \
- if (global_options_set.x_TARGET_SOFT_ATOMIC == 0) \
- TARGET_SOFT_ATOMIC = 1; \
- } \
+#define SUBTARGET_OVERRIDE_OPTIONS \
+ do \
+ { \
+ /* Set default atomic model if it hasn't been specified. */ \
+ if (global_options_set.x_sh_atomic_model_str == 0) \
+ { \
+ if (TARGET_SH3) \
+ sh_atomic_model_str = "soft-gusa"; \
+ else if (TARGET_SH1) \
+ sh_atomic_model_str = "soft-imask"; \
+ } \
+ } \
while (0)
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 93a33bf25..05ad85808 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -1071,3 +1071,19 @@
return false;
})
+
+;; A predicate that determines whether a given constant is a valid
+;; displacement for a gbr load/store of the specified mode.
+(define_predicate "gbr_displacement"
+ (match_code "const_int")
+{
+ const int mode_sz = GET_MODE_SIZE (mode);
+ const int move_sz = mode_sz > GET_MODE_SIZE (SImode)
+ ? GET_MODE_SIZE (SImode)
+ : mode_sz;
+ int max_disp = 255 * move_sz;
+ if (mode_sz > move_sz)
+ max_disp -= mode_sz - move_sz;
+
+ return INTVAL (op) >= 0 && INTVAL (op) <= max_disp;
+})
diff --git a/gcc/config/sh/sh-c.c b/gcc/config/sh/sh-c.c
index 2fdff542b..94c5f99d2 100644
--- a/gcc/config/sh/sh-c.c
+++ b/gcc/config/sh/sh-c.c
@@ -25,6 +25,9 @@ along with GCC; see the file COPYING3. If not see
#include "tm.h"
#include "tree.h"
#include "tm_p.h"
+#include "cpplib.h"
+#include "c-family/c-common.h"
+#include "target.h"
/* Handle machine specific pragmas to be semi-compatible with Renesas
compiler. */
@@ -66,3 +69,79 @@ sh_pr_nosave_low_regs (struct cpp_reader *pfile ATTRIBUTE_UNUSED)
{
sh_add_function_attribute ("nosave_low_regs");
}
+
+#define builtin_define(TXT) cpp_define (pfile, TXT)
+#define builtin_assert(TXT) cpp_assert (pfile, TXT)
+
+/* Implement the TARGET_CPU_CPP_BUILTINS macro */
+void
+sh_cpu_cpp_builtins (cpp_reader* pfile)
+{
+ builtin_define ("__sh__");
+ builtin_assert ("cpu=sh");
+ builtin_assert ("machine=sh");
+ switch ((int) sh_cpu)
+ {
+ case PROCESSOR_SH1:
+ builtin_define ("__sh1__");
+ builtin_define ("__SH1__");
+ break;
+ case PROCESSOR_SH2:
+ builtin_define ("__sh2__");
+ builtin_define ("__SH2__");
+ break;
+ case PROCESSOR_SH2E:
+ builtin_define ("__SH2E__");
+ break;
+ case PROCESSOR_SH2A:
+ builtin_define ("__SH2A__");
+ if (TARGET_SH2A_DOUBLE)
+ builtin_define (TARGET_FPU_SINGLE
+ ? "__SH2A_SINGLE__" : "__SH2A_DOUBLE__");
+ else
+ builtin_define (TARGET_FPU_ANY
+ ? "__SH2A_SINGLE_ONLY__" : "__SH2A_NOFPU__");
+ break;
+ case PROCESSOR_SH3:
+ builtin_define ("__sh3__");
+ builtin_define ("__SH3__");
+ if (TARGET_HARD_SH4)
+ builtin_define ("__SH4_NOFPU__");
+ break;
+ case PROCESSOR_SH3E:
+ builtin_define (TARGET_HARD_SH4 ? "__SH4_SINGLE_ONLY__" : "__SH3E__");
+ break;
+ case PROCESSOR_SH4:
+ builtin_define (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__");
+ break;
+ case PROCESSOR_SH4A: \
+ builtin_define ("__SH4A__");
+ builtin_define (TARGET_SH4
+ ? (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__")
+ : TARGET_FPU_ANY ? "__SH4_SINGLE_ONLY__"
+ : "__SH4_NOFPU__");
+ break;
+ case PROCESSOR_SH5:
+ {
+ builtin_define_with_value ("__SH5__",
+ TARGET_SHMEDIA64 ? "64" : "32", 0);
+ builtin_define_with_value ("__SHMEDIA__",
+ TARGET_SHMEDIA ? "1" : "0", 0);
+ if (! TARGET_FPU_DOUBLE)
+ builtin_define ("__SH4_NOFPU__");
+ }
+ }
+ if (TARGET_FPU_ANY)
+ builtin_define ("__SH_FPU_ANY__");
+ if (TARGET_FPU_DOUBLE)
+ builtin_define ("__SH_FPU_DOUBLE__");
+ if (TARGET_HITACHI)
+ builtin_define ("__HITACHI__");
+ if (TARGET_FMOVD)
+ builtin_define ("__FMOVD_ENABLED__");
+ builtin_define (TARGET_LITTLE_ENDIAN
+ ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__");
+
+ cpp_define_formatted (pfile, "__SH_ATOMIC_MODEL_%s__",
+ selected_atomic_model ().cdef_name);
+}
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index 827b1b488..d908110dc 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -37,6 +37,59 @@ enum sh_function_kind {
SFUNC_STATIC
};
+/* Atomic model. */
+struct sh_atomic_model
+{
+ enum enum_type
+ {
+ none = 0,
+ soft_gusa,
+ hard_llcs,
+ soft_tcb,
+ soft_imask,
+
+ num_models
+ };
+
+ /* If strict is set, disallow mixing of different models, as it would
+ happen on SH4A. */
+ bool strict;
+ enum_type type;
+
+ /* Name string as it was specified on the command line. */
+ const char* name;
+
+ /* Name string as it is used in C/C++ defines. */
+ const char* cdef_name;
+
+ /* GBR offset variable for TCB model. */
+ int tcb_gbr_offset;
+};
+
+extern const sh_atomic_model& selected_atomic_model (void);
+
+/* Shortcuts to check the currently selected atomic model. */
+#define TARGET_ATOMIC_ANY \
+ selected_atomic_model ().type != sh_atomic_model::none
+
+#define TARGET_ATOMIC_STRICT \
+ selected_atomic_model ().strict
+
+#define TARGET_ATOMIC_SOFT_GUSA \
+ selected_atomic_model ().type == sh_atomic_model::soft_gusa
+
+#define TARGET_ATOMIC_HARD_LLCS \
+ selected_atomic_model ().type == sh_atomic_model::hard_llcs
+
+#define TARGET_ATOMIC_SOFT_TCB \
+ selected_atomic_model ().type == sh_atomic_model::soft_tcb
+
+#define TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX \
+ GEN_INT (selected_atomic_model ().tcb_gbr_offset)
+
+#define TARGET_ATOMIC_SOFT_IMASK \
+ selected_atomic_model ().type == sh_atomic_model::soft_imask
+
#ifdef RTX_CODE
extern rtx sh_fsca_sf2int (void);
extern rtx sh_fsca_int2sf (void);
@@ -111,6 +164,8 @@ extern void sh_canonicalize_comparison (enum rtx_code&, rtx&, rtx&,
#endif /* RTX_CODE */
+extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
+
extern const char *output_jump_label_table (void);
extern rtx get_t_reg_rtx (void);
extern rtx get_fpscr_rtx (void);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index fd7879910..3a0689d94 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -62,6 +62,8 @@ along with GCC; see the file COPYING3. If not see
#include "tm-constrs.h"
#include "opts.h"
+#include <sstream>
+#include <vector>
#include <algorithm>
int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
@@ -241,8 +243,6 @@ static bool sh_ms_bitfield_layout_p (const_tree);
static void sh_init_builtins (void);
static tree sh_builtin_decl (unsigned, bool);
-static void sh_media_init_builtins (void);
-static tree sh_media_builtin_decl (unsigned, bool);
static rtx sh_expand_builtin (tree, rtx, rtx, enum machine_mode, int);
static void sh_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT, tree);
static void sh_file_start (void);
@@ -596,6 +596,119 @@ static const struct attribute_spec sh_attribute_table[] =
struct gcc_target targetm = TARGET_INITIALIZER;
+
+/* Information on the currently selected atomic model.
+ This is initialized in sh_option_override. */
+static sh_atomic_model selected_atomic_model_;
+
+const sh_atomic_model&
+selected_atomic_model (void)
+{
+ return selected_atomic_model_;
+}
+
+static sh_atomic_model
+parse_validate_atomic_model_option (const char* str)
+{
+ const char* model_names[sh_atomic_model::num_models];
+ model_names[sh_atomic_model::none] = "none";
+ model_names[sh_atomic_model::soft_gusa] = "soft-gusa";
+ model_names[sh_atomic_model::hard_llcs] = "hard-llcs";
+ model_names[sh_atomic_model::soft_tcb] = "soft-tcb";
+ model_names[sh_atomic_model::soft_imask] = "soft-imask";
+
+ const char* model_cdef_names[sh_atomic_model::num_models];
+ model_cdef_names[sh_atomic_model::none] = "NONE";
+ model_cdef_names[sh_atomic_model::soft_gusa] = "SOFT_GUSA";
+ model_cdef_names[sh_atomic_model::hard_llcs] = "HARD_LLCS";
+ model_cdef_names[sh_atomic_model::soft_tcb] = "SOFT_TCB";
+ model_cdef_names[sh_atomic_model::soft_imask] = "SOFT_IMASK";
+
+ sh_atomic_model ret;
+ ret.type = sh_atomic_model::none;
+ ret.name = model_names[sh_atomic_model::none];
+ ret.cdef_name = model_cdef_names[sh_atomic_model::none];
+ ret.strict = false;
+ ret.tcb_gbr_offset = -1;
+
+ /* Handle empty string as 'none'. */
+ if (str == NULL || *str == '\0')
+ return ret;
+
+#define err_ret(...) do { error (__VA_ARGS__); return ret; } while (0)
+
+ std::vector<std::string> tokens;
+ for (std::stringstream ss (str); ss.good (); )
+ {
+ tokens.push_back (std::string ());
+ std::getline (ss, tokens.back (), ',');
+ }
+
+ if (tokens.empty ())
+ err_ret ("invalid atomic model option");
+
+ /* The first token must be the atomic model name. */
+ {
+ for (size_t i = 0; i < sh_atomic_model::num_models; ++i)
+ if (tokens.front () == model_names[i])
+ {
+ ret.type = (sh_atomic_model::enum_type)i;
+ ret.name = model_names[i];
+ ret.cdef_name = model_cdef_names[i];
+ goto got_mode_name;
+ }
+
+ err_ret ("invalid atomic model name \"%s\"", tokens.front ().c_str ());
+got_mode_name:;
+ }
+
+ /* Go through the remaining tokens. */
+ for (size_t i = 1; i < tokens.size (); ++i)
+ {
+ if (tokens[i] == "strict")
+ ret.strict = true;
+ else if (tokens[i].find ("gbr-offset=") == 0)
+ {
+ std::string offset_str = tokens[i].substr (strlen ("gbr-offset="));
+ ret.tcb_gbr_offset = integral_argument (offset_str.c_str ());
+ if (offset_str.empty () || ret.tcb_gbr_offset == -1)
+ err_ret ("could not parse gbr-offset value \"%s\" in atomic model "
+ "option", offset_str.c_str ());
+ }
+ else
+ err_ret ("unknown parameter \"%s\" in atomic model option",
+ tokens[i].c_str ());
+ }
+
+ /* Check that the selection makes sense. */
+ if (TARGET_SHMEDIA && ret.type != sh_atomic_model::none)
+ err_ret ("atomic operations are not supported on SHmedia");
+
+ if (ret.type == sh_atomic_model::soft_gusa && !TARGET_SH3)
+ err_ret ("atomic model %s is only available on SH3 and SH4 targets",
+ ret.name);
+
+ if (ret.type == sh_atomic_model::hard_llcs && !TARGET_SH4A)
+ err_ret ("atomic model %s is only available on SH4A targets", ret.name);
+
+ if (ret.type == sh_atomic_model::soft_tcb && ret.tcb_gbr_offset == -1)
+ err_ret ("atomic model %s requires gbr-offset parameter", ret.name);
+
+ if (ret.type == sh_atomic_model::soft_tcb
+ && (ret.tcb_gbr_offset < 0 || ret.tcb_gbr_offset > 1020
+ || (ret.tcb_gbr_offset & 3) != 0))
+ err_ret ("invalid gbr-offset value \"%d\" for atomic model %s; it must be "
+ "a multiple of 4 in the range 0-1020", ret.tcb_gbr_offset,
+ ret.name);
+
+ if (ret.type == sh_atomic_model::soft_imask && TARGET_USERMODE)
+ err_ret ("cannot use atomic model %s in user mode", ret.name);
+
+ return ret;
+
+#undef err_ret
+}
+
/* Implement TARGET_OPTION_OVERRIDE macro. Validate and override
various options, and do some machine dependent initialization. */
static void
@@ -907,12 +1020,10 @@ sh_option_override (void)
if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2))
flag_strict_volatile_bitfields = 1;
- /* Make sure that only one atomic mode is selected and that the selection
- is valid for the current target CPU. */
- if (TARGET_SOFT_ATOMIC && TARGET_HARD_ATOMIC)
- error ("-msoft-atomic and -mhard-atomic cannot be used at the same time");
- if (TARGET_HARD_ATOMIC && ! TARGET_SH4A_ARCH)
- error ("-mhard-atomic is only available for SH4A targets");
+ /* Parse atomic model option and make sure it is valid for the current
+ target CPU. */
+ selected_atomic_model_
+ = parse_validate_atomic_model_option (sh_atomic_model_str);
}
/* Print the operand address in x to the stream. */
@@ -1776,7 +1887,7 @@ prepare_move_operands (rtx operands[], enum machine_mode mode)
case TLS_MODEL_LOCAL_EXEC:
tmp2 = gen_reg_rtx (Pmode);
- emit_insn (gen_load_gbr (tmp2));
+ emit_insn (gen_store_gbr (tmp2));
tmp = gen_reg_rtx (Pmode);
emit_insn (gen_symTPOFF2reg (tmp, op1));
@@ -11397,12 +11508,25 @@ sh_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
struct builtin_description
{
+ bool (* const is_enabled) (void);
const enum insn_code icode;
const char *const name;
int signature;
tree fndecl;
};
+static bool
+shmedia_builtin_p (void)
+{
+ return TARGET_SHMEDIA;
+}
+
+static bool
+sh1_builtin_p (void)
+{
+ return TARGET_SH1;
+}
+
/* describe number and signedness of arguments; arg[0] == result
(1: unsigned, 2: signed, 4: don't care, 8: pointer 0: no argument */
/* 9: 64-bit pointer, 10: 32-bit pointer */
@@ -11460,6 +11584,8 @@ static const char signature_args[][4] =
{ 1, 1, 1, 1 },
#define SH_BLTIN_PV 23
{ 0, 8 },
+#define SH_BLTIN_VP 24
+ { 8, 0 },
};
/* mcmv: operands considered unsigned. */
/* mmulsum_wq, msad_ubq: result considered unsigned long long. */
@@ -11469,103 +11595,195 @@ static const char signature_args[][4] =
/* nsb: takes long long arg, returns unsigned char. */
static struct builtin_description bdesc[] =
{
- { CODE_FOR_absv2si2, "__builtin_absv2si2", SH_BLTIN_V2SI2, 0 },
- { CODE_FOR_absv4hi2, "__builtin_absv4hi2", SH_BLTIN_V4HI2, 0 },
- { CODE_FOR_addv2si3, "__builtin_addv2si3", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_addv4hi3, "__builtin_addv4hi3", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_ssaddv2si3,"__builtin_ssaddv2si3", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_usaddv8qi3,"__builtin_usaddv8qi3", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_ssaddv4hi3,"__builtin_ssaddv4hi3", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_alloco_i, "__builtin_sh_media_ALLOCO", SH_BLTIN_PV, 0 },
- { CODE_FOR_negcmpeqv8qi,"__builtin_sh_media_MCMPEQ_B", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_negcmpeqv2si,"__builtin_sh_media_MCMPEQ_L", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_negcmpeqv4hi,"__builtin_sh_media_MCMPEQ_W", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_negcmpgtuv8qi,"__builtin_sh_media_MCMPGT_UB", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_negcmpgtv2si,"__builtin_sh_media_MCMPGT_L", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_negcmpgtv4hi,"__builtin_sh_media_MCMPGT_W", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_mcmv, "__builtin_sh_media_MCMV", SH_BLTIN_UUUU, 0 },
- { CODE_FOR_mcnvs_lw, "__builtin_sh_media_MCNVS_LW", SH_BLTIN_3, 0 },
- { CODE_FOR_mcnvs_wb, "__builtin_sh_media_MCNVS_WB", SH_BLTIN_V4HI2V8QI, 0 },
- { CODE_FOR_mcnvs_wub, "__builtin_sh_media_MCNVS_WUB", SH_BLTIN_V4HI2V8QI, 0 },
- { CODE_FOR_mextr1, "__builtin_sh_media_MEXTR1", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mextr2, "__builtin_sh_media_MEXTR2", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mextr3, "__builtin_sh_media_MEXTR3", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mextr4, "__builtin_sh_media_MEXTR4", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mextr5, "__builtin_sh_media_MEXTR5", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mextr6, "__builtin_sh_media_MEXTR6", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mextr7, "__builtin_sh_media_MEXTR7", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mmacfx_wl, "__builtin_sh_media_MMACFX_WL", SH_BLTIN_MAC_HISI, 0 },
- { CODE_FOR_mmacnfx_wl,"__builtin_sh_media_MMACNFX_WL", SH_BLTIN_MAC_HISI, 0 },
- { CODE_FOR_mulv2si3, "__builtin_mulv2si3", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_mulv4hi3, "__builtin_mulv4hi3", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_mmulfx_l, "__builtin_sh_media_MMULFX_L", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_mmulfx_w, "__builtin_sh_media_MMULFX_W", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_mmulfxrp_w,"__builtin_sh_media_MMULFXRP_W", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_mmulhi_wl, "__builtin_sh_media_MMULHI_WL", SH_BLTIN_V4HI2V2SI, 0 },
- { CODE_FOR_mmullo_wl, "__builtin_sh_media_MMULLO_WL", SH_BLTIN_V4HI2V2SI, 0 },
- { CODE_FOR_mmulsum_wq,"__builtin_sh_media_MMULSUM_WQ", SH_BLTIN_XXUU, 0 },
- { CODE_FOR_mperm_w, "__builtin_sh_media_MPERM_W", SH_BLTIN_SH_HI, 0 },
- { CODE_FOR_msad_ubq, "__builtin_sh_media_MSAD_UBQ", SH_BLTIN_XXUU, 0 },
- { CODE_FOR_mshalds_l, "__builtin_sh_media_MSHALDS_L", SH_BLTIN_SH_SI, 0 },
- { CODE_FOR_mshalds_w, "__builtin_sh_media_MSHALDS_W", SH_BLTIN_SH_HI, 0 },
- { CODE_FOR_ashrv2si3, "__builtin_ashrv2si3", SH_BLTIN_SH_SI, 0 },
- { CODE_FOR_ashrv4hi3, "__builtin_ashrv4hi3", SH_BLTIN_SH_HI, 0 },
- { CODE_FOR_mshards_q, "__builtin_sh_media_MSHARDS_Q", SH_BLTIN_SUS, 0 },
- { CODE_FOR_mshfhi_b, "__builtin_sh_media_MSHFHI_B", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mshfhi_l, "__builtin_sh_media_MSHFHI_L", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_mshfhi_w, "__builtin_sh_media_MSHFHI_W", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_mshflo_b, "__builtin_sh_media_MSHFLO_B", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_mshflo_l, "__builtin_sh_media_MSHFLO_L", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_mshflo_w, "__builtin_sh_media_MSHFLO_W", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_ashlv2si3, "__builtin_ashlv2si3", SH_BLTIN_SH_SI, 0 },
- { CODE_FOR_ashlv4hi3, "__builtin_ashlv4hi3", SH_BLTIN_SH_HI, 0 },
- { CODE_FOR_lshrv2si3, "__builtin_lshrv2si3", SH_BLTIN_SH_SI, 0 },
- { CODE_FOR_lshrv4hi3, "__builtin_lshrv4hi3", SH_BLTIN_SH_HI, 0 },
- { CODE_FOR_subv2si3, "__builtin_subv2si3", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_subv4hi3, "__builtin_subv4hi3", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_sssubv2si3,"__builtin_sssubv2si3", SH_BLTIN_V2SI3, 0 },
- { CODE_FOR_ussubv8qi3,"__builtin_ussubv8qi3", SH_BLTIN_V8QI3, 0 },
- { CODE_FOR_sssubv4hi3,"__builtin_sssubv4hi3", SH_BLTIN_V4HI3, 0 },
- { CODE_FOR_fcosa_s, "__builtin_sh_media_FCOSA_S", SH_BLTIN_SISF, 0 },
- { CODE_FOR_fsina_s, "__builtin_sh_media_FSINA_S", SH_BLTIN_SISF, 0 },
- { CODE_FOR_fipr, "__builtin_sh_media_FIPR_S", SH_BLTIN_3, 0 },
- { CODE_FOR_ftrv, "__builtin_sh_media_FTRV_S", SH_BLTIN_3, 0 },
- { CODE_FOR_sqrtdf2, "__builtin_sh_media_FSQRT_D", SH_BLTIN_2, 0 },
- { CODE_FOR_sqrtsf2, "__builtin_sh_media_FSQRT_S", SH_BLTIN_2, 0 },
- { CODE_FOR_fsrra_s, "__builtin_sh_media_FSRRA_S", SH_BLTIN_2, 0 },
- { CODE_FOR_ldhi_l, "__builtin_sh_media_LDHI_L", SH_BLTIN_LDUA_L, 0 },
- { CODE_FOR_ldhi_q, "__builtin_sh_media_LDHI_Q", SH_BLTIN_LDUA_Q, 0 },
- { CODE_FOR_ldlo_l, "__builtin_sh_media_LDLO_L", SH_BLTIN_LDUA_L, 0 },
- { CODE_FOR_ldlo_q, "__builtin_sh_media_LDLO_Q", SH_BLTIN_LDUA_Q, 0 },
- { CODE_FOR_sthi_l, "__builtin_sh_media_STHI_L", SH_BLTIN_STUA_L, 0 },
- { CODE_FOR_sthi_q, "__builtin_sh_media_STHI_Q", SH_BLTIN_STUA_Q, 0 },
- { CODE_FOR_stlo_l, "__builtin_sh_media_STLO_L", SH_BLTIN_STUA_L, 0 },
- { CODE_FOR_stlo_q, "__builtin_sh_media_STLO_Q", SH_BLTIN_STUA_Q, 0 },
- { CODE_FOR_ldhi_l64, "__builtin_sh_media_LDHI_L", SH_BLTIN_LDUA_L64, 0 },
- { CODE_FOR_ldhi_q64, "__builtin_sh_media_LDHI_Q", SH_BLTIN_LDUA_Q64, 0 },
- { CODE_FOR_ldlo_l64, "__builtin_sh_media_LDLO_L", SH_BLTIN_LDUA_L64, 0 },
- { CODE_FOR_ldlo_q64, "__builtin_sh_media_LDLO_Q", SH_BLTIN_LDUA_Q64, 0 },
- { CODE_FOR_sthi_l64, "__builtin_sh_media_STHI_L", SH_BLTIN_STUA_L64, 0 },
- { CODE_FOR_sthi_q64, "__builtin_sh_media_STHI_Q", SH_BLTIN_STUA_Q64, 0 },
- { CODE_FOR_stlo_l64, "__builtin_sh_media_STLO_L", SH_BLTIN_STUA_L64, 0 },
- { CODE_FOR_stlo_q64, "__builtin_sh_media_STLO_Q", SH_BLTIN_STUA_Q64, 0 },
- { CODE_FOR_nsb, "__builtin_sh_media_NSB", SH_BLTIN_SU, 0 },
- { CODE_FOR_byterev, "__builtin_sh_media_BYTEREV", SH_BLTIN_2, 0 },
- { CODE_FOR_prefetch, "__builtin_sh_media_PREFO", SH_BLTIN_PSSV, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_absv2si2, "__builtin_absv2si2", SH_BLTIN_V2SI2, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_absv4hi2, "__builtin_absv4hi2", SH_BLTIN_V4HI2, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_addv2si3, "__builtin_addv2si3", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_addv4hi3, "__builtin_addv4hi3", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ssaddv2si3,"__builtin_ssaddv2si3", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_usaddv8qi3,"__builtin_usaddv8qi3", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ssaddv4hi3,"__builtin_ssaddv4hi3", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_alloco_i, "__builtin_sh_media_ALLOCO", SH_BLTIN_PV, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_negcmpeqv8qi,"__builtin_sh_media_MCMPEQ_B", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_negcmpeqv2si,"__builtin_sh_media_MCMPEQ_L", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_negcmpeqv4hi,"__builtin_sh_media_MCMPEQ_W", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_negcmpgtuv8qi,"__builtin_sh_media_MCMPGT_UB", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_negcmpgtv2si,"__builtin_sh_media_MCMPGT_L", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_negcmpgtv4hi,"__builtin_sh_media_MCMPGT_W", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mcmv, "__builtin_sh_media_MCMV", SH_BLTIN_UUUU, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mcnvs_lw, "__builtin_sh_media_MCNVS_LW", SH_BLTIN_3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mcnvs_wb, "__builtin_sh_media_MCNVS_WB", SH_BLTIN_V4HI2V8QI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mcnvs_wub, "__builtin_sh_media_MCNVS_WUB", SH_BLTIN_V4HI2V8QI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mextr1, "__builtin_sh_media_MEXTR1", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mextr2, "__builtin_sh_media_MEXTR2", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mextr3, "__builtin_sh_media_MEXTR3", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mextr4, "__builtin_sh_media_MEXTR4", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mextr5, "__builtin_sh_media_MEXTR5", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mextr6, "__builtin_sh_media_MEXTR6", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mextr7, "__builtin_sh_media_MEXTR7", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mmacfx_wl, "__builtin_sh_media_MMACFX_WL", SH_BLTIN_MAC_HISI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mmacnfx_wl,"__builtin_sh_media_MMACNFX_WL", SH_BLTIN_MAC_HISI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mulv2si3, "__builtin_mulv2si3", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mulv4hi3, "__builtin_mulv4hi3", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mmulfx_l, "__builtin_sh_media_MMULFX_L", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mmulfx_w, "__builtin_sh_media_MMULFX_W", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mmulfxrp_w,"__builtin_sh_media_MMULFXRP_W", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mmulhi_wl, "__builtin_sh_media_MMULHI_WL", SH_BLTIN_V4HI2V2SI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mmullo_wl, "__builtin_sh_media_MMULLO_WL", SH_BLTIN_V4HI2V2SI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mmulsum_wq,"__builtin_sh_media_MMULSUM_WQ", SH_BLTIN_XXUU, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mperm_w, "__builtin_sh_media_MPERM_W", SH_BLTIN_SH_HI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_msad_ubq, "__builtin_sh_media_MSAD_UBQ", SH_BLTIN_XXUU, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshalds_l, "__builtin_sh_media_MSHALDS_L", SH_BLTIN_SH_SI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshalds_w, "__builtin_sh_media_MSHALDS_W", SH_BLTIN_SH_HI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ashrv2si3, "__builtin_ashrv2si3", SH_BLTIN_SH_SI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ashrv4hi3, "__builtin_ashrv4hi3", SH_BLTIN_SH_HI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshards_q, "__builtin_sh_media_MSHARDS_Q", SH_BLTIN_SUS, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshfhi_b, "__builtin_sh_media_MSHFHI_B", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshfhi_l, "__builtin_sh_media_MSHFHI_L", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshfhi_w, "__builtin_sh_media_MSHFHI_W", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshflo_b, "__builtin_sh_media_MSHFLO_B", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshflo_l, "__builtin_sh_media_MSHFLO_L", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_mshflo_w, "__builtin_sh_media_MSHFLO_W", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ashlv2si3, "__builtin_ashlv2si3", SH_BLTIN_SH_SI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ashlv4hi3, "__builtin_ashlv4hi3", SH_BLTIN_SH_HI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_lshrv2si3, "__builtin_lshrv2si3", SH_BLTIN_SH_SI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_lshrv4hi3, "__builtin_lshrv4hi3", SH_BLTIN_SH_HI, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_subv2si3, "__builtin_subv2si3", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_subv4hi3, "__builtin_subv4hi3", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_sssubv2si3,"__builtin_sssubv2si3", SH_BLTIN_V2SI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ussubv8qi3,"__builtin_ussubv8qi3", SH_BLTIN_V8QI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_sssubv4hi3,"__builtin_sssubv4hi3", SH_BLTIN_V4HI3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_fcosa_s, "__builtin_sh_media_FCOSA_S", SH_BLTIN_SISF, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_fsina_s, "__builtin_sh_media_FSINA_S", SH_BLTIN_SISF, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_fipr, "__builtin_sh_media_FIPR_S", SH_BLTIN_3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ftrv, "__builtin_sh_media_FTRV_S", SH_BLTIN_3, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_sqrtdf2, "__builtin_sh_media_FSQRT_D", SH_BLTIN_2, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_sqrtsf2, "__builtin_sh_media_FSQRT_S", SH_BLTIN_2, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_fsrra_s, "__builtin_sh_media_FSRRA_S", SH_BLTIN_2, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ldhi_l, "__builtin_sh_media_LDHI_L", SH_BLTIN_LDUA_L, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ldhi_q, "__builtin_sh_media_LDHI_Q", SH_BLTIN_LDUA_Q, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ldlo_l, "__builtin_sh_media_LDLO_L", SH_BLTIN_LDUA_L, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ldlo_q, "__builtin_sh_media_LDLO_Q", SH_BLTIN_LDUA_Q, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_sthi_l, "__builtin_sh_media_STHI_L", SH_BLTIN_STUA_L, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_sthi_q, "__builtin_sh_media_STHI_Q", SH_BLTIN_STUA_Q, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_stlo_l, "__builtin_sh_media_STLO_L", SH_BLTIN_STUA_L, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_stlo_q, "__builtin_sh_media_STLO_Q", SH_BLTIN_STUA_Q, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ldhi_l64, "__builtin_sh_media_LDHI_L", SH_BLTIN_LDUA_L64, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ldhi_q64, "__builtin_sh_media_LDHI_Q", SH_BLTIN_LDUA_Q64, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ldlo_l64, "__builtin_sh_media_LDLO_L", SH_BLTIN_LDUA_L64, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_ldlo_q64, "__builtin_sh_media_LDLO_Q", SH_BLTIN_LDUA_Q64, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_sthi_l64, "__builtin_sh_media_STHI_L", SH_BLTIN_STUA_L64, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_sthi_q64, "__builtin_sh_media_STHI_Q", SH_BLTIN_STUA_Q64, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_stlo_l64, "__builtin_sh_media_STLO_L", SH_BLTIN_STUA_L64, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_stlo_q64, "__builtin_sh_media_STLO_Q", SH_BLTIN_STUA_Q64, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_nsb, "__builtin_sh_media_NSB", SH_BLTIN_SU, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_byterev, "__builtin_sh_media_BYTEREV", SH_BLTIN_2, 0 },
+ { shmedia_builtin_p,
+ CODE_FOR_prefetch, "__builtin_sh_media_PREFO", SH_BLTIN_PSSV, 0 },
+
+ { sh1_builtin_p,
+ CODE_FOR_get_thread_pointer, "__builtin_thread_pointer", SH_BLTIN_VP, 0 },
+ { sh1_builtin_p,
+ CODE_FOR_set_thread_pointer, "__builtin_set_thread_pointer",
+ SH_BLTIN_PV, 0 },
};
static void
-sh_media_init_builtins (void)
+sh_init_builtins (void)
{
tree shared[SH_BLTIN_NUM_SHARED_SIGNATURES];
- struct builtin_description *d;
-
memset (shared, 0, sizeof shared);
- for (d = bdesc; d - bdesc < (int) ARRAY_SIZE (bdesc); d++)
+
+ for (unsigned int di = 0; di < ARRAY_SIZE (bdesc); ++di)
{
- tree type, arg_type = 0;
+ builtin_description* d = &bdesc[di];
+
+ if (!d->is_enabled ())
+ continue;
+
+ tree type, arg_type = NULL_TREE;
int signature = d->signature;
- int i;
if (signature < SH_BLTIN_NUM_SHARED_SIGNATURES && shared[signature])
type = shared[signature];
@@ -11581,9 +11799,9 @@ sh_media_init_builtins (void)
if (! TARGET_FPU_ANY
&& FLOAT_MODE_P (insn_data[d->icode].operand[0].mode))
continue;
- for (i = 0; i < (int) ARRAY_SIZE (args); i++)
+ for (unsigned int i = 0; i < ARRAY_SIZE (args); i++)
args[i] = NULL_TREE;
- for (i = 3; ; i--)
+ for (int i = 3; ; i--)
{
int arg = signature_args[signature][i];
int opno = i - 1 + has_result;
@@ -11592,8 +11810,7 @@ sh_media_init_builtins (void)
arg_type = ptr_type_node;
else if (arg)
arg_type = (*lang_hooks.types.type_for_mode)
- (insn_data[d->icode].operand[opno].mode,
- (arg & 1));
+ (insn_data[d->icode].operand[opno].mode, (arg & 1));
else if (i)
continue;
else
@@ -11613,17 +11830,6 @@ sh_media_init_builtins (void)
}
}
-/* Returns the shmedia builtin decl for CODE. */
-
-static tree
-sh_media_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
-{
- if (code >= ARRAY_SIZE (bdesc))
- return error_mark_node;
-
- return bdesc[code].fndecl;
-}
-
/* Implements target hook vector_mode_supported_p. */
bool
sh_vector_mode_supported_p (enum machine_mode mode)
@@ -11669,22 +11875,18 @@ sh_dwarf_calling_convention (const_tree func)
return DW_CC_normal;
}
-static void
-sh_init_builtins (void)
-{
- if (TARGET_SHMEDIA)
- sh_media_init_builtins ();
-}
-
/* Returns the sh builtin decl for CODE. */
static tree
sh_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
-{
- if (TARGET_SHMEDIA)
- return sh_media_builtin_decl (code, initialize_p);
-
- return error_mark_node;
+{
+ if (code >= ARRAY_SIZE (bdesc))
+ return error_mark_node;
+
+ if (!bdesc[code].is_enabled ())
+ return error_mark_node;
+
+ return bdesc[code].fndecl;
}
/* Expand an expression EXP that calls a built-in function,
@@ -11702,27 +11904,24 @@ sh_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
const struct builtin_description *d = &bdesc[fcode];
enum insn_code icode = d->icode;
int signature = d->signature;
- enum machine_mode tmode = VOIDmode;
- int nop = 0, i;
+ int nop = 0;
rtx op[4];
- rtx pat = NULL_RTX;
if (signature_args[signature][0])
{
if (ignore)
return NULL_RTX;
- tmode = insn_data[icode].operand[0].mode;
- if (! target
- || GET_MODE (target) != tmode
+ enum machine_mode tmode = insn_data[icode].operand[0].mode;
+ if (! target || GET_MODE (target) != tmode
|| ! (*insn_data[icode].operand[0].predicate) (target, tmode))
target = gen_reg_rtx (tmode);
op[nop++] = target;
}
else
- target = 0;
+ target = NULL_RTX;
- for (i = 1; i <= 3; i++, nop++)
+ for (int i = 1; i <= 3; i++, nop++)
{
tree arg;
enum machine_mode opmode, argmode;
@@ -11751,6 +11950,8 @@ sh_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
op[nop] = copy_to_mode_reg (opmode, op[nop]);
}
+ rtx pat = NULL_RTX;
+
switch (nop)
{
case 1:
@@ -13021,6 +13222,12 @@ sh_can_use_simple_return_p (void)
HARD_REG_SET live_regs_mask;
int d;
+ /* Some targets require special return insns. */
+ if (TARGET_SHMEDIA
+ || (TARGET_SHCOMPACT
+ && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
+ return false;
+
if (! reload_completed || frame_pointer_needed)
return false;
@@ -13039,7 +13246,6 @@ sh_can_use_simple_return_p (void)
return false;
return true;
-
}
#include "gt-sh.h"
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index d72379022..52875265e 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -31,69 +31,7 @@ along with GCC; see the file COPYING3. If not see
/* ??? No longer true. */
extern int code_for_indirect_jump_scratch;
-#define TARGET_CPU_CPP_BUILTINS() \
-do { \
- builtin_define ("__sh__"); \
- builtin_assert ("cpu=sh"); \
- builtin_assert ("machine=sh"); \
- switch ((int) sh_cpu) \
- { \
- case PROCESSOR_SH1: \
- builtin_define ("__sh1__"); \
- break; \
- case PROCESSOR_SH2: \
- builtin_define ("__sh2__"); \
- break; \
- case PROCESSOR_SH2E: \
- builtin_define ("__SH2E__"); \
- break; \
- case PROCESSOR_SH2A: \
- builtin_define ("__SH2A__"); \
- builtin_define (TARGET_SH2A_DOUBLE \
- ? (TARGET_FPU_SINGLE ? "__SH2A_SINGLE__" : "__SH2A_DOUBLE__") \
- : TARGET_FPU_ANY ? "__SH2A_SINGLE_ONLY__" \
- : "__SH2A_NOFPU__"); \
- break; \
- case PROCESSOR_SH3: \
- builtin_define ("__sh3__"); \
- builtin_define ("__SH3__"); \
- if (TARGET_HARD_SH4) \
- builtin_define ("__SH4_NOFPU__"); \
- break; \
- case PROCESSOR_SH3E: \
- builtin_define (TARGET_HARD_SH4 ? "__SH4_SINGLE_ONLY__" : "__SH3E__"); \
- break; \
- case PROCESSOR_SH4: \
- builtin_define (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__"); \
- break; \
- case PROCESSOR_SH4A: \
- builtin_define ("__SH4A__"); \
- builtin_define (TARGET_SH4 \
- ? (TARGET_FPU_SINGLE ? "__SH4_SINGLE__" : "__SH4__") \
- : TARGET_FPU_ANY ? "__SH4_SINGLE_ONLY__" \
- : "__SH4_NOFPU__"); \
- break; \
- case PROCESSOR_SH5: \
- { \
- builtin_define_with_value ("__SH5__", \
- TARGET_SHMEDIA64 ? "64" : "32", 0); \
- builtin_define_with_value ("__SHMEDIA__", \
- TARGET_SHMEDIA ? "1" : "0", 0); \
- if (! TARGET_FPU_DOUBLE) \
- builtin_define ("__SH4_NOFPU__"); \
- } \
- } \
- if (TARGET_FPU_ANY) \
- builtin_define ("__SH_FPU_ANY__"); \
- if (TARGET_FPU_DOUBLE) \
- builtin_define ("__SH_FPU_DOUBLE__"); \
- if (TARGET_HITACHI) \
- builtin_define ("__HITACHI__"); \
- if (TARGET_FMOVD) \
- builtin_define ("__FMOVD_ENABLED__"); \
- builtin_define (TARGET_LITTLE_ENDIAN \
- ? "__LITTLE_ENDIAN__" : "__BIG_ENDIAN__"); \
-} while (0)
+#define TARGET_CPU_CPP_BUILTINS() sh_cpu_cpp_builtins (pfile)
/* Value should be nonzero if functions must have frame pointers.
Zero means the frame pointer need not be set up (and parms may be accessed
@@ -172,9 +110,6 @@ do { \
(TARGET_SH1 && ! TARGET_SH2E && ! TARGET_SH5 \
&& ! (TARGET_HITACHI || sh_attr_renesas_p (FUN_DECL)))
-/* Nonzero if either soft or hard atomics are enabled. */
-#define TARGET_ANY_ATOMIC (TARGET_SOFT_ATOMIC | TARGET_HARD_ATOMIC)
-
#ifndef TARGET_CPU_DEFAULT
#define TARGET_CPU_DEFAULT SELECT_SH1
#define SUPPORT_SH1 1
@@ -436,20 +371,8 @@ do { \
"%{m2a*:%eSH2a does not support little-endian}}"
#endif
-#define UNSUPPORTED_ATOMIC_OPTIONS \
-"%{msoft-atomic:%{mhard-atomic:%e-msoft-atomic and -mhard-atomic cannot be \
-used at the same time}}"
-
-#if TARGET_CPU_DEFAULT & MASK_SH4A
-#define UNSUPPORTED_HARD_ATOMIC_CPU ""
-#else
-#define UNSUPPORTED_HARD_ATOMIC_CPU \
-"%{!m4a*:%{mhard-atomic:%e-mhard-atomic is only available for SH4A targets}}"
-#endif
-
#undef DRIVER_SELF_SPECS
-#define DRIVER_SELF_SPECS UNSUPPORTED_SH2A, UNSUPPORTED_ATOMIC_OPTIONS,\
- UNSUPPORTED_HARD_ATOMIC_CPU
+#define DRIVER_SELF_SPECS UNSUPPORTED_SH2A
#define ASSEMBLER_DIALECT assembler_dialect
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index 8f0443ad6..eeed56190 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -175,6 +175,7 @@
(UNSPECV_WINDOW_END 10)
(UNSPECV_CONST_END 11)
(UNSPECV_EH_RETURN 12)
+ (UNSPECV_GBR 13)
])
;; -------------------------------------------------------------------------
@@ -10029,13 +10030,37 @@ label:
DONE;
})
-(define_insn "load_gbr"
- [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))
- (use (reg:SI GBR_REG))]
+;;------------------------------------------------------------------------------
+;; Thread pointer getter and setter.
+;;
+;; On SH the thread pointer is kept in the GBR.
+;; These patterns are usually expanded from the respective built-in functions.
+(define_expand "get_thread_pointer"
+ [(set (match_operand:SI 0 "register_operand") (reg:SI GBR_REG))]
+ "TARGET_SH1")
+
+;; The store_gbr insn can also be used on !TARGET_SH1 for doing TLS accesses.
+(define_insn "store_gbr"
+ [(set (match_operand:SI 0 "register_operand" "=r") (reg:SI GBR_REG))]
""
"stc gbr,%0"
[(set_attr "type" "tls_load")])
+(define_expand "set_thread_pointer"
+ [(set (reg:SI GBR_REG)
+ (unspec_volatile:SI [(match_operand:SI 0 "register_operand")]
+ UNSPECV_GBR))]
+ "TARGET_SH1")
+
+(define_insn "load_gbr"
+ [(set (reg:SI GBR_REG)
+ (unspec_volatile:SI [(match_operand:SI 0 "register_operand" "r")]
+ UNSPECV_GBR))]
+ "TARGET_SH1"
+ "ldc %0,gbr"
+ [(set_attr "type" "move")])
+
+;;------------------------------------------------------------------------------
;; case instruction for switch statements.
;; Operand 0 is index
@@ -10460,6 +10485,13 @@ label:
""
{
sh_expand_epilogue (false);
+ if (TARGET_SHMEDIA
+ || (TARGET_SHCOMPACT
+ && (crtl->args.info.call_cookie & CALL_COOKIE_RET_TRAMP (1))))
+ {
+ emit_jump_insn (gen_return ());
+ DONE;
+ }
})
(define_expand "eh_return"
@@ -10769,6 +10801,51 @@ label:
(set (reg:SI T_REG) (const_int 1))
(use (match_dup 2))])])
+;; Use negc to store the T bit in a MSB of a reg in the following way:
+;; T = 1: 0x80000000 -> reg
+;; T = 0: 0x7FFFFFFF -> reg
+;; This works because 0 - 0x80000000 = 0x80000000.
+(define_insn_and_split "*mov_t_msb_neg"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (minus:SI (const_int -2147483648) ;; 0x80000000
+ (match_operand 1 "t_reg_operand")))
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH1"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(set (match_dup 2) (const_int -2147483648))
+ (parallel [(set (match_dup 0) (minus:SI (neg:SI (match_dup 2))
+ (reg:SI T_REG)))
+ (clobber (reg:SI T_REG))])]
+{
+ operands[2] = gen_reg_rtx (SImode);
+})
+
+;; These are essentially the same as above, but with the inverted T bit.
+;; Combine recognizes the split patterns, but does not take them sometimes
+;; if the T_REG clobber is specified. Instead it tries to split out the
+;; T bit negation. Since these splits are supposed to be taken only by
+;; combine, it will see the T_REG clobber of the *mov_t_msb_neg insn, so this
+;; should be fine.
+(define_split
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (plus:SI (match_operand 1 "negt_reg_operand")
+ (const_int 2147483647)))] ;; 0x7fffffff
+ "TARGET_SH1 && can_create_pseudo_p ()"
+ [(parallel [(set (match_dup 0)
+ (minus:SI (const_int -2147483648) (reg:SI T_REG)))
+ (clobber (reg:SI T_REG))])])
+
+(define_split
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (if_then_else:SI (match_operand 1 "t_reg_operand")
+ (const_int 2147483647) ;; 0x7fffffff
+ (const_int -2147483648)))] ;; 0x80000000
+ "TARGET_SH1 && can_create_pseudo_p ()"
+ [(parallel [(set (match_dup 0)
+ (minus:SI (const_int -2147483648) (reg:SI T_REG)))
+ (clobber (reg:SI T_REG))])])
+
;; The *negnegt pattern helps the combine pass to figure out how to fold
;; an explicit double T bit negation.
(define_insn_and_split "*negnegt"
diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt
index cb0181061..df9df6d3e 100644
--- a/gcc/config/sh/sh.opt
+++ b/gcc/config/sh/sh.opt
@@ -320,12 +320,12 @@ Target Mask(HITACHI)
Follow Renesas (formerly Hitachi) / SuperH calling conventions
msoft-atomic
-Target Report Var(TARGET_SOFT_ATOMIC)
-Use gUSA software atomic sequences
+Target Undocumented Alias(matomic-model=, soft-gusa, none)
+Deprecated. Use -matomic= instead to select the atomic model
-mhard-atomic
-Target Report Var(TARGET_HARD_ATOMIC)
-Use hardware atomic sequences
+matomic-model=
+Target Report RejectNegative Joined Var(sh_atomic_model_str)
+Specify the model for atomic operations
mtas
Target Report RejectNegative Var(TARGET_ENABLE_TAS)
diff --git a/gcc/config/sh/sync.md b/gcc/config/sh/sync.md
index aa87c57c7..6cd982c79 100644
--- a/gcc/config/sh/sync.md
+++ b/gcc/config/sh/sync.md
@@ -22,9 +22,12 @@
;; Atomic integer operations for the Renesas / SuperH SH CPUs.
;;
;; On SH CPUs atomic integer operations can be done either in 'software' or
-;; in 'hardware', where true hardware support was introduced with the SH4A.
-;; In addition to that all SH CPUs support the 'tas.b' instruction, which
-;; can be optionally used to implement the 'atomic_test_and_set' builtin.
+;; in 'hardware' in various styles. True hardware support was introduced
+;; with the SH4A. Some SH2A dual-core models (e.g. SH7205) also come with
+;; 'semaphore' hardware registers, but these are currently unsupported.
+;; All SH CPUs support the 'tas.b' instruction, which can be optionally used
+;; to implement the 'atomic_test_and_set' builtin.
+;; The following atomic options and models are supported.
;;
;; tas.b atomic_test_and_set (-mtas)
;;
@@ -37,7 +40,7 @@
;; other atomic operations.
;;
;;
-;; Hardware Atomics (-mhard-atomic, SH4A only)
+;; Hardware Atomics (-matomic-model=hard-llcs; SH4A only)
;;
;; Hardware atomics implement all atomic operations using the 'movli.l' and
;; 'movco.l' instructions that are availble on SH4A. On multi-core hardware
@@ -48,7 +51,7 @@
;; larger code.
;;
;;
-;; Software Atomics (-msoft-atomic)
+;; gUSA Software Atomics (-matomic-model=soft-gusa; SH3*, SH4* only)
;;
;; On single-core systems there can only be one execution context running
;; at a given point in time. This allows the usage of rewindable atomic
@@ -68,9 +71,8 @@
;; interrupted_pc = atomic_entrypoint;
;;
;; This method is also known as gUSA ("g" User Space Atomicity) and the
-;; Linux kernel for SH3/SH4 implements support for such software
-;; atomic sequences. However, it can also be implemented in freestanding
-;; environments.
+;; Linux kernel for SH3/SH4 implements support for such software atomic
+;; sequences. It can also be implemented in freestanding environments.
;;
;; For this the following atomic sequence ABI is used.
;;
@@ -111,16 +113,72 @@
;; For correct operation the atomic sequences must not be rewound after
;; they have passed the write-back instruction.
;;
+;; This is model works only on SH3* and SH4* because the stack pointer (r15)
+;; is set to an invalid pointer temporarily. SH1* and SH2* CPUs will try
+;; to push SR and PC registers on the stack when an interrupt / exception
+;; occurs, and thus require the stack pointer (r15) always to be valid.
+;;
+;;
+;; TCB Software Atomics (-matomic-model=soft-tcb)
+;;
+;; This model is a variation of the gUSA model. The concept of rewindable
+;; atomic sequences is the same, but it does not use the stack pointer (r15)
+;; for signaling the 'is in atomic sequence' condition. Instead, a variable
+;; in the thread control block (TCB) is set to hold the exit point of the
+;; atomic sequence. This assumes that the GBR is used as a thread pointer
+;; register. The offset of the variable in the TCB to be used must be
+;; specified with an additional option 'gbr-offset', such as:
+;; -matomic-model=soft-tcb,gbr-offset=4
+;;
+;; For this model the following atomic sequence ABI is used.
+;;
+;; @(#x,gbr) == 0: Execution context is not in an atomic sequence.
+;;
+;; @(#x,gbr) != 0: Execution context is in an atomic sequence. In this
+;; case the following applies:
+;;
+;; @(#x,gbr): PC of the first instruction after the atomic
+;; write-back instruction (exit point).
+;;
+;; r1: Negative byte length of the atomic sequence.
+;; The entry point PC of the sequence can be
+;; determined by doing @(#x,gbr) + r1
+;;
+;; Note: #x is the user specified gbr-offset.
+;;
+;;
+;; Interrupt-Flipping Software Atomics (-matomic-model=soft-imask)
+;;
+;; This model achieves atomicity by temporarily disabling interrupts for
+;; the duration of the atomic sequence. This works only when the program
+;; runs in privileged mode but does not require any support from the
+;; interrupt / exception handling code. There is no particular ABI.
+;; To disable interrupts the SR.IMASK bits are set to '1111'.
+;; This method is not as efficient as the other software atomic models,
+;; since loading and storing SR (in order to flip interrupts on / off)
+;; requires using multi-cycle instructions. Moreover, it can potentially
+;; increase the interrupt latency which might be important for hard-realtime
+;; applications.
+;;
+;;
+;; Compatibility Notes
+;;
+;; On single-core SH4A CPUs software atomic aware interrupt / exception code
+;; is actually compatible with user code that utilizes hardware atomics.
+;; Since SImode hardware atomic sequences are more compact on SH4A they are
+;; always used, regardless of the selected atomic model. This atomic model
+;; mixing can be disabled by setting the 'strict' flag, like:
+;; -matomic-model=soft-gusa,strict
+;;
+;; The software atomic models are generally compatible with each other,
+;; but the interrupt / exception handling code has to support both gUSA and
+;; TCB models.
+;;
;; The current atomic support is limited to QImode, HImode and SImode
;; atomic operations. DImode operations could also be implemented but
;; would require some ABI modifications to support multiple-instruction
;; write-back. This is because SH1/SH2/SH3/SH4 does not have a DImode
;; store instruction. DImode stores must be split into two SImode stores.
-;;
-;; On single-core SH4A CPUs software atomic aware interrupt / exception code
-;; is actually compatible with user code that utilizes hardware atomics.
-;; Since SImode hardware atomic sequences are more compact on SH4A they are
-;; always used, regardless of the selected atomic mode.
(define_c_enum "unspec" [
UNSPEC_ATOMIC
@@ -158,7 +216,7 @@
(match_operand:SI 5 "const_int_operand" "") ;; is_weak
(match_operand:SI 6 "const_int_operand" "") ;; success model
(match_operand:SI 7 "const_int_operand" "")] ;; failure model
- "TARGET_ANY_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_ANY"
{
rtx addr = force_reg (Pmode, XEXP (operands[2], 0));
rtx old_val = gen_lowpart (SImode, operands[1]);
@@ -166,12 +224,22 @@
rtx new_val = operands[4];
rtx atomic_insn;
- if (TARGET_HARD_ATOMIC || (TARGET_SH4A_ARCH && <MODE>mode == SImode))
+ if (TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && <MODE>mode == SImode && !TARGET_ATOMIC_STRICT))
atomic_insn = gen_atomic_compare_and_swap<mode>_hard (old_val, addr,
exp_val, new_val);
+ else if (TARGET_ATOMIC_SOFT_GUSA)
+ atomic_insn = gen_atomic_compare_and_swap<mode>_soft_gusa (old_val, addr,
+ exp_val, new_val);
+ else if (TARGET_ATOMIC_SOFT_TCB)
+ atomic_insn = gen_atomic_compare_and_swap<mode>_soft_tcb (old_val, addr,
+ exp_val, new_val, TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX);
+ else if (TARGET_ATOMIC_SOFT_IMASK)
+ atomic_insn = gen_atomic_compare_and_swap<mode>_soft_imask (old_val, addr,
+ exp_val, new_val);
else
- atomic_insn = gen_atomic_compare_and_swap<mode>_soft (old_val, addr,
- exp_val, new_val);
+ FAIL;
+
emit_insn (atomic_insn);
if (<MODE>mode == QImode)
@@ -196,7 +264,8 @@
(set (reg:SI T_REG)
(unspec_volatile:SI [(const_int 0)] UNSPECV_CMPXCHG_3))
(clobber (reg:SI R0_REG))]
- "TARGET_ANY_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)"
{
return "\r0: movli.l @%1,r0" "\n"
" cmp/eq %2,r0" "\n"
@@ -224,7 +293,7 @@
(clobber (match_scratch:SI 4 "=&r"))
(clobber (match_scratch:SI 5 "=&r"))
(clobber (match_scratch:SI 6 "=1"))]
- "TARGET_HARD_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%5" "\n"
" <i124extend_insn> %2,%4" "\n"
@@ -245,7 +314,7 @@
}
[(set_attr "length" "30")])
-(define_insn "atomic_compare_and_swap<mode>_soft"
+(define_insn "atomic_compare_and_swap<mode>_soft_gusa"
[(set (match_operand:SI 0 "register_operand" "=&u")
(unspec_volatile:SI
[(mem:QIHISI (match_operand:SI 1 "register_operand" "u"))
@@ -259,7 +328,7 @@
(clobber (match_scratch:SI 4 "=&u"))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
- "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_SOFT_GUSA"
{
return "\r mova 1f,r0" "\n"
" <i124extend_insn> %2,%4" "\n"
@@ -274,6 +343,86 @@
}
[(set_attr "length" "20")])
+(define_insn "atomic_compare_and_swap<mode>_soft_tcb"
+ [(set (match_operand:SI 0 "register_operand" "=&r")
+ (unspec_volatile:SI
+ [(mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:QIHISI 2 "register_operand" "r")
+ (match_operand:QIHISI 3 "register_operand" "r")]
+ UNSPECV_CMPXCHG_1))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec_volatile:QIHISI [(const_int 0)] UNSPECV_CMPXCHG_2))
+ (set (reg:SI T_REG)
+ (unspec_volatile:SI [(const_int 0)] UNSPECV_CMPXCHG_3))
+ (use (match_operand:SI 4 "gbr_displacement"))
+ (clobber (match_scratch:SI 5 "=&r"))
+ (clobber (reg:SI R0_REG))
+ (clobber (reg:SI R1_REG))]
+ "TARGET_ATOMIC_SOFT_TCB"
+{
+ return "\r mova 1f,r0" "\n"
+ " .align 2" "\n"
+ " <i124extend_insn> %2,%5" "\n"
+ " mov #(0f-1f),r1" "\n"
+ " mov.l r0,@(%O4,gbr)" "\n"
+ "0: mov.<bwl> @%1,%0" "\n"
+ " mov #0,r0" "\n"
+ " cmp/eq %0,%5" "\n"
+ " bf 1f" "\n"
+ " mov.<bwl> %3,@%1" "\n"
+ "1: mov.l r0,@(%O4,gbr)";
+}
+ [(set_attr "length" "22")])
+
+(define_insn "atomic_compare_and_swap<mode>_soft_imask"
+ [(set (match_operand:SI 0 "register_operand" "=&z")
+ (unspec_volatile:SI
+ [(mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:QIHISI 2 "register_operand" "r")
+ (match_operand:QIHISI 3 "register_operand" "r")]
+ UNSPECV_CMPXCHG_1))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec_volatile:QIHISI [(const_int 0)] UNSPECV_CMPXCHG_2))
+ (set (reg:SI T_REG)
+ (unspec_volatile:SI [(const_int 0)] UNSPECV_CMPXCHG_3))
+ (clobber (match_scratch:SI 4 "=&r"))
+ (clobber (match_scratch:SI 5 "=&r"))]
+ "TARGET_ATOMIC_SOFT_IMASK"
+{
+ /* The comparison result is supposed to be in T_REG.
+ Notice that restoring SR will overwrite the T_REG. We handle this by
+ rotating the T_REG into the saved SR before restoring SR. On SH2A we
+ can do one insn shorter by using the bst insn. */
+ if (!TARGET_SH2A)
+ return "\r stc sr,%0" "\n"
+ " <i124extend_insn> %2,%4" "\n"
+ " mov %0,%5" "\n"
+ " or #0xF0,%0" "\n"
+ " shlr %5" "\n"
+ " ldc %0,sr" "\n"
+ " mov.<bwl> @%1,%0" "\n"
+ " cmp/eq %4,%0" "\n"
+ " bf 1f" "\n"
+ " mov.<bwl> %3,@%1" "\n"
+ "1: rotcl %5" "\n"
+ " ldc %5,sr";
+ else
+ return "\r stc sr,%0" "\n"
+ " <i124extend_insn> %2,%4" "\n"
+ " mov %0,%5" "\n"
+ " or #0xF0,%0" "\n"
+ " ldc %0,sr" "\n"
+ " mov.<bwl> @%1,%0" "\n"
+ " cmp/eq %4,%0" "\n"
+ " bst #0,%5" "\n"
+ " bf 1f" "\n"
+ " mov.<bwl> %3,@%1" "\n"
+ "1: ldc %5,sr";
+}
+ [(set (attr "length") (if_then_else (match_test "!TARGET_SH2A")
+ (const_string "24")
+ (const_string "22")))])
+
;;------------------------------------------------------------------------------
;; read - write - return old value
@@ -282,16 +431,24 @@
(match_operand:QIHISI 1 "memory_operand" "") ;; memory
(match_operand:QIHISI 2 "atomic_arith_operand" "") ;; newval input
(match_operand:SI 3 "const_int_operand" "")] ;; memory model
- "TARGET_ANY_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_ANY"
{
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
rtx val = operands[2];
rtx atomic_insn;
- if (TARGET_HARD_ATOMIC || (TARGET_SH4A_ARCH && <MODE>mode == SImode))
+ if (TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && <MODE>mode == SImode && !TARGET_ATOMIC_STRICT))
atomic_insn = gen_atomic_exchange<mode>_hard (operands[0], addr, val);
+ else if (TARGET_ATOMIC_SOFT_GUSA)
+ atomic_insn = gen_atomic_exchange<mode>_soft_gusa (operands[0], addr, val);
+ else if (TARGET_ATOMIC_SOFT_TCB)
+ atomic_insn = gen_atomic_exchange<mode>_soft_tcb (operands[0], addr, val,
+ TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX);
+ else if (TARGET_ATOMIC_SOFT_IMASK)
+ atomic_insn = gen_atomic_exchange<mode>_soft_imask (operands[0], addr, val);
else
- atomic_insn = gen_atomic_exchange<mode>_soft (operands[0], addr, val);
+ FAIL;
emit_insn (atomic_insn);
@@ -311,7 +468,8 @@
(unspec:SI
[(match_operand:SI 2 "arith_operand" "rI08")] UNSPEC_ATOMIC))
(clobber (reg:SI R0_REG))]
- "TARGET_ANY_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)"
{
return "\r0: movli.l @%1,r0" "\n"
" mov r0,%0" "\n"
@@ -330,7 +488,7 @@
(clobber (reg:SI R0_REG))
(clobber (match_scratch:SI 3 "=&r"))
(clobber (match_scratch:SI 4 "=1"))]
- "TARGET_HARD_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%3" "\n"
" and %1,%3" "\n"
@@ -347,7 +505,7 @@
}
[(set_attr "length" "24")])
-(define_insn "atomic_exchange<mode>_soft"
+(define_insn "atomic_exchange<mode>_soft_gusa"
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
(mem:QIHISI (match_operand:SI 1 "register_operand" "u")))
(set (mem:QIHISI (match_dup 1))
@@ -355,7 +513,7 @@
[(match_operand:QIHISI 2 "register_operand" "u")] UNSPEC_ATOMIC))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
- "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_SOFT_GUSA"
{
return "\r mova 1f,r0" "\n"
" .align 2" "\n"
@@ -367,6 +525,47 @@
}
[(set_attr "length" "14")])
+(define_insn "atomic_exchange<mode>_soft_tcb"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&r")
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(match_operand:QIHISI 2 "register_operand" "r")] UNSPEC_ATOMIC))
+ (clobber (reg:SI R0_REG))
+ (clobber (reg:SI R1_REG))
+ (use (match_operand:SI 3 "gbr_displacement"))]
+ "TARGET_ATOMIC_SOFT_TCB"
+{
+ return "\r mova 1f,r0" "\n"
+ " mov #(0f-1f),r1" "\n"
+ " .align 2" "\n"
+ " mov.l r0,@(%O3,gbr)" "\n"
+ "0: mov.<bwl> @%1,%0" "\n"
+ " mov #0,r0" "\n"
+ " mov.<bwl> %2,@%1" "\n"
+ "1: mov.l r0,@(%O3,gbr)";
+}
+ [(set_attr "length" "16")])
+
+(define_insn "atomic_exchange<mode>_soft_imask"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&z")
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(match_operand:QIHISI 2 "register_operand" "r")] UNSPEC_ATOMIC))
+ (clobber (match_scratch:SI 3 "=&r"))]
+ "TARGET_ATOMIC_SOFT_IMASK"
+{
+ return "\r stc sr,%0" "\n"
+ " mov %0,%3" "\n"
+ " or #0xF0,%0" "\n"
+ " ldc %0,sr" "\n"
+ " mov.<bwl> @%1,%0" "\n"
+ " mov.<bwl> %2,@%1" "\n"
+ " ldc %3,sr";
+}
+ [(set_attr "length" "14")])
+
;;------------------------------------------------------------------------------
;; read - add|sub|or|and|xor|nand - write - return old value
@@ -379,18 +578,27 @@
(match_operand:QIHISI 2 "<fetchop_predicate>" ""))]
UNSPEC_ATOMIC))
(match_operand:SI 3 "const_int_operand" "")]
- "TARGET_ANY_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_ANY"
{
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
rtx atomic_insn;
- if (TARGET_HARD_ATOMIC || (TARGET_SH4A_ARCH && <MODE>mode == SImode))
+ if (TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && <MODE>mode == SImode && !TARGET_ATOMIC_STRICT))
atomic_insn = gen_atomic_fetch_<fetchop_name><mode>_hard (operands[0], addr,
operands[2]);
+ else if (TARGET_ATOMIC_SOFT_GUSA)
+ atomic_insn = gen_atomic_fetch_<fetchop_name><mode>_soft_gusa (operands[0],
+ addr, operands[2]);
+ else if (TARGET_ATOMIC_SOFT_TCB)
+ atomic_insn = gen_atomic_fetch_<fetchop_name><mode>_soft_tcb (operands[0],
+ addr, operands[2], TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX);
+ else if (TARGET_ATOMIC_SOFT_IMASK)
+ atomic_insn = gen_atomic_fetch_<fetchop_name><mode>_soft_imask (operands[0],
+ addr, operands[2]);
else
- atomic_insn = gen_atomic_fetch_<fetchop_name><mode>_soft (operands[0],
- addr,
- operands[2]);
+ FAIL;
+
emit_insn (atomic_insn);
if (<MODE>mode == QImode)
@@ -411,7 +619,8 @@
(match_operand:SI 2 "<fetchop_predicate>" "<fetchop_constraint>"))]
UNSPEC_ATOMIC))
(clobber (reg:SI R0_REG))]
- "TARGET_ANY_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)"
{
return "\r0: movli.l @%1,r0" "\n"
" mov r0,%0" "\n"
@@ -432,7 +641,7 @@
(clobber (reg:SI R0_REG))
(clobber (match_scratch:SI 3 "=&r"))
(clobber (match_scratch:SI 4 "=1"))]
- "TARGET_HARD_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%3" "\n"
" and %1,%3" "\n"
@@ -451,7 +660,7 @@
}
[(set_attr "length" "28")])
-(define_insn "atomic_fetch_<fetchop_name><mode>_soft"
+(define_insn "atomic_fetch_<fetchop_name><mode>_soft_gusa"
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
(mem:QIHISI (match_operand:SI 1 "register_operand" "u")))
(set (mem:QIHISI (match_dup 1))
@@ -462,7 +671,7 @@
(clobber (match_scratch:QIHISI 3 "=&u"))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
- "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_SOFT_GUSA"
{
return "\r mova 1f,r0" "\n"
" .align 2" "\n"
@@ -476,6 +685,57 @@
}
[(set_attr "length" "18")])
+(define_insn "atomic_fetch_<fetchop_name><mode>_soft_tcb"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&r")
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(FETCHOP:QIHISI (mem:QIHISI (match_dup 1))
+ (match_operand:QIHISI 2 "register_operand" "r"))]
+ UNSPEC_ATOMIC))
+ (use (match_operand:SI 3 "gbr_displacement"))
+ (clobber (match_scratch:QIHISI 4 "=&r"))
+ (clobber (reg:SI R0_REG))
+ (clobber (reg:SI R1_REG))]
+ "TARGET_ATOMIC_SOFT_TCB"
+{
+ return "\r mova 1f,r0" "\n"
+ " mov #(0f-1f),r1" "\n"
+ " .align 2" "\n"
+ " mov.l r0,@(%O3,gbr)" "\n"
+ "0: mov.<bwl> @%1,%0" "\n"
+ " mov #0,r0" "\n"
+ " mov %0,%4" "\n"
+ " <fetchop_name> %2,%4" "\n"
+ " mov.<bwl> %4,@%1" "\n"
+ "1: mov.l r0,@(%O3,gbr)";
+}
+ [(set_attr "length" "20")])
+
+(define_insn "atomic_fetch_<fetchop_name><mode>_soft_imask"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&z")
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(FETCHOP:QIHISI (mem:QIHISI (match_dup 1))
+ (match_operand:QIHISI 2 "register_operand" "r"))]
+ UNSPEC_ATOMIC))
+ (clobber (match_scratch:QIHISI 3 "=&r"))
+ (clobber (match_scratch:SI 4 "=&r"))]
+ "TARGET_ATOMIC_SOFT_IMASK"
+{
+ return "\r stc sr,%0" "\n"
+ " mov %0,%4" "\n"
+ " or #0xF0,%0" "\n"
+ " ldc %0,sr" "\n"
+ " mov.<bwl> @%1,%0" "\n"
+ " mov %0,%3" "\n"
+ " <fetchop_name> %2,%3" "\n"
+ " mov.<bwl> %3,@%1" "\n"
+ " ldc %4,sr";
+}
+ [(set_attr "length" "18")])
+
(define_expand "atomic_fetch_nand<mode>"
[(set (match_operand:QIHISI 0 "register_operand" "")
(match_operand:QIHISI 1 "memory_operand" ""))
@@ -485,17 +745,26 @@
(match_operand:QIHISI 2 "atomic_logical_operand" "")))]
UNSPEC_ATOMIC))
(match_operand:SI 3 "const_int_operand" "")]
- "TARGET_ANY_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_ANY"
{
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
rtx atomic_insn;
- if (TARGET_HARD_ATOMIC || (TARGET_SH4A_ARCH && <MODE>mode == SImode))
+ if (TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && <MODE>mode == SImode && !TARGET_ATOMIC_STRICT))
atomic_insn = gen_atomic_fetch_nand<mode>_hard (operands[0], addr,
operands[2]);
+ else if (TARGET_ATOMIC_SOFT_GUSA)
+ atomic_insn = gen_atomic_fetch_nand<mode>_soft_gusa (operands[0], addr,
+ operands[2]);
+ else if (TARGET_ATOMIC_SOFT_TCB)
+ atomic_insn = gen_atomic_fetch_nand<mode>_soft_tcb (operands[0], addr,
+ operands[2], TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX);
+ else if (TARGET_ATOMIC_SOFT_IMASK)
+ atomic_insn = gen_atomic_fetch_nand<mode>_soft_imask (operands[0], addr,
+ operands[2]);
else
- atomic_insn = gen_atomic_fetch_nand<mode>_soft (operands[0], addr,
- operands[2]);
+ FAIL;
emit_insn (atomic_insn);
@@ -517,7 +786,8 @@
(match_operand:SI 2 "logical_operand" "rK08")))]
UNSPEC_ATOMIC))
(clobber (reg:SI R0_REG))]
- "TARGET_ANY_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)"
{
return "\r0: movli.l @%1,r0" "\n"
" mov r0,%0" "\n"
@@ -539,7 +809,7 @@
(clobber (reg:SI R0_REG))
(clobber (match_scratch:SI 3 "=&r"))
(clobber (match_scratch:SI 4 "=1"))]
- "TARGET_HARD_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%3" "\n"
" and %1,%3" "\n"
@@ -559,7 +829,7 @@
}
[(set_attr "length" "30")])
-(define_insn "atomic_fetch_nand<mode>_soft"
+(define_insn "atomic_fetch_nand<mode>_soft_gusa"
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
(mem:QIHISI (match_operand:SI 1 "register_operand" "u")))
(set (mem:QIHISI (match_dup 1))
@@ -570,7 +840,7 @@
(clobber (match_scratch:QIHISI 3 "=&u"))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
- "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_SOFT_GUSA"
{
return "\r mova 1f,r0" "\n"
" mov r15,r1" "\n"
@@ -585,6 +855,59 @@
}
[(set_attr "length" "20")])
+(define_insn "atomic_fetch_nand<mode>_soft_tcb"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&r")
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1))
+ (match_operand:QIHISI 2 "register_operand" "r")))]
+ UNSPEC_ATOMIC))
+ (use (match_operand:SI 3 "gbr_displacement"))
+ (clobber (match_scratch:QIHISI 4 "=&r"))
+ (clobber (reg:SI R0_REG))
+ (clobber (reg:SI R1_REG))]
+ "TARGET_ATOMIC_SOFT_TCB"
+{
+ return "\r mova 1f,r0" "\n"
+ " .align 2" "\n"
+ " mov #(0f-1f),r1" "\n"
+ " mov.l r0,@(%O3,gbr)" "\n"
+ "0: mov.<bwl> @%1,%0" "\n"
+ " mov #0,r0" "\n"
+ " mov %2,%4" "\n"
+ " and %0,%4" "\n"
+ " not %4,%4" "\n"
+ " mov.<bwl> %4,@%1" "\n"
+ "1: mov.l r0,@(%O3,gbr)";
+}
+ [(set_attr "length" "22")])
+
+(define_insn "atomic_fetch_nand<mode>_soft_imask"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&z")
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r")))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1))
+ (match_operand:QIHISI 2 "register_operand" "r")))]
+ UNSPEC_ATOMIC))
+ (clobber (match_scratch:QIHISI 3 "=&r"))
+ (clobber (match_scratch:SI 4 "=&r"))]
+ "TARGET_ATOMIC_SOFT_IMASK"
+{
+ return "\r stc sr,%0" "\n"
+ " mov %0,%4" "\n"
+ " or #0xF0,%0" "\n"
+ " ldc %0,sr" "\n"
+ " mov.<bwl> @%1,%0" "\n"
+ " mov %2,%3" "\n"
+ " and %0,%3" "\n"
+ " not %3,%3" "\n"
+ " mov.<bwl> %3,@%1" "\n"
+ " stc %4,sr";
+}
+ [(set_attr "length" "20")])
+
;;------------------------------------------------------------------------------
;; read - add|sub|or|and|xor|nand - write - return new value
@@ -598,17 +921,27 @@
[(FETCHOP:QIHISI (match_dup 1) (match_dup 2))]
UNSPEC_ATOMIC))
(match_operand:SI 3 "const_int_operand" "")]
- "TARGET_ANY_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_ANY"
{
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
rtx atomic_insn;
- if (TARGET_HARD_ATOMIC || (TARGET_SH4A_ARCH && <MODE>mode == SImode))
+ if (TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && <MODE>mode == SImode && !TARGET_ATOMIC_STRICT))
atomic_insn = gen_atomic_<fetchop_name>_fetch<mode>_hard (operands[0], addr,
operands[2]);
+ else if (TARGET_ATOMIC_SOFT_GUSA)
+ atomic_insn = gen_atomic_<fetchop_name>_fetch<mode>_soft_gusa (operands[0],
+ addr, operands[2]);
+ else if (TARGET_ATOMIC_SOFT_TCB)
+ atomic_insn = gen_atomic_<fetchop_name>_fetch<mode>_soft_tcb (operands[0],
+ addr, operands[2], TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX);
+ else if (TARGET_ATOMIC_SOFT_IMASK)
+ atomic_insn = gen_atomic_<fetchop_name>_fetch<mode>_soft_imask (operands[0],
+ addr, operands[2]);
else
- atomic_insn = gen_atomic_<fetchop_name>_fetch<mode>_soft (operands[0], addr,
- operands[2]);
+ FAIL;
+
emit_insn (atomic_insn);
if (<MODE>mode == QImode)
@@ -629,7 +962,8 @@
(unspec:SI
[(FETCHOP:SI (mem:SI (match_dup 1)) (match_dup 2))]
UNSPEC_ATOMIC))]
- "TARGET_ANY_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)"
{
return "\r0: movli.l @%1,%0" "\n"
" <fetchop_name> %2,%0" "\n"
@@ -647,11 +981,10 @@
(unspec:QIHI
[(FETCHOP:QIHI (mem:QIHI (match_dup 1)) (match_dup 2))]
UNSPEC_ATOMIC))
-
(clobber (reg:SI R0_REG))
(clobber (match_scratch:SI 3 "=&r"))
(clobber (match_scratch:SI 4 "=1"))]
- "TARGET_HARD_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%3" "\n"
" and %1,%3" "\n"
@@ -670,7 +1003,7 @@
}
[(set_attr "length" "28")])
-(define_insn "atomic_<fetchop_name>_fetch<mode>_soft"
+(define_insn "atomic_<fetchop_name>_fetch<mode>_soft_gusa"
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
(FETCHOP:QIHISI
(mem:QIHISI (match_operand:SI 1 "register_operand" "u"))
@@ -681,7 +1014,7 @@
UNSPEC_ATOMIC))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
- "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_SOFT_GUSA"
{
return "\r mova 1f,r0" "\n"
" mov r15,r1" "\n"
@@ -694,6 +1027,55 @@
}
[(set_attr "length" "16")])
+(define_insn "atomic_<fetchop_name>_fetch<mode>_soft_tcb"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&r")
+ (FETCHOP:QIHISI
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:QIHISI 2 "register_operand" "r")))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(FETCHOP:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2))]
+ UNSPEC_ATOMIC))
+ (clobber (reg:SI R0_REG))
+ (clobber (reg:SI R1_REG))
+ (use (match_operand:SI 3 "gbr_displacement"))]
+ "TARGET_ATOMIC_SOFT_TCB"
+{
+ return "\r mova 1f,r0" "\n"
+ " .align 2" "\n"
+ " mov #(0f-1f),r1" "\n"
+ " mov.l r0,@(%O3,gbr)" "\n"
+ "0: mov.<bwl> @%1,%0" "\n"
+ " mov #0,r0" "\n"
+ " <fetchop_name> %2,%0" "\n"
+ " mov.<bwl> %0,@%1" "\n"
+ "1: mov.l r0,@(%O3,gbr)";
+}
+ [(set_attr "length" "18")])
+
+(define_insn "atomic_<fetchop_name>_fetch<mode>_soft_imask"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&z")
+ (FETCHOP:QIHISI
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:QIHISI 2 "register_operand" "r")))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(FETCHOP:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2))]
+ UNSPEC_ATOMIC))
+ (clobber (match_scratch:SI 3 "=&r"))]
+ "TARGET_ATOMIC_SOFT_IMASK"
+{
+ return "\r stc sr,%0" "\n"
+ " mov %0,%3" "\n"
+ " or #0xF0,%0" "\n"
+ " ldc %0,sr" "\n"
+ " mov.<bwl> @%1,%0" "\n"
+ " <fetchop_name> %2,%0" "\n"
+ " mov.<bwl> %0,@%1" "\n"
+ " ldc %3,sr";
+}
+ [(set_attr "length" "16")])
+
(define_expand "atomic_nand_fetch<mode>"
[(set (match_operand:QIHISI 0 "register_operand" "")
(not:QIHISI (and:QIHISI
@@ -704,17 +1086,27 @@
[(not:QIHISI (and:QIHISI (match_dup 1) (match_dup 2)))]
UNSPEC_ATOMIC))
(match_operand:SI 3 "const_int_operand" "")]
- "TARGET_ANY_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_ANY"
{
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
rtx atomic_insn;
- if (TARGET_HARD_ATOMIC || (TARGET_SH4A_ARCH && <MODE>mode == SImode))
+ if (TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && <MODE>mode == SImode && !TARGET_ATOMIC_STRICT))
atomic_insn = gen_atomic_nand_fetch<mode>_hard (operands[0], addr,
operands[2]);
+ else if (TARGET_ATOMIC_SOFT_GUSA)
+ atomic_insn = gen_atomic_nand_fetch<mode>_soft_gusa (operands[0], addr,
+ operands[2]);
+ else if (TARGET_ATOMIC_SOFT_TCB)
+ atomic_insn = gen_atomic_nand_fetch<mode>_soft_tcb (operands[0], addr,
+ operands[2], TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX);
+ else if (TARGET_ATOMIC_SOFT_IMASK)
+ atomic_insn = gen_atomic_nand_fetch<mode>_soft_imask (operands[0], addr,
+ operands[2]);
else
- atomic_insn = gen_atomic_nand_fetch<mode>_soft (operands[0], addr,
- operands[2]);
+ FAIL;
+
emit_insn (atomic_insn);
if (<MODE>mode == QImode)
@@ -734,7 +1126,8 @@
(unspec:SI
[(not:SI (and:SI (mem:SI (match_dup 1)) (match_dup 2)))]
UNSPEC_ATOMIC))]
- "TARGET_ANY_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS
+ || (TARGET_SH4A_ARCH && TARGET_ATOMIC_ANY && !TARGET_ATOMIC_STRICT)"
{
return "\r0: movli.l @%1,%0" "\n"
" and %2,%0" "\n"
@@ -756,7 +1149,7 @@
(clobber (reg:SI R0_REG))
(clobber (match_scratch:SI 3 "=&r"))
(clobber (match_scratch:SI 4 "=1"))]
- "TARGET_HARD_ATOMIC && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS"
{
return "\r mov #-4,%3" "\n"
" and %1,%3" "\n"
@@ -775,7 +1168,7 @@
}
[(set_attr "length" "28")])
-(define_insn "atomic_nand_fetch<mode>_soft"
+(define_insn "atomic_nand_fetch<mode>_soft_gusa"
[(set (match_operand:QIHISI 0 "register_operand" "=&u")
(not:QIHISI (and:QIHISI
(mem:QIHISI (match_operand:SI 1 "register_operand" "u"))
@@ -786,7 +1179,7 @@
UNSPEC_ATOMIC))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
- "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_SOFT_GUSA"
{
return "\r mova 1f,r0" "\n"
" .align 2" "\n"
@@ -800,6 +1193,57 @@
}
[(set_attr "length" "18")])
+(define_insn "atomic_nand_fetch<mode>_soft_tcb"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&r")
+ (not:QIHISI (and:QIHISI
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:QIHISI 2 "register_operand" "r"))))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2)))]
+ UNSPEC_ATOMIC))
+ (clobber (reg:SI R0_REG))
+ (clobber (reg:SI R1_REG))
+ (use (match_operand:SI 3 "gbr_displacement"))]
+ "TARGET_ATOMIC_SOFT_TCB"
+{
+ return "\r mova 1f,r0" "\n"
+ " mov #(0f-1f),r1" "\n"
+ " .align 2" "\n"
+ " mov.l r0,@(%O3,gbr)" "\n"
+ "0: mov.<bwl> @%1,%0" "\n"
+ " mov #0,r0" "\n"
+ " and %2,%0" "\n"
+ " not %0,%0" "\n"
+ " mov.<bwl> %0,@%1" "\n"
+ "1: mov.l r0,@(%O3,gbr)";
+}
+ [(set_attr "length" "20")])
+
+(define_insn "atomic_nand_fetch<mode>_soft_imask"
+ [(set (match_operand:QIHISI 0 "register_operand" "=&z")
+ (not:QIHISI (and:QIHISI
+ (mem:QIHISI (match_operand:SI 1 "register_operand" "r"))
+ (match_operand:QIHISI 2 "register_operand" "r"))))
+ (set (mem:QIHISI (match_dup 1))
+ (unspec:QIHISI
+ [(not:QIHISI (and:QIHISI (mem:QIHISI (match_dup 1)) (match_dup 2)))]
+ UNSPEC_ATOMIC))
+ (clobber (match_scratch:SI 3 "=&r"))]
+ "TARGET_ATOMIC_SOFT_IMASK"
+{
+ return "\r stc sr,%0" "\n"
+ " mov %0,%3" "\n"
+ " or #0xF0,%0" "\n"
+ " ldc %0,sr" "\n"
+ " mov.<bwl> @%1,%0" "\n"
+ " and %2,%0" "\n"
+ " not %0,%0" "\n"
+ " mov.<bwl> %0,@%1" "\n"
+ " ldc %3,sr";
+}
+ [(set_attr "length" "18")])
+
;;------------------------------------------------------------------------------
;; read - test against zero - or with 0x80 - write - return test result
@@ -807,7 +1251,7 @@
[(match_operand:SI 0 "register_operand" "") ;; bool result output
(match_operand:QI 1 "memory_operand" "") ;; memory
(match_operand:SI 2 "const_int_operand" "")] ;; model
- "(TARGET_ANY_ATOMIC || TARGET_ENABLE_TAS) && !TARGET_SHMEDIA"
+ "(TARGET_ATOMIC_ANY || TARGET_ENABLE_TAS) && !TARGET_SHMEDIA"
{
rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
@@ -818,10 +1262,17 @@
rtx val = gen_int_mode (targetm.atomic_test_and_set_trueval, QImode);
val = force_reg (QImode, val);
- if (TARGET_HARD_ATOMIC)
+ if (TARGET_ATOMIC_HARD_LLCS)
emit_insn (gen_atomic_test_and_set_hard (addr, val));
+ else if (TARGET_ATOMIC_SOFT_GUSA)
+ emit_insn (gen_atomic_test_and_set_soft_gusa (addr, val));
+ else if (TARGET_ATOMIC_SOFT_TCB)
+ emit_insn (gen_atomic_test_and_set_soft_tcb (addr, val,
+ TARGET_ATOMIC_SOFT_TCB_GBR_OFFSET_RTX));
+ else if (TARGET_ATOMIC_SOFT_IMASK)
+ emit_insn (gen_atomic_test_and_set_soft_imask (addr, val));
else
- emit_insn (gen_atomic_test_and_set_soft (addr, val));
+ FAIL;
}
/* The result of the test op is the inverse of what we are
@@ -841,7 +1292,7 @@
"tas.b @%0"
[(set_attr "insn_class" "co_group")])
-(define_insn "atomic_test_and_set_soft"
+(define_insn "atomic_test_and_set_soft_gusa"
[(set (reg:SI T_REG)
(eq:SI (mem:QI (match_operand:SI 0 "register_operand" "u"))
(const_int 0)))
@@ -850,7 +1301,7 @@
(clobber (match_scratch:QI 2 "=&u"))
(clobber (reg:SI R0_REG))
(clobber (reg:SI R1_REG))]
- "TARGET_SOFT_ATOMIC && !TARGET_ENABLE_TAS && !TARGET_SHMEDIA"
+ "TARGET_ATOMIC_SOFT_GUSA && !TARGET_ENABLE_TAS"
{
return "\r mova 1f,r0" "\n"
" .align 2" "\n"
@@ -863,6 +1314,51 @@
}
[(set_attr "length" "16")])
+(define_insn "atomic_test_and_set_soft_tcb"
+ [(set (reg:SI T_REG)
+ (eq:SI (mem:QI (match_operand:SI 0 "register_operand" "r"))
+ (const_int 0)))
+ (set (mem:QI (match_dup 0))
+ (unspec:QI [(match_operand:QI 1 "register_operand" "r")] UNSPEC_ATOMIC))
+ (use (match_operand:SI 2 "gbr_displacement"))
+ (clobber (match_scratch:QI 3 "=&r"))
+ (clobber (reg:SI R0_REG))
+ (clobber (reg:SI R1_REG))]
+ "TARGET_ATOMIC_SOFT_TCB && !TARGET_ENABLE_TAS"
+{
+ return "\r mova 1f,r0" "\n"
+ " mov #(0f-1f),r1" "\n"
+ " .align 2" "\n"
+ " mov.l r0,@(%O2,gbr)" "\n"
+ "0: mov.b @%0,%3" "\n"
+ " mov #0,r0" "\n"
+ " mov.b %1,@%0" "\n"
+ "1: mov.l r0,@(%O2,gbr)" "\n"
+ " tst %3,%3";
+}
+ [(set_attr "length" "18")])
+
+(define_insn "atomic_test_and_set_soft_imask"
+ [(set (reg:SI T_REG)
+ (eq:SI (mem:QI (match_operand:SI 0 "register_operand" "r"))
+ (const_int 0)))
+ (set (mem:QI (match_dup 0))
+ (unspec:QI [(match_operand:QI 1 "register_operand" "r")] UNSPEC_ATOMIC))
+ (clobber (match_scratch:SI 2 "=&r"))
+ (clobber (reg:SI R0_REG))]
+ "TARGET_ATOMIC_SOFT_IMASK && !TARGET_ENABLE_TAS"
+{
+ return "\r stc sr,r0" "\n"
+ " mov r0,%2" "\n"
+ " or #0xF0,r0" "\n"
+ " ldc r0,sr" "\n"
+ " mov.b @%0,r0" "\n"
+ " mov.b %1,@%0" "\n"
+ " stc %2,sr" "\n"
+ " tst r0,r0";
+}
+ [(set_attr "length" "16")])
+
(define_insn "atomic_test_and_set_hard"
[(set (reg:SI T_REG)
(eq:SI (mem:QI (match_operand:SI 0 "register_operand" "r"))
@@ -873,7 +1369,7 @@
(clobber (match_scratch:SI 2 "=&r"))
(clobber (match_scratch:SI 3 "=&r"))
(clobber (match_scratch:SI 4 "=0"))]
- "TARGET_HARD_ATOMIC && !TARGET_ENABLE_TAS && TARGET_SH4A_ARCH"
+ "TARGET_ATOMIC_HARD_LLCS && !TARGET_ENABLE_TAS"
{
return "\r mov #-4,%2" "\n"
" and %0,%2" "\n"
diff --git a/gcc/configure b/gcc/configure
index 29fa38e61..951a0bdb0 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -6636,7 +6636,7 @@ fi
# Disable exceptions and RTTI if building with g++
noexception_flags=
save_CFLAGS="$CFLAGS"
-for real_option in -fno-exceptions -fno-rtti; do
+for real_option in -fno-exceptions -fno-rtti -fasynchronous-unwind-tables; do
# Do the check with the no- prefix removed since gcc silently
# accepts any -Wno-* option on purpose
case $real_option in
diff --git a/gcc/configure.ac b/gcc/configure.ac
index d0870bf77..9d7f60415 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -365,7 +365,8 @@ AC_SUBST(warn_cxxflags)
# Disable exceptions and RTTI if building with g++
ACX_PROG_CC_WARNING_OPTS(
- m4_quote(m4_do([-fno-exceptions -fno-rtti])), [noexception_flags])
+ m4_quote(m4_do([-fno-exceptions -fno-rtti -fasynchronous-unwind-tables])),
+ [noexception_flags])
# Enable expensive internal checks
is_release=
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 376cbf671..525efe417 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,93 @@
+2012-10-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * pt.c (fold_non_dependent_expr_sfinae): Remove static specifier.
+ (tsubst_copy_and_build): Use get_target_expr_sfinae.
+ * call.c (build_conditional_expr_1, convert_like_real): Likewise.
+ * cvt.c (build_up_reference): Likewise.
+ (ocp_convert): Use abstract_virtuals_error_sfinae.
+ (build_up_reference): Propagate complain to cp_build_addr_expr.
+ * decl.c (compute_array_index_type): Use fold_non_dependent_expr_sfinae.
+ * cp-tree.h: Update declarations.
+
+ * cvt.c (build_expr_type_conversion): Tidy.
+
+ * tree.c (stabilize_aggr_init): Change to static.
+
+2012-10-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51422
+ * semantics.c (is_normal_capture_proxy): Return true for
+ error_mark_node as DECL_VALUE_EXPR.
+
+2012-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ * cp-tree.h (SIZEOF_EXPR_TYPE_P): Define.
+ * tree.c (cp_tree_equal): Handle SIZEOF_EXPR with
+ SIZEOF_EXPR_TYPE_P.
+ * mangle.c (write_expression): Likewise.
+ * cxx-pretty-print.c (pp_cxx_unary_expression): Likewise.
+ * error.c (dump_expr): Likewise.
+ * parser.c (cp_parser_unary_expression): For sizeof call
+ cxx_sizeof_or_alignof_{type,expr} just for diagnostics and
+ return SIZEOF_EXPR with the operand.
+ * pt.c (tsubst_copy, tsubst_copy_and_build): For SIZEOF_EXPR,
+ call cxx_sizeof_or_alignof_{type,expr} for diagnostics, but
+ return SIZEOF_EXPR with tsubsted operand.
+ (value_dependent_expression_p): Handle SIZEOF_EXPR with
+ SIZEOF_EXPR_TYPE_P.
+ (instantiation_dependent_r): Likewise.
+ * call.c (null_ptr_cst_p): Call maybe_constant_value for C++98.
+ * semantics.c (finish_call_expr): Call
+ sizeof_pointer_memaccess_warning if needed.
+ (cxx_eval_constant_expression): Handle SIZEOF_EXPR.
+ (potential_constant_expression_1): Remove early exit for
+ C++98. Handle PROPERTY_REF.
+ * decl.c (duplicate_decls): When redeclaring a builtin function,
+ keep the merged decl builtin also if newdecl is a gnu_inline
+ inline definition.
+ (fold_sizeof_expr_r): New function.
+ (compute_array_index_type): Fold SIZEOF_EXPRs in itype.
+ * cp-gimplify.c (cp_genericize_r): Fold SIZEOF_EXPR.
+ * typeck.c (cp_build_binary_op): For warn_for_sign_compare
+ try harder using maybe_constant_value to get INTEGER_CSTs.
+
+ * decl.c (stabilize_vla_size): Call pointer_set_destroy
+ at the end.
+
+2012-10-04 Arnaud Charlet <charlet@adacore.com>
+
+ * decl2.c (cp_write_global_declarations): Fix handling of
+ -fdump-ada-spec*.
+
+2012-10-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/54777
+ * semantics.c (cxx_eval_constant_expression) <case COMPOUND_EXPR>: If
+ not ignoring the second operand, pass the original second operand
+ and not one with stripped nops to cxx_eval_constant_expression.
+
+2012-10-01 Jason Merrill <jason@redhat.com>
+
+ * decl.c (check_initializer): Set DECL_NONTRIVIALLY_INITIALIZED_P
+ for a constructor call.
+ (decl_jump_unsafe): So don't bother checking
+ type_has_nontrivial_default_init.
+ * call.c (set_up_extended_ref_temp): Set
+ DECL_NONTRIVIALLY_INITIALIZED_P.
+
+ * cp-tree.h (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK): New.
+ (DECL_FRIEND_P, DECL_ANTICIPATED): Use it.
+ (TYPE_FUNCTION_OR_TEMPLATE_DECL_P): New.
+ * name-lookup.c (hidden_name_p): Use it.
+
+ * cp-tree.h (DECL_PRETTY_FUNCTION_P): Just look at the name.
+ * decl.c (cp_make_fname_decl): Adjust.
+
+2012-09-30 Sharad Singhai <singhai@google.com>
+
+ * decl2.c (cp_write_global_declarations): Use a different method
+ to determine if the dump has ben initialized.
+
2012-09-29 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/54738
@@ -367,6 +457,14 @@
(ARGUMENT_PACK_INCOMPLETE_P): Use TREE_ADDRESSABLE instead of
TREE_LANG_FLAG_0 on TREE_VECs.
+2012-08-20 Florian Weimer <fweimer@redhat.com>
+
+ PR c++/19351
+ * call.c (build_operator_new_call): Add size_check argument and
+ evaluate it.
+ * cp-tree.h (build_operator_new_call): Adjust declaration.
+ * init.c (build_new_1): Compute array size check and apply it.
+
2012-08-20 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/10416
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 6f7e34669..f58dc8a52 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -557,7 +557,7 @@ null_ptr_cst_p (tree t)
{
/* Core issue 903 says only literal 0 is a null pointer constant. */
if (cxx_dialect < cxx0x)
- t = integral_constant_value (t);
+ t = maybe_constant_value (t);
STRIP_NOPS (t);
if (integer_zerop (t) && !TREE_OVERFLOW (t))
return true;
@@ -4777,7 +4777,7 @@ build_conditional_expr_1 (tree arg1, tree arg2, tree arg3,
but now we sometimes wrap them in NOP_EXPRs so the test would
fail. */
if (CLASS_TYPE_P (TREE_TYPE (result)))
- result = get_target_expr (result);
+ result = get_target_expr_sfinae (result, complain);
/* If this expression is an rvalue, but might be mistaken for an
lvalue, we must add a NON_LVALUE_EXPR. */
result = rvalue (result);
@@ -5883,7 +5883,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
field = next_initializable_field (DECL_CHAIN (field));
CONSTRUCTOR_APPEND_ELT (vec, field, size_int (len));
new_ctor = build_constructor (totype, vec);
- return get_target_expr (new_ctor);
+ return get_target_expr_sfinae (new_ctor, complain);
}
case ck_aggr:
@@ -5899,7 +5899,8 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
return fold_if_not_in_template (expr);
}
expr = reshape_init (totype, expr, complain);
- return get_target_expr (digest_init (totype, expr, complain));
+ return get_target_expr_sfinae (digest_init (totype, expr, complain),
+ complain);
default:
break;
@@ -8792,6 +8793,9 @@ set_up_extended_ref_temp (tree decl, tree expr, VEC(tree,gc) **cleanups,
TARGET_EXPR_INITIAL (expr)
= extend_ref_init_temps (decl, TARGET_EXPR_INITIAL (expr), cleanups);
+ /* Any reference temp has a non-trivial initializer. */
+ DECL_NONTRIVIALLY_INITIALIZED_P (var) = true;
+
/* If the initializer is constant, put it in DECL_INITIAL so we get
static initialization and use in constant expressions. */
init = maybe_constant_init (expr);
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index dd2ef067c..6178993fe 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1,6 +1,7 @@
/* C++-specific tree lowering bits; see also c-gimplify.c and tree-gimple.c.
- Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
+ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
+ 2012
Free Software Foundation, Inc.
Contributed by Jason Merrill <jason@redhat.com>
@@ -1119,6 +1120,22 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
genericize_break_stmt (stmt_p);
else if (TREE_CODE (stmt) == OMP_FOR)
genericize_omp_for_stmt (stmt_p, walk_subtrees, data);
+ else if (TREE_CODE (stmt) == SIZEOF_EXPR)
+ {
+ if (SIZEOF_EXPR_TYPE_P (stmt))
+ *stmt_p
+ = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (stmt, 0)),
+ SIZEOF_EXPR, false);
+ else if (TYPE_P (TREE_OPERAND (stmt, 0)))
+ *stmt_p = cxx_sizeof_or_alignof_type (TREE_OPERAND (stmt, 0),
+ SIZEOF_EXPR, false);
+ else
+ *stmt_p = cxx_sizeof_or_alignof_expr (TREE_OPERAND (stmt, 0),
+ SIZEOF_EXPR, false);
+ if (*stmt_p == error_mark_node)
+ *stmt_p = size_one_node;
+ return NULL;
+ }
pointer_set_insert (p_set, *stmt_p);
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index f4370224d..00f2d4a25 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -56,7 +56,6 @@ c-common.h, not after.
AGGR_INIT_VIA_CTOR_P (in AGGR_INIT_EXPR)
PTRMEM_OK_P (in ADDR_EXPR, OFFSET_REF, SCOPE_REF)
PAREN_STRING_LITERAL (in STRING_CST)
- DECL_PRETTY_FUNCTION_P (in VAR_DECL)
KOENIG_LOOKUP_P (in CALL_EXPR)
STATEMENT_LIST_NO_SCOPE (in STATEMENT_LIST).
EXPR_STMT_STMT_EXPR_RESULT (in EXPR_STMT)
@@ -79,6 +78,7 @@ c-common.h, not after.
OVL_ARG_DEPENDENT (in OVERLOAD)
PACK_EXPANSION_LOCAL_P (in *_PACK_EXPANSION)
TINFO_RECHECK_ACCESS_P (in TEMPLATE_INFO)
+ SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR)
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@@ -203,6 +203,13 @@ c-common.h, not after.
#define VAR_OR_FUNCTION_DECL_CHECK(NODE) \
TREE_CHECK2(NODE,VAR_DECL,FUNCTION_DECL)
+#define TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK(NODE) \
+ TREE_CHECK3(NODE,TYPE_DECL,TEMPLATE_DECL,FUNCTION_DECL)
+
+#define TYPE_FUNCTION_OR_TEMPLATE_DECL_P(NODE) \
+ (TREE_CODE (NODE) == TYPE_DECL || TREE_CODE (NODE) == TEMPLATE_DECL \
+ || TREE_CODE (NODE) == FUNCTION_DECL)
+
#define VAR_FUNCTION_OR_PARM_DECL_CHECK(NODE) \
TREE_CHECK3(NODE,VAR_DECL,FUNCTION_DECL,PARM_DECL)
@@ -1876,8 +1883,8 @@ struct GTY(()) lang_decl_base {
unsigned initialized_in_class : 1; /* var or fn */
unsigned repo_available_p : 1; /* var or fn */
unsigned threadprivate_or_deleted_p : 1; /* var or fn */
- unsigned anticipated_p : 1; /* fn or type */
- unsigned friend_attr : 1; /* fn or type */
+ unsigned anticipated_p : 1; /* fn, type or template */
+ unsigned friend_attr : 1; /* fn, type or template */
unsigned template_conv_p : 1; /* var or template */
unsigned odr_used : 1; /* var or fn */
unsigned u2sel : 1;
@@ -2265,12 +2272,13 @@ struct GTY((variable_size)) lang_decl {
/* Nonzero for a VAR_DECL means that the variable's initialization (if
any) has been processed. (In general, DECL_INITIALIZED_P is
- !DECL_EXTERN, but static data members may be initialized even if
+ !DECL_EXTERNAL, but static data members may be initialized even if
not defined.) */
#define DECL_INITIALIZED_P(NODE) \
(TREE_LANG_FLAG_1 (VAR_DECL_CHECK (NODE)))
-/* Nonzero for a VAR_DECL iff an explicit initializer was provided. */
+/* Nonzero for a VAR_DECL iff an explicit initializer was provided
+ or a non-trivial constructor is called. */
#define DECL_NONTRIVIALLY_INITIALIZED_P(NODE) \
(TREE_LANG_FLAG_3 (VAR_DECL_CHECK (NODE)))
@@ -2294,7 +2302,9 @@ struct GTY((variable_size)) lang_decl {
/* Nonzero for DECL means that this decl is just a friend declaration,
and should not be added to the list of members for this class. */
-#define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC (NODE)->u.base.friend_attr)
+#define DECL_FRIEND_P(NODE) \
+ (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \
+ ->u.base.friend_attr)
/* A TREE_LIST of the types which have befriended this FUNCTION_DECL. */
#define DECL_BEFRIENDING_CLASSES(NODE) \
@@ -2410,7 +2420,8 @@ struct GTY((variable_size)) lang_decl {
/* Nonzero if this DECL is the __PRETTY_FUNCTION__ variable in a
template function. */
#define DECL_PRETTY_FUNCTION_P(NODE) \
- (TREE_LANG_FLAG_0 (VAR_DECL_CHECK (NODE)))
+ (DECL_NAME (NODE) \
+ && !strcmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__PRETTY_FUNCTION__"))
/* The _TYPE context in which this _DECL appears. This field holds the
class where a virtual function instance is actually defined. */
@@ -3101,7 +3112,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
declared inside a class. In the latter case DECL_HIDDEN_FRIEND_P
will be set. */
#define DECL_ANTICIPATED(NODE) \
- (DECL_LANG_SPECIFIC (DECL_COMMON_CHECK (NODE))->u.base.anticipated_p)
+ (DECL_LANG_SPECIFIC (TYPE_FUNCTION_OR_TEMPLATE_DECL_CHECK (NODE)) \
+ ->u.base.anticipated_p)
/* Nonzero if NODE is a FUNCTION_DECL which was declared as a friend
within a class but has not been declared in the surrounding scope.
@@ -4044,6 +4056,10 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define CONVERT_EXPR_VBASE_PATH(NODE) \
TREE_LANG_FLAG_0 (CONVERT_EXPR_CHECK (NODE))
+/* True if SIZEOF_EXPR argument is type. */
+#define SIZEOF_EXPR_TYPE_P(NODE) \
+ TREE_LANG_FLAG_0 (SIZEOF_EXPR_CHECK (NODE))
+
/* An enumeration of the kind of tags that C++ accepts. */
enum tag_types {
none_type = 0, /* Not a tag type. */
@@ -5395,6 +5411,7 @@ extern tree build_non_dependent_expr (tree);
extern void make_args_non_dependent (VEC(tree,gc) *);
extern bool reregister_specialization (tree, tree, tree);
extern tree fold_non_dependent_expr (tree);
+extern tree fold_non_dependent_expr_sfinae (tree, tsubst_flags_t);
extern bool alias_type_or_template_p (tree);
extern bool alias_template_specialization_p (tree);
extern bool explicit_class_specialization_p (tree);
@@ -5684,7 +5701,6 @@ extern void lang_check_failed (const char *, int,
const char *) ATTRIBUTE_NORETURN;
extern tree stabilize_expr (tree, tree *);
extern void stabilize_call (tree, tree *);
-extern void stabilize_aggr_init (tree, tree *);
extern bool stabilize_init (tree, tree *);
extern tree add_stmt_to_compound (tree, tree);
extern void init_tree (void);
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 86f01abf2..d30c7e530 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -339,12 +339,12 @@ build_up_reference (tree type, tree arg, int flags, tree decl,
LOOKUP_ONLYCONVERTING|DIRECT_BIND);
}
else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg))
- return get_target_expr (arg);
+ return get_target_expr_sfinae (arg, complain);
/* If we had a way to wrap this up, and say, if we ever needed its
address, transform all occurrences of the register, into a memory
reference we could win better. */
- rval = cp_build_addr_expr (arg, tf_warning_or_error);
+ rval = cp_build_addr_expr (arg, complain);
if (rval == error_mark_node)
return error_mark_node;
@@ -842,7 +842,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
ctor = e;
- if (abstract_virtuals_error (NULL_TREE, type))
+ if (abstract_virtuals_error_sfinae (NULL_TREE, type, complain))
return error_mark_node;
if (BRACE_ENCLOSED_INITIALIZER_P (ctor))
@@ -1514,8 +1514,6 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
"converting NULL to non-pointer type");
}
- basetype = TREE_TYPE (expr);
-
if (basetype == error_mark_node)
return error_mark_node;
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index 03d9149f4..ce64a7b23 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -1,6 +1,6 @@
/* Implementation of subroutines for the GNU C++ pretty-printer.
Copyright (C) 2003, 2004, 2005, 2007, 2008,
- 2009, 2010, 2011 Free Software Foundation, Inc.
+ 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
This file is part of GCC.
@@ -798,7 +798,13 @@ pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
case ALIGNOF_EXPR:
pp_cxx_ws_string (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
pp_cxx_whitespace (pp);
- if (TYPE_P (TREE_OPERAND (t, 0)))
+ if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
+ {
+ pp_cxx_left_paren (pp);
+ pp_cxx_type_id (pp, TREE_TYPE (TREE_OPERAND (t, 0)));
+ pp_cxx_right_paren (pp);
+ }
+ else if (TYPE_P (TREE_OPERAND (t, 0)))
{
pp_cxx_left_paren (pp);
pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 078b14866..c162734cd 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2160,39 +2160,40 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl);
DECL_RESULT (olddecl) = DECL_RESULT (newdecl);
}
+ /* If redeclaring a builtin function, it stays built in
+ if newdecl is a gnu_inline definition, or if newdecl is just
+ a declaration. */
+ if (DECL_BUILT_IN (olddecl)
+ && (new_defines_function ? GNU_INLINE_P (newdecl) : types_match))
+ {
+ DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
+ DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
+ /* If we're keeping the built-in definition, keep the rtl,
+ regardless of declaration matches. */
+ COPY_DECL_RTL (olddecl, newdecl);
+ if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
+ {
+ enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
+ switch (fncode)
+ {
+ /* If a compatible prototype of these builtin functions
+ is seen, assume the runtime implements it with the
+ expected semantics. */
+ case BUILT_IN_STPCPY:
+ if (builtin_decl_explicit_p (fncode))
+ set_builtin_decl_implicit_p (fncode, true);
+ break;
+ default:
+ break;
+ }
+ }
+ }
if (new_defines_function)
/* If defining a function declared with other language
linkage, use the previously declared language linkage. */
SET_DECL_LANGUAGE (newdecl, DECL_LANGUAGE (olddecl));
else if (types_match)
{
- /* If redeclaring a builtin function, and not a definition,
- it stays built in. */
- if (DECL_BUILT_IN (olddecl))
- {
- DECL_BUILT_IN_CLASS (newdecl) = DECL_BUILT_IN_CLASS (olddecl);
- DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl);
- /* If we're keeping the built-in definition, keep the rtl,
- regardless of declaration matches. */
- COPY_DECL_RTL (olddecl, newdecl);
- if (DECL_BUILT_IN_CLASS (newdecl) == BUILT_IN_NORMAL)
- {
- enum built_in_function fncode = DECL_FUNCTION_CODE (newdecl);
- switch (fncode)
- {
- /* If a compatible prototype of these builtin functions
- is seen, assume the runtime implements it with the
- expected semantics. */
- case BUILT_IN_STPCPY:
- if (builtin_decl_explicit_p (fncode))
- set_builtin_decl_implicit_p (fncode, true);
- break;
- default:
- break;
- }
- }
- }
-
DECL_RESULT (newdecl) = DECL_RESULT (olddecl);
/* Don't clear out the arguments if we're just redeclaring a
function. */
@@ -2679,8 +2680,7 @@ decl_jump_unsafe (tree decl)
type = strip_array_types (type);
- if (type_has_nontrivial_default_init (TREE_TYPE (decl))
- || DECL_NONTRIVIALLY_INITIALIZED_P (decl))
+ if (DECL_NONTRIVIALLY_INITIALIZED_P (decl))
return 2;
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
@@ -3829,7 +3829,6 @@ cp_make_fname_decl (location_t loc, tree id, int type_dep)
/* As we're using pushdecl_with_scope, we must set the context. */
DECL_CONTEXT (decl) = current_function_decl;
- DECL_PRETTY_FUNCTION_P (decl) = type_dep;
TREE_STATIC (decl) = 1;
TREE_READONLY (decl) = 1;
@@ -5582,6 +5581,11 @@ check_initializer (tree decl, tree init, int flags, VEC(tree,gc) **cleanups)
{
init_code = build_aggr_init_full_exprs (decl, init, flags);
+ /* A constructor call is a non-trivial initializer even if
+ it isn't explicitly written. */
+ if (TREE_SIDE_EFFECTS (init_code))
+ DECL_NONTRIVIALLY_INITIALIZED_P (decl) = true;
+
/* If this is a constexpr initializer, expand_default_init will
have returned an INIT_EXPR rather than a CALL_EXPR. In that
case, pull the initializer back out and pass it down into
@@ -7928,6 +7932,36 @@ stabilize_vla_size (tree size)
struct pointer_set_t *pset = pointer_set_create ();
/* Break out any function calls into temporary variables. */
cp_walk_tree (&size, stabilize_save_expr_r, pset, pset);
+ pointer_set_destroy (pset);
+}
+
+/* Helper function for compute_array_index_type. Look for SIZEOF_EXPR
+ not inside of SAVE_EXPR and fold them. */
+
+static tree
+fold_sizeof_expr_r (tree *expr_p, int *walk_subtrees, void *data)
+{
+ tree expr = *expr_p;
+ if (TREE_CODE (expr) == SAVE_EXPR || TYPE_P (expr))
+ *walk_subtrees = 0;
+ else if (TREE_CODE (expr) == SIZEOF_EXPR)
+ {
+ *(bool *)data = true;
+ if (SIZEOF_EXPR_TYPE_P (expr))
+ expr = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (expr, 0)),
+ SIZEOF_EXPR, false);
+ else if (TYPE_P (TREE_OPERAND (expr, 0)))
+ expr = cxx_sizeof_or_alignof_type (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
+ false);
+ else
+ expr = cxx_sizeof_or_alignof_expr (TREE_OPERAND (expr, 0), SIZEOF_EXPR,
+ false);
+ if (expr == error_mark_node)
+ expr = size_one_node;
+ *expr_p = expr;
+ *walk_subtrees = 0;
+ }
+ return NULL;
}
/* Given the SIZE (i.e., number of elements) in an array, compute an
@@ -7956,7 +7990,7 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
NOP_EXPR with TREE_SIDE_EFFECTS; don't fold in that case. */;
else
{
- size = fold_non_dependent_expr (size);
+ size = fold_non_dependent_expr_sfinae (size, complain);
if (CLASS_TYPE_P (type)
&& CLASSTYPE_LITERAL_P (type))
@@ -8123,8 +8157,21 @@ compute_array_index_type (tree name, tree size, tsubst_flags_t complain)
processing_template_decl = saved_processing_template_decl;
if (!TREE_CONSTANT (itype))
- /* A variable sized array. */
- itype = variable_size (itype);
+ {
+ /* A variable sized array. */
+ itype = variable_size (itype);
+ if (TREE_CODE (itype) != SAVE_EXPR)
+ {
+ /* Look for SIZEOF_EXPRs in itype and fold them, otherwise
+ they might survive till gimplification. */
+ tree newitype = itype;
+ bool found = false;
+ cp_walk_tree_without_duplicates (&newitype,
+ fold_sizeof_expr_r, &found);
+ if (found)
+ itype = variable_size (fold (newitype));
+ }
+ }
/* Make sure that there was no overflow when creating to a signed
index type. (For example, on a 32-bit machine, an array with
size 2^32 - 1 is too big.) */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 4cff0516d..87e38d3bf 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3698,9 +3698,9 @@ cp_write_global_declarations (void)
cgraph_process_same_body_aliases ();
/* Handle -fdump-ada-spec[-slim] */
- if (dump_enabled_p (TDI_ada))
+ if (flag_dump_ada_spec || flag_dump_ada_spec_slim)
{
- if (get_dump_file_info (TDI_ada)->flags & TDF_SLIM)
+ if (flag_dump_ada_spec_slim)
collect_source_ref (main_input_filename);
else
collect_source_refs (global_namespace);
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index c8b614b16..e1aa938dd 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -2312,7 +2312,9 @@ dump_expr (tree t, int flags)
}
pp_cxx_whitespace (cxx_pp);
pp_cxx_left_paren (cxx_pp);
- if (TYPE_P (TREE_OPERAND (t, 0)))
+ if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
+ dump_type (TREE_TYPE (TREE_OPERAND (t, 0)), flags);
+ else if (TYPE_P (TREE_OPERAND (t, 0)))
dump_type (TREE_OPERAND (t, 0), flags);
else
dump_expr (TREE_OPERAND (t, 0), flags);
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 13c658b29..eee44a1ba 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -1,6 +1,6 @@
/* Name mangling for the 3.0 C++ ABI.
Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010,
- 2011 Free Software Foundation, Inc.
+ 2011, 2012 Free Software Foundation, Inc.
Written by Alex Samuel <samuel@codesourcery.com>
This file is part of GCC.
@@ -2581,6 +2581,12 @@ write_expression (tree expr)
write_char ('E');
}
else if (TREE_CODE (expr) == SIZEOF_EXPR
+ && SIZEOF_EXPR_TYPE_P (expr))
+ {
+ write_string ("st");
+ write_type (TREE_TYPE (TREE_OPERAND (expr, 0)));
+ }
+ else if (TREE_CODE (expr) == SIZEOF_EXPR
&& TYPE_P (TREE_OPERAND (expr, 0)))
{
write_string ("st");
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index e4e982764..cd328b31c 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4174,6 +4174,7 @@ hidden_name_p (tree val)
{
if (DECL_P (val)
&& DECL_LANG_SPECIFIC (val)
+ && TYPE_FUNCTION_OR_TEMPLATE_DECL_P (val)
&& DECL_ANTICIPATED (val))
return true;
return false;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 155b51a18..baaa80956 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6383,17 +6383,19 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
case RID_ALIGNOF:
case RID_SIZEOF:
{
- tree operand;
+ tree operand, ret;
enum tree_code op;
+ location_t first_loc;
op = keyword == RID_ALIGNOF ? ALIGNOF_EXPR : SIZEOF_EXPR;
/* Consume the token. */
cp_lexer_consume_token (parser->lexer);
+ first_loc = cp_lexer_peek_token (parser->lexer)->location;
/* Parse the operand. */
operand = cp_parser_sizeof_operand (parser, keyword);
if (TYPE_P (operand))
- return cxx_sizeof_or_alignof_type (operand, op, true);
+ ret = cxx_sizeof_or_alignof_type (operand, op, true);
else
{
/* ISO C++ defines alignof only with types, not with
@@ -6404,8 +6406,29 @@ cp_parser_unary_expression (cp_parser *parser, bool address_p, bool cast_p,
"ISO C++ does not allow %<alignof%> "
"with a non-type");
- return cxx_sizeof_or_alignof_expr (operand, op, true);
+ ret = cxx_sizeof_or_alignof_expr (operand, op, true);
}
+ /* For SIZEOF_EXPR, just issue diagnostics, but keep
+ SIZEOF_EXPR with the original operand. */
+ if (op == SIZEOF_EXPR && ret != error_mark_node)
+ {
+ if (TREE_CODE (ret) != SIZEOF_EXPR || TYPE_P (operand))
+ {
+ if (!processing_template_decl && TYPE_P (operand))
+ {
+ ret = build_min (SIZEOF_EXPR, size_type_node,
+ build1 (NOP_EXPR, operand,
+ error_mark_node));
+ SIZEOF_EXPR_TYPE_P (ret) = 1;
+ }
+ else
+ ret = build_min (SIZEOF_EXPR, size_type_node, operand);
+ TREE_SIDE_EFFECTS (ret) = 0;
+ TREE_READONLY (ret) = 1;
+ }
+ SET_EXPR_LOCATION (ret, first_loc);
+ }
+ return ret;
}
case RID_NEW:
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 104d4dd68..1377b3eed 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -5020,7 +5020,7 @@ redeclare_class_template (tree type, tree parms)
/* Simplify EXPR if it is a non-dependent expression. Returns the
(possibly simplified) expression. */
-static tree
+tree
fold_non_dependent_expr_sfinae (tree expr, tsubst_flags_t complain)
{
if (expr == NULL_TREE)
@@ -12031,14 +12031,16 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
{
- tree expanded;
+ tree expanded, op = TREE_OPERAND (t, 0);
int len = 0;
+ if (SIZEOF_EXPR_TYPE_P (t))
+ op = TREE_TYPE (op);
+
++cp_unevaluated_operand;
++c_inhibit_evaluation_warnings;
/* We only want to compute the number of arguments. */
- expanded = tsubst_pack_expansion (TREE_OPERAND (t, 0), args,
- complain, in_decl);
+ expanded = tsubst_pack_expansion (op, args, complain, in_decl);
--cp_unevaluated_operand;
--c_inhibit_evaluation_warnings;
@@ -12065,6 +12067,16 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl)
else
return build_int_cst (size_type_node, len);
}
+ if (SIZEOF_EXPR_TYPE_P (t))
+ {
+ r = tsubst_copy (TREE_TYPE (TREE_OPERAND (t, 0)),
+ args, complain, in_decl);
+ r = build1 (NOP_EXPR, r, error_mark_node);
+ r = build1 (SIZEOF_EXPR,
+ tsubst (TREE_TYPE (t), args, complain, in_decl), r);
+ SIZEOF_EXPR_TYPE_P (r) = 1;
+ return r;
+ }
/* Fall through */
case INDIRECT_REF:
@@ -13468,31 +13480,56 @@ tsubst_copy_and_build (tree t,
/* Fall through */
case ALIGNOF_EXPR:
- op1 = TREE_OPERAND (t, 0);
- if (!args)
- {
- /* When there are no ARGS, we are trying to evaluate a
- non-dependent expression from the parser. Trying to do
- the substitutions may not work. */
- if (!TYPE_P (op1))
- op1 = TREE_TYPE (op1);
- }
- else
- {
- ++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);
- --cp_unevaluated_operand;
- --c_inhibit_evaluation_warnings;
- }
- if (TYPE_P (op1))
- RETURN (cxx_sizeof_or_alignof_type (op1, TREE_CODE (t),
- complain & tf_error));
- else
- RETURN (cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t),
- complain & tf_error));
+ {
+ tree r;
+
+ op1 = TREE_OPERAND (t, 0);
+ if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
+ op1 = TREE_TYPE (op1);
+ if (!args)
+ {
+ /* When there are no ARGS, we are trying to evaluate a
+ non-dependent expression from the parser. Trying to do
+ the substitutions may not work. */
+ if (!TYPE_P (op1))
+ op1 = TREE_TYPE (op1);
+ }
+ else
+ {
+ ++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);
+ --cp_unevaluated_operand;
+ --c_inhibit_evaluation_warnings;
+ }
+ if (TYPE_P (op1))
+ r = cxx_sizeof_or_alignof_type (op1, TREE_CODE (t),
+ complain & tf_error);
+ else
+ r = cxx_sizeof_or_alignof_expr (op1, TREE_CODE (t),
+ complain & tf_error);
+ if (TREE_CODE (t) == SIZEOF_EXPR && r != error_mark_node)
+ {
+ if (TREE_CODE (r) != SIZEOF_EXPR || TYPE_P (op1))
+ {
+ if (TYPE_P (op1))
+ {
+ r = build_min (SIZEOF_EXPR, size_type_node,
+ build1 (NOP_EXPR, op1, error_mark_node));
+ SIZEOF_EXPR_TYPE_P (r) = 1;
+ }
+ else
+ r = build_min (SIZEOF_EXPR, size_type_node, op1);
+ TREE_SIDE_EFFECTS (r) = 0;
+ TREE_READONLY (r) = 1;
+ }
+ SET_EXPR_LOCATION (r, EXPR_LOCATION (t));
+ }
+ RETURN (r);
+ }
case AT_ENCODE_EXPR:
{
@@ -14250,7 +14287,8 @@ tsubst_copy_and_build (tree t,
FIXME stop folding in cp_parser_initializer_clause. */
gcc_assert (TREE_CONSTANT (t));
{
- tree r = get_target_expr (RECUR (TARGET_EXPR_INITIAL (t)));
+ tree r = get_target_expr_sfinae (RECUR (TARGET_EXPR_INITIAL (t)),
+ complain);
TREE_CONSTANT (r) = true;
RETURN (r);
}
@@ -19288,6 +19326,9 @@ value_dependent_expression_p (tree expression)
}
case SIZEOF_EXPR:
+ if (SIZEOF_EXPR_TYPE_P (expression))
+ return dependent_type_p (TREE_TYPE (TREE_OPERAND (expression, 0)));
+ /* FALLTHRU */
case ALIGNOF_EXPR:
case TYPEID_EXPR:
/* A `sizeof' expression is value-dependent if the operand is
@@ -19627,6 +19668,8 @@ instantiation_dependent_r (tree *tp, int *walk_subtrees,
case TRAIT_EXPR:
{
tree op = TREE_OPERAND (*tp, 0);
+ if (code == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (*tp))
+ op = TREE_TYPE (op);
if (TYPE_P (op))
{
if (dependent_type_p (op)
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 1aa5a8b8b..717492709 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3,8 +3,7 @@
building RTL. These routines are used both during actual parsing
and during the instantiation of template functions.
- Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+ Copyright (C) 1998-2012 Free Software Foundation, Inc.
Written by Mark Mitchell (mmitchell@usa.net) based on code found
formerly in parse.y and pt.c.
@@ -2170,8 +2169,25 @@ finish_call_expr (tree fn, VEC(tree,gc) **args, bool disallow_virtual,
result = resolve_overloaded_builtin (input_location, fn, *args);
if (!result)
- /* A call to a namespace-scope function. */
- result = build_new_function_call (fn, args, koenig_p, complain);
+ {
+ if (warn_sizeof_pointer_memaccess
+ && !VEC_empty(tree, *args)
+ && TREE_CODE (VEC_last(tree, *args)) == SIZEOF_EXPR
+ && !processing_template_decl)
+ {
+ tree sizeof_arg = VEC_last(tree, *args);
+ if (SIZEOF_EXPR_TYPE_P (sizeof_arg))
+ sizeof_arg = TREE_TYPE (TREE_OPERAND (sizeof_arg, 0));
+ else
+ sizeof_arg = TREE_OPERAND (sizeof_arg, 0);
+ sizeof_pointer_memaccess_warning
+ (EXPR_LOCATION (VEC_last(tree, *args)), fn, *args,
+ sizeof_arg, same_type_ignoring_top_level_qualifiers_p);
+ }
+
+ /* A call to a namespace-scope function. */
+ result = build_new_function_call (fn, args, koenig_p, complain);
+ }
}
else if (TREE_CODE (fn) == PSEUDO_DTOR_EXPR)
{
@@ -7723,6 +7739,21 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
non_constant_p);
break;
+ case SIZEOF_EXPR:
+ if (SIZEOF_EXPR_TYPE_P (t))
+ r = cxx_sizeof_or_alignof_type (TREE_TYPE (TREE_OPERAND (t, 0)),
+ SIZEOF_EXPR, false);
+ else if (TYPE_P (TREE_OPERAND (t, 0)))
+ r = cxx_sizeof_or_alignof_type (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+ false);
+ else
+ r = cxx_sizeof_or_alignof_expr (TREE_OPERAND (t, 0), SIZEOF_EXPR,
+ false);
+ if (r == error_mark_node)
+ r = size_one_node;
+ VERIFY_CONSTANT (r);
+ break;
+
case COMPOUND_EXPR:
{
/* check_return_expr sometimes wraps a TARGET_EXPR in a
@@ -7740,6 +7771,7 @@ cxx_eval_constant_expression (const constexpr_call *call, tree t,
/* Check that the LHS is constant and then discard it. */
cxx_eval_constant_expression (call, op0, allow_non_constant,
false, non_constant_p);
+ op1 = TREE_OPERAND (t, 1);
r = cxx_eval_constant_expression (call, op1, allow_non_constant,
addr, non_constant_p);
}
@@ -8106,12 +8138,6 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
int i;
tree tmp;
- /* C++98 has different rules for the form of a constant expression that
- are enforced in the parser, so we can assume that anything that gets
- this far is suitable. */
- if (cxx_dialect < cxx0x)
- return true;
-
if (t == error_mark_node)
return false;
if (t == NULL_TREE)
@@ -8632,6 +8658,9 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
return false;
default:
+ if (objc_is_property_ref (t))
+ return false;
+
sorry ("unexpected AST of kind %s", tree_code_name[TREE_CODE (t)]);
gcc_unreachable();
return false;
@@ -8975,14 +9004,15 @@ is_capture_proxy (tree decl)
bool
is_normal_capture_proxy (tree decl)
{
- tree val;
-
if (!is_capture_proxy (decl))
/* It's not a capture proxy. */
return false;
/* It is a capture proxy, is it a normal capture? */
- val = DECL_VALUE_EXPR (decl);
+ tree val = DECL_VALUE_EXPR (decl);
+ if (val == error_mark_node)
+ return true;
+
gcc_assert (TREE_CODE (val) == COMPONENT_REF);
val = TREE_OPERAND (val, 1);
return DECL_NORMAL_CAPTURE_P (val);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 7dddf2299..e1af37864 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -2602,6 +2602,10 @@ cp_tree_equal (tree t1, tree t2)
tree o1 = TREE_OPERAND (t1, 0);
tree o2 = TREE_OPERAND (t2, 0);
+ if (SIZEOF_EXPR_TYPE_P (t1))
+ o1 = TREE_TYPE (o1);
+ if (SIZEOF_EXPR_TYPE_P (t2))
+ o2 = TREE_TYPE (o2);
if (TREE_CODE (o1) != TREE_CODE (o2))
return false;
if (TYPE_P (o1))
@@ -3553,7 +3557,7 @@ stabilize_call (tree call, tree *initp)
arguments, while, upon return, *INITP contains an expression to
compute the arguments. */
-void
+static void
stabilize_aggr_init (tree call, tree *initp)
{
tree inits = NULL_TREE;
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 884f7d057..ce779075d 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4624,7 +4624,14 @@ cp_build_binary_op (location_t location,
&& !enum_cast_to_int (orig_op0)
&& !enum_cast_to_int (orig_op1))
{
- warn_for_sign_compare (location, orig_op0, orig_op1, op0, op1,
+ tree oop0 = maybe_constant_value (orig_op0);
+ tree oop1 = maybe_constant_value (orig_op1);
+
+ if (TREE_CODE (oop0) != INTEGER_CST)
+ oop0 = orig_op0;
+ if (TREE_CODE (oop1) != INTEGER_CST)
+ oop1 = orig_op1;
+ warn_for_sign_compare (location, oop0, oop1, op0, op1,
result_type, resultcode);
}
}
diff --git a/gcc/dce.c b/gcc/dce.c
index c951865f7..11f8edb7b 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -806,15 +806,17 @@ struct rtl_opt_pass pass_ud_rtl_dce =
/* Process basic block BB. Return true if the live_in set has
changed. REDO_OUT is true if the info at the bottom of the block
needs to be recalculated before starting. AU is the proper set of
- artificial uses. */
+ artificial uses. Track global substitution of uses of dead pseudos
+ in debug insns using GLOBAL_DEBUG. */
static bool
-word_dce_process_block (basic_block bb, bool redo_out)
+word_dce_process_block (basic_block bb, bool redo_out,
+ struct dead_debug_global *global_debug)
{
bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
rtx insn;
bool block_changed;
- struct dead_debug debug;
+ struct dead_debug_local debug;
if (redo_out)
{
@@ -836,7 +838,7 @@ word_dce_process_block (basic_block bb, bool redo_out)
}
bitmap_copy (local_live, DF_WORD_LR_OUT (bb));
- dead_debug_init (&debug, NULL);
+ dead_debug_local_init (&debug, NULL, global_debug);
FOR_BB_INSNS_REVERSE (bb, insn)
if (DEBUG_INSN_P (insn))
@@ -890,7 +892,7 @@ word_dce_process_block (basic_block bb, bool redo_out)
if (block_changed)
bitmap_copy (DF_WORD_LR_IN (bb), local_live);
- dead_debug_finish (&debug, NULL);
+ dead_debug_local_finish (&debug, NULL);
BITMAP_FREE (local_live);
return block_changed;
}
@@ -899,16 +901,18 @@ word_dce_process_block (basic_block bb, bool redo_out)
/* Process basic block BB. Return true if the live_in set has
changed. REDO_OUT is true if the info at the bottom of the block
needs to be recalculated before starting. AU is the proper set of
- artificial uses. */
+ artificial uses. Track global substitution of uses of dead pseudos
+ in debug insns using GLOBAL_DEBUG. */
static bool
-dce_process_block (basic_block bb, bool redo_out, bitmap au)
+dce_process_block (basic_block bb, bool redo_out, bitmap au,
+ struct dead_debug_global *global_debug)
{
bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
rtx insn;
bool block_changed;
df_ref *def_rec;
- struct dead_debug debug;
+ struct dead_debug_local debug;
if (redo_out)
{
@@ -932,7 +936,7 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au)
bitmap_copy (local_live, DF_LR_OUT (bb));
df_simulate_initialize_backwards (bb, local_live);
- dead_debug_init (&debug, NULL);
+ dead_debug_local_init (&debug, NULL, global_debug);
FOR_BB_INSNS_REVERSE (bb, insn)
if (DEBUG_INSN_P (insn))
@@ -977,7 +981,7 @@ dce_process_block (basic_block bb, bool redo_out, bitmap au)
DEBUG_TEMP_BEFORE_WITH_VALUE);
}
- dead_debug_finish (&debug, NULL);
+ dead_debug_local_finish (&debug, NULL);
df_simulate_finalize_backwards (bb, local_live);
block_changed = !bitmap_equal_p (local_live, DF_LR_IN (bb));
@@ -1014,12 +1018,15 @@ fast_dce (bool word_level)
bitmap au = &df->regular_block_artificial_uses;
bitmap au_eh = &df->eh_block_artificial_uses;
int i;
+ struct dead_debug_global global_debug;
prescan_insns_for_dce (true);
for (i = 0; i < n_blocks; i++)
bitmap_set_bit (all_blocks, postorder[i]);
+ dead_debug_global_init (&global_debug, NULL);
+
while (global_changed)
{
global_changed = false;
@@ -1038,11 +1045,13 @@ fast_dce (bool word_level)
if (word_level)
local_changed
- = word_dce_process_block (bb, bitmap_bit_p (redo_out, index));
+ = word_dce_process_block (bb, bitmap_bit_p (redo_out, index),
+ &global_debug);
else
local_changed
= dce_process_block (bb, bitmap_bit_p (redo_out, index),
- bb_has_eh_pred (bb) ? au_eh : au);
+ bb_has_eh_pred (bb) ? au_eh : au,
+ &global_debug);
bitmap_set_bit (processed, index);
if (local_changed)
@@ -1090,6 +1099,8 @@ fast_dce (bool word_level)
}
}
+ dead_debug_global_finish (&global_debug, NULL);
+
delete_unmarked_insns ();
BITMAP_FREE (processed);
diff --git a/gcc/df-problems.c b/gcc/df-problems.c
index abeb118dd..a1a0e7142 100644
--- a/gcc/df-problems.c
+++ b/gcc/df-problems.c
@@ -2892,7 +2892,7 @@ static void
df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
bitmap live, bitmap do_not_gen,
bitmap artificial_uses,
- struct dead_debug *debug)
+ struct dead_debug_local *debug)
{
unsigned int r;
@@ -3021,7 +3021,7 @@ df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
static void
df_create_unused_note (rtx insn, df_ref def,
bitmap live, bitmap artificial_uses,
- struct dead_debug *debug)
+ struct dead_debug_local *debug)
{
unsigned int dregno = DF_REF_REGNO (def);
@@ -3060,9 +3060,9 @@ df_note_bb_compute (unsigned int bb_index,
rtx insn;
df_ref *def_rec;
df_ref *use_rec;
- struct dead_debug debug;
+ struct dead_debug_local debug;
- dead_debug_init (&debug, NULL);
+ dead_debug_local_init (&debug, NULL, NULL);
bitmap_copy (live, df_get_live_out (bb));
bitmap_clear (artificial_uses);
@@ -3268,7 +3268,7 @@ df_note_bb_compute (unsigned int bb_index,
}
}
- dead_debug_finish (&debug, NULL);
+ dead_debug_local_finish (&debug, NULL);
}
@@ -3286,6 +3286,11 @@ df_note_compute (bitmap all_blocks)
EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
{
+ /* ??? Unlike fast DCE, we don't use global_debug for uses of dead
+ pseudos in debug insns because we don't always (re)visit blocks
+ with death points after visiting dead uses. Even changing this
+ loop to postorder would still leave room for visiting a death
+ point before visiting a subsequent debug use. */
df_note_bb_compute (bb_index, &live, &do_not_gen, &artificial_uses);
}
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index b363db014..fa5989e6b 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -3634,6 +3634,15 @@ This pragma takes no arguments. It causes the rest of the code in the
current file to be treated as if it came from a system header.
@xref{System Headers}.
+@item #pragma GCC warning
+@itemx #pragma GCC error
+@code{#pragma GCC warning "message"} causes the preprocessor to issue
+a warning diagnostic with the text @samp{message}. The message
+contained in the pragma must be a single string literal. Similarly,
+@code{#pragma GCC error "message"} issues an error message. Unlike
+the @samp{#warning} and @samp{#error} directives, these pragmas can be
+embedded in preprocessor macros using @samp{_Pragma}.
+
@end ftable
@node Other Directives
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 4461a5f27..b15a4d317 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -330,6 +330,8 @@ Objective-C and Objective-C++ Dialects}.
-fenable-@var{kind}-@var{pass}=@var{range-list} @gol
-fdebug-types-section -fmem-report-wpa @gol
-fmem-report -fpre-ipa-mem-report -fpost-ipa-mem-report -fprofile-arcs @gol
+-fopt-info @gol
+-fopt-info-@var{options}@r{[}=@var{file}@r{]} @gol
-frandom-seed=@var{string} -fsched-verbose=@var{n} @gol
-fsel-sched-verbose -fsel-sched-dump-cfg -fsel-sched-pipelining-verbose @gol
-fstack-usage -ftest-coverage -ftime-report -fvar-tracking @gol
@@ -386,7 +388,7 @@ Objective-C and Objective-C++ Dialects}.
-fno-toplevel-reorder -fno-trapping-math -fno-zero-initialized-in-bss @gol
-fomit-frame-pointer -foptimize-register-move -foptimize-sibling-calls @gol
-fpartial-inlining -fpeel-loops -fpredictive-commoning @gol
--fprefetch-loop-arrays @gol
+-fprefetch-loop-arrays -fprofile-report @gol
-fprofile-correction -fprofile-dir=@var{path} -fprofile-generate @gol
-fprofile-generate=@var{path} @gol
-fprofile-use -fprofile-use=@var{path} -fprofile-values @gol
@@ -637,7 +639,7 @@ Objective-C and Objective-C++ Dialects}.
-mincoming-stack-boundary=@var{num} @gol
-mcld -mcx16 -msahf -mmovbe -mcrc32 @gol
-mrecip -mrecip=@var{opt} @gol
--mvzeroupper @gol
+-mvzeroupper -mprefer-avx128 @gol
-mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol
-mavx2 -maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma @gol
-msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlzcnt @gol
@@ -866,6 +868,7 @@ See RS/6000 and PowerPC Options.
-mmax-constant-size=@gol
-mint-register=@gol
-mpid@gol
+-mno-warn-multiple-fast-interrupts@gol
-msave-acc-in-interrupts}
@emph{S/390 and zSeries Options}
@@ -900,7 +903,8 @@ See RS/6000 and PowerPC Options.
-mspace -mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
-mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol
-mindexed-addressing -mgettrcost=@var{number} -mpt-fixed @gol
--maccumulate-outgoing-args -minvalid-symbols -msoft-atomic -mhard-atomic @gol
+-maccumulate-outgoing-args -minvalid-symbols @gol
+-matomic-model=@var{atomic-model} @gol
-mbranch-cost=@var{num} -mzdcbranch -mno-zdcbranch -mcbranchdi -mcmpeqdi @gol
-mfused-madd -mno-fused-madd -mfsca -mno-fsca -mfsrra -mno-fsrra @gol
-mpretend-cmove -mtas}
@@ -5158,6 +5162,11 @@ allocation for the WPA phase only.
Makes the compiler print some statistics about permanent memory
allocation before or after interprocedural optimization.
+@item -fprofile-report
+@opindex fprofile-report
+Makes the compiler print some statistics about consistency of the
+(estimated) profile and effect of individual passes.
+
@item -fstack-usage
@opindex fstack-usage
Makes the compiler output stack usage information for the program, on a
@@ -5359,20 +5368,23 @@ Here are some examples showing uses of these options.
@item -d@var{letters}
@itemx -fdump-rtl-@var{pass}
+@itemx -fdump-rtl-@var{pass}=@var{filename}
@opindex d
Says to make debugging dumps during compilation at times specified by
@var{letters}. This is used for debugging the RTL-based passes of the
compiler. The file names for most of the dumps are made by appending
a pass number and a word to the @var{dumpname}, and the files are
-created in the directory of the output file. Note that the pass
-number is computed statically as passes get registered into the pass
-manager. Thus the numbering is not related to the dynamic order of
-execution of passes. In particular, a pass installed by a plugin
-could have a number over 200 even if it executed quite early.
-@var{dumpname} is generated from the name of the output file, if
-explicitly specified and it is not an executable, otherwise it is the
-basename of the source file. These switches may have different effects
-when @option{-E} is used for preprocessing.
+created in the directory of the output file. In case of
+@option{=@var{filename}} option, the dump is output on the given file
+instead of the pass numbered dump files. Note that the pass number is
+computed statically as passes get registered into the pass manager.
+Thus the numbering is not related to the dynamic order of execution of
+passes. In particular, a pass installed by a plugin could have a
+number over 200 even if it executed quite early. @var{dumpname} is
+generated from the name of the output file, if explicitly specified
+and it is not an executable, otherwise it is the basename of the
+source file. These switches may have different effects when
+@option{-E} is used for preprocessing.
Debug dumps can be enabled with a @option{-fdump-rtl} switch or some
@option{-d} option @var{letters}. Here are the possible
@@ -5753,15 +5765,18 @@ counters for each function compiled.
@item -fdump-tree-@var{switch}
@itemx -fdump-tree-@var{switch}-@var{options}
+@itemx -fdump-tree-@var{switch}-@var{options}=@var{filename}
@opindex fdump-tree
Control the dumping at various stages of processing the intermediate
language tree to a file. The file name is generated by appending a
switch-specific suffix to the source file name, and the file is
-created in the same directory as the output file. If the
-@samp{-@var{options}} form is used, @var{options} is a list of
-@samp{-} separated options which control the details of the dump. Not
-all options are applicable to all dumps; those that are not
-meaningful are ignored. The following options are available
+created in the same directory as the output file. In case of
+@option{=@var{filename}} option, the dump is output on the given file
+instead of the auto named dump files. If the @samp{-@var{options}}
+form is used, @var{options} is a list of @samp{-} separated options
+which control the details of the dump. Not all options are applicable
+to all dumps; those that are not meaningful are ignored. The
+following options are available
@table @samp
@item address
@@ -5781,7 +5796,8 @@ trees, this option inhibits dumping the bodies of control structures.
Print a raw representation of the tree. By default, trees are
pretty-printed into a C-like representation.
@item details
-Enable more detailed dumps (not honored by every dump option).
+Enable more detailed dumps (not honored by every dump option). Also
+include information from the optimization passes.
@item stats
Enable dumping various statistics about the pass (not honored by every dump
option).
@@ -5799,9 +5815,38 @@ Enable showing the tree dump for each statement.
Enable showing the EH region number holding each statement.
@item scev
Enable showing scalar evolution analysis details.
+@item optimized
+Enable showing optimization information (only available in certain
+passes).
+@item missed
+Enable showing missed optimization information (only available in certain
+passes).
+@item notes
+Enable other detailed optimization information (only available in
+certain passes).
+@item =@var{filename}
+Instead of an auto named dump file, output into the given file
+name. The file names @file{stdout} and @file{stderr} are treated
+specially and are considered already open standard streams. For
+example,
+
+@smallexample
+gcc -O2 -ftree-vectorize -fdump-tree-vect-blocks=foo.dump
+ -fdump-tree-pre=stderr file.c
+@end smallexample
+
+outputs vectorizer dump into @file{foo.dump}, while the PRE dump is
+output on to @file{stderr}. If two conflicting dump filenames are
+given for the same pass, then the latter option overrides the earlier
+one.
+
@item all
Turn on all options, except @option{raw}, @option{slim}, @option{verbose}
and @option{lineno}.
+
+@item optall
+Turn on all optimization options, i.e., @option{optimized},
+@option{missed}, and @option{note}.
@end table
The following tree dumps are possible:
@@ -5949,33 +5994,80 @@ is made by appending @file{.vrp} to the source file name.
Enable all the available tree dumps with the flags provided in this option.
@end table
+@item -fopt-info
+@itemx -fopt-info-@var{options}
+@itemx -fopt-info-@var{options}=@var{filename}
+@opindex fopt-info
+Controls optimization dumps from all the passes. If the
+@samp{-@var{options}} form is used, @var{options} is a list of
+@samp{-} separated options to control the dump details. If
+@var{options} is not specified, it defaults to @option{optall}. If the
+@var{filename} is not specified, it defaults to @file{stderr}. Note
+that the output @var{filename} will be overwritten in case of multiple
+translation units. If a combined output from multiple translation
+units is desired, @file{stderr} should be used instead.
+
+The following options are available
+
+@table @samp
+@item optimized
+Print information when an optimization is successfully applied. It is
+up to a pass to decide which information is relevant. For example, the
+vectorizer pass prints the location of loop which got vectorized.
+@item missed
+Print information about missed optimizations. Individual passes
+control which information to include in the output. For example,
+
+@smallexample
+gcc -O2 -ftree-vectorize -fopt-info-missed
+@end smallexample
+
+will print information about missed optimization opportunities on
+stderr.
+@item note
+Print verbose information about optimizations, such as certain
+transformations, more detailed messages about decisions etc.
+@item optall
+Print detailed optimization information. This includes
+@var{optimized}, @var{missed}, and @var{note}. For example,
+
+@smallexample
+gcc -O2 -ftree-vectorize -fopt-info-optall=opt.all
+@end smallexample
+
+outputs detailed optimization report from all the passes into
+@file{opt.all}.
+@end table
+
+It applies the dump options to all the passes. If the @var{filename}
+is provided, the dump from all the passes is concatenated, otherwise
+the dump is output onto @file{stderr}. If @var{options} is omitted, it
+defaults to @option{optall}.
+
+@smallexample
+gcc -O3 -fopt-info-optimized-missed=optdump.txt
+@end smallexample
+
+This will output information about missed optimizations as well as
+optimized locations from all the passes into @file{optdump.txt}.
+
@item -ftree-vectorizer-verbose=@var{n}
@opindex ftree-vectorizer-verbose
-This option controls the amount of debugging output the vectorizer prints.
-This information is written to standard error, unless
-@option{-fdump-tree-all} or @option{-fdump-tree-vect} is specified,
-in which case it is output to the usual dump listing file, @file{.vect}.
-For @var{n}=0 no diagnostic information is reported.
-If @var{n}=1 the vectorizer reports each loop that got vectorized,
-and the total number of loops that got vectorized.
-If @var{n}=2 the vectorizer also reports non-vectorized loops that passed
-the first analysis phase (vect_analyze_loop_form) - i.e.@: countable,
-inner-most, single-bb, single-entry/exit loops. This is the same verbosity
-level that @option{-fdump-tree-vect-stats} uses.
-Higher verbosity levels mean either more information dumped for each
-reported loop, or same amount of information reported for more loops:
-if @var{n}=3, vectorizer cost model information is reported.
-If @var{n}=4, alignment related information is added to the reports.
-If @var{n}=5, data-references related information (e.g.@: memory dependences,
-memory access-patterns) is added to the reports.
-If @var{n}=6, the vectorizer reports also non-vectorized inner-most loops
-that did not pass the first analysis phase (i.e., may not be countable, or
-may have complicated control-flow).
-If @var{n}=7, the vectorizer reports also non-vectorized nested loops.
-If @var{n}=8, SLP related information is added to the reports.
-For @var{n}=9, all the information the vectorizer generates during its
-analysis and transformation is reported. This is the same verbosity level
-that @option{-fdump-tree-vect-details} uses.
+This option is deprecated and is implemented in terms of
+@option{-fopt-info}. Please use @option{-fopt-info-@var{kind}} form
+instead, where @var{kind} is one of the valid opt-info options. It
+prints additional optimization information. For @var{n}=0 no
+diagnostic information is reported. If @var{n}=1 the vectorizer
+reports each loop that got vectorized, and the total number of loops
+that got vectorized. If @var{n}=2 the vectorizer reports locations
+which could not be vectorized and the reasons for those. For any
+higher verbosity levels all the analysis and transformation
+information from the vectorizer is reported.
+
+Note that the information output by @option{-ftree-vectorizer-verbose}
+option is sent to @file{stderr}. If the equivalent form
+@option{-fopt-info-@var{options}=@var{filename}} is used then the
+output is sent into @var{filename} instead.
@item -frandom-seed=@var{string}
@opindex frandom-seed
@@ -13969,6 +14061,11 @@ before a transfer of control flow out of the function to minimize
the AVX to SSE transition penalty as well as remove unnecessary @code{zeroupper}
intrinsics.
+@item -mprefer-avx128
+@opindex mprefer-avx128
+This option instructs GCC to use 128-bit AVX instructions instead of
+256-bit AVX instructions in the auto-vectorizer.
+
@item -mcx16
@opindex mcx16
This option enables GCC to generate @code{CMPXCHG16B} instructions.
@@ -17913,6 +18010,15 @@ command line.
By default this feature is not enabled. The default can be restored
via the @option{-mno-pid} command-line option.
+@item -mno-warn-multiple-fast-interrupts
+@itemx -mwarn-multiple-fast-interrupts
+@opindex mno-warn-multiple-fast-interrupts
+@opindex mwarn-multiple-fast-interrupts
+Prevents GCC from issuing a warning message if it finds more than one
+fast interrupt handler when it is compiling a file. The default is to
+issue a warning for each extra fast interrupt handler found, as the RX
+only supports one such interrupt.
+
@end table
@emph{Note:} The generic GCC command-line option @option{-ffixed-@var{reg}}
@@ -18341,26 +18447,67 @@ Dump instruction size and location in the assembly code.
This option is deprecated. It pads structures to multiple of 4 bytes,
which is incompatible with the SH ABI@.
-@item -msoft-atomic
-@opindex msoft-atomic
+@item -matomic-model=@var{model}
+@opindex matomic-model=@var{model}
+Sets the model of atomic operations and additional parameters as a comma
+separated list. For details on the atomic built-in functions see
+@ref{__atomic Builtins}. The following models and parameters are supported:
+
+@table @samp
+
+@item none
+Disable compiler generated atomic sequences and emit library calls for atomic
+operations. This is the default if the target is not @code{sh-*-linux*}.
+
+@item soft-gusa
Generate GNU/Linux compatible gUSA software atomic sequences for the atomic
-built-in functions. The generated atomic sequences require support from the
-interrupt / exception handling code of the system and are only suitable for
-single-core systems. They will not operate correctly on multi-core systems.
-This option is enabled by default when the target is @code{sh-*-linux*}.
-When the target is SH4A, this option will also partially utilize the hardware
-atomic instructions @code{movli.l} and @code{movco.l} to create more
-efficient code.
-For details on the atomic built-in functions see @ref{__atomic Builtins}.
-
-@item -mhard-atomic
-@opindex hard-atomic
-Generate hardware atomic sequences for the atomic built-in functions. This
-is only available on SH4A and is suitable for multi-core systems. Code
-compiled with this option will also be compatible with gUSA aware
-interrupt / exception handling systems. In contrast to the
-@option{-msoft-atomic} option this will only use the instructions
-@code{movli.l} and @code{movco.l} to create atomic sequences.
+built-in functions. The generated atomic sequences require additional support
+from the interrupt/exception handling code of the system and are only suitable
+for SH3* and SH4* single-core systems. This option is enabled by default when
+the target is @code{sh-*-linux*} and SH3* or SH4*. When the target is SH4A,
+this option will also partially utilize the hardware atomic instructions
+@code{movli.l} and @code{movco.l} to create more efficient code, unless
+@samp{strict} is specified.
+
+@item soft-tcb
+Generate software atomic sequences that use a variable in the thread control
+block. This is a variation of the gUSA sequences which can also be used on
+SH1* and SH2* targets. The generated atomic sequences require additional
+support from the interrupt/exception handling code of the system and are only
+suitable for single-core systems. When using this model, the @samp{gbr-offset=}
+parameter has to be specified as well.
+
+@item soft-imask
+Generate software atomic sequences that temporarily disable interrupts by
+setting @code{SR.IMASK = 1111}. This model works only when the program runs
+in privileged mode and is only suitable for single-core systems. Additional
+support from the interrupt/exception handling code of the system is not
+required. This model is enabled by default when the target is
+@code{sh-*-linux*} and SH1* or SH2*.
+
+@item hard-llcs
+Generate hardware atomic sequences using the @code{movli.l} and @code{movco.l}
+instructions only. This is only available on SH4A and is suitable for
+multi-core systems. Since the hardware instructions support only 32 bit atomic
+variables access to 8 or 16 bit variables is emulated with 32 bit accesses.
+Code compiled with this option will also be compatible with other software
+atomic model interrupt/exception handling systems if executed on an SH4A
+system. Additional support from the interrupt/exception handling code of the
+system is not required for this model.
+
+@item gbr-offset=
+This parameter specifies the offset in bytes of the variable in the thread
+control block structure that should be used by the generated atomic sequences
+when the @samp{soft-tcb} model has been selected. For other models this
+parameter is ignored. The specified value must be an integer multiple of four
+and in the range 0-1020.
+
+@item strict
+This parameter prevents mixed usage of multiple atomic models, even though they
+would be compatible, and will make the compiler generate atomic sequences of the
+specified model only.
+
+@end table
@item -mtas
@opindex mtas
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
new file mode 100644
index 000000000..2f610b6c2
--- /dev/null
+++ b/gcc/dumpfile.c
@@ -0,0 +1,868 @@
+/* Dump infrastructure for optimizations and intermediate representation.
+ Copyright (C) 2012 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-core.h"
+#include "dumpfile.h"
+#include "gimple-pretty-print.h"
+#include "tree.h"
+
+/* If non-NULL, return one past-the-end of the matching SUBPART of
+ the WHOLE string. */
+#define skip_leading_substring(whole, part) \
+ (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
+
+static int pflags; /* current dump_flags */
+static int alt_flags; /* current opt_info flags */
+static FILE *alt_dump_file = NULL;
+
+static void dump_loc (int, FILE *, source_location);
+static int dump_enabled_p (int);
+static FILE *dump_open_alternate_stream (struct dump_file_info *);
+
+/* Table of tree dump switches. This must be consistent with the
+ TREE_DUMP_INDEX enumeration in dumpfile.h. */
+static struct dump_file_info dump_files[TDI_end] =
+{
+ {NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0},
+ {".cgraph", "ipa-cgraph", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
+ 0, 0, 0, 0},
+ {".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
+ 0, 0, 0, 1},
+ {".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
+ 0, 0, 0, 2},
+ {".original", "tree-original", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
+ 0, 0, 0, 3},
+ {".gimple", "tree-gimple", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
+ 0, 0, 0, 4},
+ {".nested", "tree-nested", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
+ 0, 0, 0, 5},
+ {".vcg", "tree-vcg", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
+ 0, 0, 0, 6},
+#define FIRST_AUTO_NUMBERED_DUMP 7
+
+ {NULL, "tree-all", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
+ 0, 0, 0, 0},
+ {NULL, "rtl-all", NULL, NULL, NULL, NULL, NULL, TDF_RTL,
+ 0, 0, 0, 0},
+ {NULL, "ipa-all", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
+ 0, 0, 0, 0},
+};
+
+/* Dynamically registered tree dump files and switches. */
+static struct dump_file_info *extra_dump_files;
+static size_t extra_dump_files_in_use;
+static size_t extra_dump_files_alloced;
+
+/* Define a name->number mapping for a dump flag value. */
+struct dump_option_value_info
+{
+ const char *const name; /* the name of the value */
+ const int value; /* the value of the name */
+};
+
+/* Table of dump options. This must be consistent with the TDF_* flags
+ in dumpfile.h and opt_info_options below. */
+static const struct dump_option_value_info dump_options[] =
+{
+ {"address", TDF_ADDRESS},
+ {"asmname", TDF_ASMNAME},
+ {"slim", TDF_SLIM},
+ {"raw", TDF_RAW},
+ {"graph", TDF_GRAPH},
+ {"details", (TDF_DETAILS | MSG_OPTIMIZED_LOCATIONS
+ | MSG_MISSED_OPTIMIZATION
+ | MSG_NOTE)},
+ {"cselib", TDF_CSELIB},
+ {"stats", TDF_STATS},
+ {"blocks", TDF_BLOCKS},
+ {"vops", TDF_VOPS},
+ {"lineno", TDF_LINENO},
+ {"uid", TDF_UID},
+ {"stmtaddr", TDF_STMTADDR},
+ {"memsyms", TDF_MEMSYMS},
+ {"verbose", TDF_VERBOSE},
+ {"eh", TDF_EH},
+ {"alias", TDF_ALIAS},
+ {"nouid", TDF_NOUID},
+ {"enumerate_locals", TDF_ENUMERATE_LOCALS},
+ {"scev", TDF_SCEV},
+ {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
+ | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
+ | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV)},
+ {NULL, 0}
+};
+
+/* A subset of the dump_options table which is used for opt-info
+ options. This must be consistent with the MSG_* flags in
+ dump_options.
+ */
+static const struct dump_option_value_info opt_info_options[] =
+{
+ {"optimized", MSG_OPTIMIZED_LOCATIONS},
+ {"missed", MSG_MISSED_OPTIMIZATION},
+ {"note", MSG_NOTE},
+ {"optall", (MSG_OPTIMIZED_LOCATIONS
+ | MSG_MISSED_OPTIMIZATION
+ | MSG_NOTE)},
+ {NULL, 0}
+};
+
+unsigned int
+dump_register (const char *suffix, const char *swtch, const char *glob,
+ int flags)
+{
+ static int next_dump = FIRST_AUTO_NUMBERED_DUMP;
+ int num = next_dump++;
+
+ size_t count = extra_dump_files_in_use++;
+
+ if (count >= extra_dump_files_alloced)
+ {
+ if (extra_dump_files_alloced == 0)
+ extra_dump_files_alloced = 32;
+ else
+ extra_dump_files_alloced *= 2;
+ extra_dump_files = XRESIZEVEC (struct dump_file_info,
+ extra_dump_files,
+ extra_dump_files_alloced);
+ }
+
+ memset (&extra_dump_files[count], 0, sizeof (struct dump_file_info));
+ extra_dump_files[count].suffix = suffix;
+ extra_dump_files[count].swtch = swtch;
+ extra_dump_files[count].glob = glob;
+ extra_dump_files[count].pflags = flags;
+ extra_dump_files[count].num = num;
+
+ return count + TDI_end;
+}
+
+
+/* Return the dump_file_info for the given phase. */
+
+struct dump_file_info *
+get_dump_file_info (int phase)
+{
+ if (phase < TDI_end)
+ return &dump_files[phase];
+ else if ((size_t) (phase - TDI_end) >= extra_dump_files_in_use)
+ return NULL;
+ else
+ return extra_dump_files + (phase - TDI_end);
+}
+
+
+/* Return the name of the dump file for the given phase.
+ If the dump is not enabled, returns NULL. */
+
+char *
+get_dump_file_name (int phase)
+{
+ char dump_id[10];
+ struct dump_file_info *dfi;
+
+ if (phase == TDI_none)
+ return NULL;
+
+ dfi = get_dump_file_info (phase);
+ if (dfi->pstate == 0)
+ return NULL;
+
+ /* If available, use the command line dump filename. */
+ if (dfi->pfilename)
+ return xstrdup (dfi->pfilename);
+
+ if (dfi->num < 0)
+ dump_id[0] = '\0';
+ else
+ {
+ char suffix;
+ if (dfi->pflags & TDF_TREE)
+ suffix = 't';
+ else if (dfi->pflags & TDF_IPA)
+ suffix = 'i';
+ else
+ suffix = 'r';
+
+ if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
+ dump_id[0] = '\0';
+ }
+
+ return concat (dump_base_name, dump_id, dfi->suffix, NULL);
+}
+
+/* For a given DFI, open an alternate dump filename (which could also
+ be a standard stream such as stdout/stderr). If the alternate dump
+ file cannot be opened, return NULL. */
+
+static FILE *
+dump_open_alternate_stream (struct dump_file_info *dfi)
+{
+ FILE *stream ;
+ if (!dfi->alt_filename)
+ return NULL;
+
+ if (dfi->alt_stream)
+ return dfi->alt_stream;
+
+ stream = strcmp("stderr", dfi->alt_filename) == 0
+ ? stderr
+ : strcmp("stdout", dfi->alt_filename) == 0
+ ? stdout
+ : fopen (dfi->alt_filename, dfi->alt_state < 0 ? "w" : "a");
+
+ if (!stream)
+ error ("could not open dump file %qs: %m", dfi->alt_filename);
+ else
+ dfi->alt_state = 1;
+
+ return stream;
+}
+
+/* Print source location on DFILE if enabled. */
+
+void
+dump_loc (int dump_kind, FILE *dfile, source_location loc)
+{
+ /* Currently vectorization passes print location information. */
+ if (dump_kind)
+ {
+ if (loc == UNKNOWN_LOCATION)
+ fprintf (dfile, "\n%s:%d: note: ",
+ DECL_SOURCE_FILE (current_function_decl),
+ DECL_SOURCE_LINE (current_function_decl));
+ else
+ fprintf (dfile, "\n%d: ", LOCATION_LINE (loc));
+ }
+}
+
+/* Dump gimple statement GS with SPC indentation spaces and
+ EXTRA_DUMP_FLAGS on the dump streams if DUMP_KIND is enabled. */
+
+void
+dump_gimple_stmt (int dump_kind, int extra_dump_flags, gimple gs, int spc)
+{
+ if (dump_file && (dump_kind & pflags))
+ print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
+
+ if (alt_dump_file && (dump_kind & alt_flags))
+ print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
+}
+
+/* Similar to dump_gimple_stmt, except additionally print source location. */
+
+void
+dump_gimple_stmt_loc (int dump_kind, source_location loc, int extra_dump_flags,
+ gimple gs, int spc)
+{
+ if (dump_file && (dump_kind & pflags))
+ {
+ dump_loc (dump_kind, dump_file, loc);
+ print_gimple_stmt (dump_file, gs, spc, dump_flags | extra_dump_flags);
+ }
+
+ if (alt_dump_file && (dump_kind & alt_flags))
+ {
+ dump_loc (dump_kind, alt_dump_file, loc);
+ print_gimple_stmt (alt_dump_file, gs, spc, dump_flags | extra_dump_flags);
+ }
+}
+
+/* Dump expression tree T using EXTRA_DUMP_FLAGS on dump streams if
+ DUMP_KIND is enabled. */
+
+void
+dump_generic_expr (int dump_kind, int extra_dump_flags, tree t)
+{
+ if (dump_file && (dump_kind & pflags))
+ print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
+
+ if (alt_dump_file && (dump_kind & alt_flags))
+ print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
+}
+
+
+/* Similar to dump_generic_expr, except additionally print the source
+ location. */
+
+void
+dump_generic_expr_loc (int dump_kind, source_location loc,
+ int extra_dump_flags, tree t)
+{
+ if (dump_file && (dump_kind & pflags))
+ {
+ dump_loc (dump_kind, dump_file, loc);
+ print_generic_expr (dump_file, t, dump_flags | extra_dump_flags);
+ }
+
+ if (alt_dump_file && (dump_kind & alt_flags))
+ {
+ dump_loc (dump_kind, alt_dump_file, loc);
+ print_generic_expr (alt_dump_file, t, dump_flags | extra_dump_flags);
+ }
+}
+
+/* Output a formatted message using FORMAT on appropriate dump streams. */
+
+void
+dump_printf (int dump_kind, const char *format, ...)
+{
+ if (dump_file && (dump_kind & pflags))
+ {
+ va_list ap;
+ va_start (ap, format);
+ vfprintf (dump_file, format, ap);
+ va_end (ap);
+ }
+
+ if (alt_dump_file && (dump_kind & alt_flags))
+ {
+ va_list ap;
+ va_start (ap, format);
+ vfprintf (alt_dump_file, format, ap);
+ va_end (ap);
+ }
+}
+
+/* Similar to dump_printf, except source location is also printed. */
+
+void
+dump_printf_loc (int dump_kind, source_location loc, const char *format, ...)
+{
+ if (dump_file && (dump_kind & pflags))
+ {
+ va_list ap;
+ dump_loc (dump_kind, dump_file, loc);
+ va_start (ap, format);
+ vfprintf (dump_file, format, ap);
+ va_end (ap);
+ }
+
+ if (alt_dump_file && (dump_kind & alt_flags))
+ {
+ va_list ap;
+ dump_loc (dump_kind, alt_dump_file, loc);
+ va_start (ap, format);
+ vfprintf (alt_dump_file, format, ap);
+ va_end (ap);
+ }
+}
+
+/* Start a dump for PHASE. Store user-supplied dump flags in
+ *FLAG_PTR. Return the number of streams opened. Set globals
+ DUMP_FILE, and ALT_DUMP_FILE to point to the opened streams, and
+ set dump_flags appropriately for both pass dump stream and opt-info
+ stream. */
+
+int
+dump_start (int phase, int *flag_ptr)
+{
+ int count = 0;
+ char *name;
+ struct dump_file_info *dfi;
+ FILE *stream;
+ if (phase == TDI_none || !dump_enabled_p (phase))
+ return 0;
+
+ dfi = get_dump_file_info (phase);
+ name = get_dump_file_name (phase);
+ if (name)
+ {
+ stream = strcmp("stderr", name) == 0
+ ? stderr
+ : strcmp("stdout", name) == 0
+ ? stdout
+ : fopen (name, dfi->pstate < 0 ? "w" : "a");
+ if (!stream)
+ error ("could not open dump file %qs: %m", name);
+ else
+ {
+ dfi->pstate = 1;
+ count++;
+ }
+ free (name);
+ dfi->pstream = stream;
+ dump_file = dfi->pstream;
+ /* Initialize current dump flags. */
+ pflags = dfi->pflags;
+ }
+
+ stream = dump_open_alternate_stream (dfi);
+ if (stream)
+ {
+ dfi->alt_stream = stream;
+ count++;
+ alt_dump_file = dfi->alt_stream;
+ /* Initialize current opt-info flags. */
+ alt_flags = dfi->alt_flags;
+ }
+
+ if (flag_ptr)
+ *flag_ptr = dfi->pflags;
+
+ return count;
+}
+
+/* Finish a tree dump for PHASE and close associated dump streams. Also
+ reset the globals DUMP_FILE, ALT_DUMP_FILE, and DUMP_FLAGS. */
+
+void
+dump_finish (int phase)
+{
+ struct dump_file_info *dfi;
+
+ if (phase < 0)
+ return;
+ dfi = get_dump_file_info (phase);
+ if (dfi->pstream)
+ fclose (dfi->pstream);
+
+ if (dfi->alt_stream && strcmp("stderr", dfi->alt_filename) != 0
+ && strcmp("stdout", dfi->alt_filename) != 0)
+ fclose (dfi->alt_stream);
+
+ dfi->alt_stream = NULL;
+ dfi->pstream = NULL;
+ dump_file = NULL;
+ alt_dump_file = NULL;
+ dump_flags = TDI_none;
+ alt_flags = 0;
+ pflags = 0;
+}
+
+/* Begin a tree dump for PHASE. Stores any user supplied flag in
+ *FLAG_PTR and returns a stream to write to. If the dump is not
+ enabled, returns NULL.
+ Multiple calls will reopen and append to the dump file. */
+
+FILE *
+dump_begin (int phase, int *flag_ptr)
+{
+ char *name;
+ struct dump_file_info *dfi;
+ FILE *stream;
+
+ if (phase == TDI_none || !dump_enabled_p (phase))
+ return NULL;
+
+ name = get_dump_file_name (phase);
+ if (!name)
+ return NULL;
+ dfi = get_dump_file_info (phase);
+
+ stream = strcmp("stderr", name) == 0
+ ? stderr
+ : strcmp("stdout", name) == 0
+ ? stdout
+ : fopen (name, dfi->pstate < 0 ? "w" : "a");
+
+ if (!stream)
+ error ("could not open dump file %qs: %m", name);
+ else
+ dfi->pstate = 1;
+ free (name);
+
+ if (flag_ptr)
+ *flag_ptr = dfi->pflags;
+
+ /* Initialize current flags */
+ pflags = dfi->pflags;
+ return stream;
+}
+
+/* Returns nonzero if dump PHASE is enabled for at least one stream.
+ If PHASE is TDI_tree_all, return nonzero if any dump is enabled for
+ any phase. */
+
+int
+dump_enabled_p (int phase)
+{
+ if (phase == TDI_tree_all)
+ {
+ size_t i;
+ for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
+ if (dump_files[i].pstate || dump_files[i].alt_state)
+ return 1;
+ for (i = 0; i < extra_dump_files_in_use; i++)
+ if (extra_dump_files[i].pstate || extra_dump_files[i].alt_state)
+ return 1;
+ return 0;
+ }
+ else
+ {
+ struct dump_file_info *dfi = get_dump_file_info (phase);
+ return dfi->pstate || dfi->alt_state;
+ }
+}
+
+/* Returns nonzero if tree dump PHASE has been initialized. */
+
+int
+dump_initialized_p (int phase)
+{
+ struct dump_file_info *dfi = get_dump_file_info (phase);
+ return dfi->pstate > 0 || dfi->alt_state > 0;
+}
+
+/* Returns the switch name of PHASE. */
+
+const char *
+dump_flag_name (int phase)
+{
+ struct dump_file_info *dfi = get_dump_file_info (phase);
+ return dfi->swtch;
+}
+
+/* Finish a tree dump for PHASE. STREAM is the stream created by
+ dump_begin. */
+
+void
+dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
+{
+ if (stream != stderr && stream != stdout)
+ fclose (stream);
+}
+
+/* Enable all tree dumps with FLAGS on FILENAME. Return number of
+ enabled tree dumps. */
+
+static int
+dump_enable_all (int flags, const char *filename)
+{
+ int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
+ int n = 0;
+ size_t i;
+
+ for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
+ {
+ if ((dump_files[i].pflags & ir_dump_type))
+ {
+ const char *old_filename = dump_files[i].pfilename;
+ dump_files[i].pstate = -1;
+ dump_files[i].pflags |= flags;
+ n++;
+ /* Override the existing filename. */
+ if (filename)
+ {
+ dump_files[i].pfilename = xstrdup (filename);
+ /* Since it is a command-line provided file, which is
+ common to all the phases, use it in append mode. */
+ dump_files[i].pstate = 1;
+ }
+ if (old_filename && filename != old_filename)
+ free (CONST_CAST (char *, old_filename));
+ }
+ }
+
+ for (i = 0; i < extra_dump_files_in_use; i++)
+ {
+ if ((extra_dump_files[i].pflags & ir_dump_type))
+ {
+ const char *old_filename = extra_dump_files[i].pfilename;
+ extra_dump_files[i].pstate = -1;
+ extra_dump_files[i].pflags |= flags;
+ n++;
+ /* Override the existing filename. */
+ if (filename)
+ {
+ extra_dump_files[i].pfilename = xstrdup (filename);
+ /* Since it is a command-line provided file, which is
+ common to all the phases, use it in append mode. */
+ extra_dump_files[i].pstate = 1;
+ }
+ if (old_filename && filename != old_filename)
+ free (CONST_CAST (char *, old_filename));
+ }
+ }
+
+ return n;
+}
+
+/* Enable opt-info dumps on all IR_DUMP_TYPE passes with FLAGS on
+ FILENAME. Return the number of enabled dumps. */
+
+static int
+opt_info_enable_all (int ir_dump_type, int flags, const char *filename)
+{
+ int n = 0;
+ size_t i;
+
+ for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
+ {
+ if ((dump_files[i].pflags & ir_dump_type))
+ {
+ const char *old_filename = dump_files[i].alt_filename;
+ /* Since this file is shared among different passes, it
+ should be opened in append mode. */
+ dump_files[i].alt_state = 1;
+ dump_files[i].alt_flags |= flags;
+ n++;
+ /* Override the existing filename. */
+ if (filename)
+ dump_files[i].alt_filename = xstrdup (filename);
+ if (old_filename && filename != old_filename)
+ free (CONST_CAST (char *, old_filename));
+ }
+ }
+
+ for (i = 0; i < extra_dump_files_in_use; i++)
+ {
+ if ((extra_dump_files[i].pflags & ir_dump_type))
+ {
+ const char *old_filename = extra_dump_files[i].alt_filename;
+ /* Since this file is shared among different passes, it
+ should be opened in append mode. */
+ extra_dump_files[i].alt_state = 1;
+ extra_dump_files[i].alt_flags |= flags;
+ n++;
+ /* Override the existing filename. */
+ if (filename)
+ extra_dump_files[i].alt_filename = xstrdup (filename);
+ if (old_filename && filename != old_filename)
+ free (CONST_CAST (char *, old_filename));
+ }
+ }
+
+ return n;
+}
+
+/* Parse ARG as a dump switch. Return nonzero if it is, and store the
+ relevant details in the dump_files array. */
+
+static int
+dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
+{
+ const char *option_value;
+ const char *ptr;
+ int flags;
+
+ if (doglob && !dfi->glob)
+ return 0;
+
+ option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
+ if (!option_value)
+ return 0;
+
+ if (*option_value && *option_value != '-' && *option_value != '=')
+ return 0;
+
+ ptr = option_value;
+ flags = 0;
+
+ while (*ptr)
+ {
+ const struct dump_option_value_info *option_ptr;
+ const char *end_ptr;
+ const char *eq_ptr;
+ unsigned length;
+
+ while (*ptr == '-')
+ ptr++;
+ end_ptr = strchr (ptr, '-');
+ eq_ptr = strchr (ptr, '=');
+
+ if (eq_ptr && !end_ptr)
+ end_ptr = eq_ptr;
+
+ if (!end_ptr)
+ end_ptr = ptr + strlen (ptr);
+ length = end_ptr - ptr;
+
+ for (option_ptr = dump_options; option_ptr->name; option_ptr++)
+ if (strlen (option_ptr->name) == length
+ && !memcmp (option_ptr->name, ptr, length))
+ {
+ flags |= option_ptr->value;
+ goto found;
+ }
+
+ if (*ptr == '=')
+ {
+ /* Interpret rest of the argument as a dump filename. This
+ filename overrides other command line filenames. */
+ if (dfi->pfilename)
+ free (CONST_CAST (char *, dfi->pfilename));
+ dfi->pfilename = xstrdup (ptr + 1);
+ break;
+ }
+ else
+ warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
+ length, ptr, dfi->swtch);
+ found:;
+ ptr = end_ptr;
+ }
+
+ dfi->pstate = -1;
+ dfi->pflags |= flags;
+
+ /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
+ known dumps. */
+ if (dfi->suffix == NULL)
+ dump_enable_all (dfi->pflags, dfi->pfilename);
+
+ return 1;
+}
+
+int
+dump_switch_p (const char *arg)
+{
+ size_t i;
+ int any = 0;
+
+ for (i = TDI_none + 1; i != TDI_end; i++)
+ any |= dump_switch_p_1 (arg, &dump_files[i], false);
+
+ /* Don't glob if we got a hit already */
+ if (!any)
+ for (i = TDI_none + 1; i != TDI_end; i++)
+ any |= dump_switch_p_1 (arg, &dump_files[i], true);
+
+ for (i = 0; i < extra_dump_files_in_use; i++)
+ any |= dump_switch_p_1 (arg, &extra_dump_files[i], false);
+
+ if (!any)
+ for (i = 0; i < extra_dump_files_in_use; i++)
+ any |= dump_switch_p_1 (arg, &extra_dump_files[i], true);
+
+
+ return any;
+}
+
+/* Parse ARG as a -fopt-info switch and store flags and filename.
+ Return non-zero if it is a recognized switch. */
+
+static int
+opt_info_switch_p_1 (const char *arg, int *flags, char **filename)
+{
+ const char *option_value;
+ const char *ptr;
+
+ option_value = arg;
+ ptr = option_value;
+
+ *filename = NULL;
+ *flags = 0;
+
+ if (!ptr)
+ return 1;
+
+ while (*ptr)
+ {
+ const struct dump_option_value_info *option_ptr;
+ const char *end_ptr;
+ const char *eq_ptr;
+ unsigned length;
+
+ while (*ptr == '-')
+ ptr++;
+ end_ptr = strchr (ptr, '-');
+ eq_ptr = strchr (ptr, '=');
+
+ if (eq_ptr && !end_ptr)
+ end_ptr = eq_ptr;
+
+ if (!end_ptr)
+ end_ptr = ptr + strlen (ptr);
+ length = end_ptr - ptr;
+
+ for (option_ptr = opt_info_options; option_ptr->name; option_ptr++)
+ if (strlen (option_ptr->name) == length
+ && !memcmp (option_ptr->name, ptr, length))
+ {
+ *flags |= option_ptr->value;
+ goto found;
+ }
+
+ if (*ptr == '=')
+ {
+ /* Interpret rest of the argument as a dump filename. This
+ filename overrides other command line filenames. */
+ *filename = xstrdup (ptr + 1);
+ break;
+ }
+ else
+ warning (0, "ignoring unknown option %q.*s in %<-fopt-info=%s%>",
+ length, ptr, arg);
+ found:;
+ ptr = end_ptr;
+ }
+
+ return 1;
+}
+
+/* Return non-zero if ARG is a recognized switch for
+ -fopt-info. Return zero otherwise. */
+
+int
+opt_info_switch_p (const char *arg)
+{
+ int flags;
+ char *filename;
+
+ opt_info_switch_p_1 (arg, &flags, &filename);
+
+ if (!filename)
+ filename = xstrdup ("stderr");
+ if (!flags)
+ flags = MSG_ALL;
+
+ return opt_info_enable_all ((TDF_TREE | TDF_RTL | TDF_IPA), flags, filename);
+}
+
+/* Return true if any dumps are enabled for the given MSG_TYPE, false
+ otherwise. */
+
+bool
+dump_kind_p (int msg_type)
+{
+ if (!current_function_decl)
+ return 0;
+ return ((msg_type & pflags) || (msg_type & alt_flags));
+}
+
+/* Print basic block on the dump streams. */
+
+void
+dump_basic_block (int dump_kind, basic_block bb, int indent)
+{
+ if (dump_file && (dump_kind & pflags))
+ dump_bb (dump_file, bb, indent, TDF_DETAILS);
+ if (alt_dump_file && (dump_kind & alt_flags))
+ dump_bb (alt_dump_file, bb, indent, TDF_DETAILS);
+}
+
+/* Print information from the combine pass on dump_file. */
+
+void
+print_combine_total_stats (void)
+{
+ if (dump_file)
+ dump_combine_total_stats (dump_file);
+}
+
+/* Enable RTL dump for all the RTL passes. */
+
+bool
+enable_rtl_dump_file (void)
+{
+ return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS, NULL) > 0;
+}
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index 2ea3901b3..87a2c7286 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -22,6 +22,8 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_DUMPFILE_H
#define GCC_DUMPFILE_H 1
+#include "line-map.h"
+
/* Different tree dump places. When you add new tree dump places,
extend the DUMP_FILES array in tree-dump.c. */
enum tree_dump_index
@@ -35,7 +37,6 @@ enum tree_dump_index
TDI_nested, /* dump each function after unnesting it */
TDI_vcg, /* create a VCG graph file for each
function's flowgraph. */
- TDI_ada, /* dump declarations in Ada syntax. */
TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */
TDI_rtl_all, /* enable all the RTL dumps. */
TDI_ipa_all, /* enable all the IPA dumps. */
@@ -43,9 +44,11 @@ enum tree_dump_index
TDI_end
};
-/* Bit masks to control dumping. Not all values are applicable to
- all dumps. Add new ones at the end. When you define new
- values, extend the DUMP_OPTIONS array in tree-dump.c */
+/* Bit masks to control dumping. Not all values are applicable to all
+ dumps. Add new ones at the end. When you define new values, extend
+ the DUMP_OPTIONS array in tree-dump.c. The TDF_* flags coexist with
+ MSG_* flags (for -fopt-info) and the bit values must be chosen
+ to allow that. */
#define TDF_ADDRESS (1 << 0) /* dump node addresses */
#define TDF_SLIM (1 << 1) /* don't go wild following links */
#define TDF_RAW (1 << 2) /* don't unparse the function */
@@ -82,18 +85,59 @@ enum tree_dump_index
#define TDF_CSELIB (1 << 23) /* Dump cselib details. */
#define TDF_SCEV (1 << 24) /* Dump SCEV details. */
#define TDF_COMMENT (1 << 25) /* Dump lines with prefix ";;" */
+#define MSG_OPTIMIZED_LOCATIONS (1 << 26) /* -fopt-info optimized sources */
+#define MSG_MISSED_OPTIMIZATION (1 << 27) /* missed opportunities */
+#define MSG_NOTE (1 << 28) /* general optimization info */
+#define MSG_ALL (MSG_OPTIMIZED_LOCATIONS | MSG_MISSED_OPTIMIZATION \
+ | MSG_NOTE)
+/* Define a tree dump switch. */
+struct dump_file_info
+{
+ const char *suffix; /* suffix to give output file. */
+ const char *swtch; /* command line dump switch */
+ const char *glob; /* command line glob */
+ const char *pfilename; /* filename for the pass-specific stream */
+ const char *alt_filename; /* filename for the opt-info stream */
+ FILE *pstream; /* pass-specific dump stream */
+ FILE *alt_stream; /* opt-info stream */
+ int pflags; /* dump flags */
+ int alt_flags; /* flags for opt-info */
+ int pstate; /* state of pass-specific stream */
+ int alt_state; /* state of the opt-info stream */
+ int num; /* dump file number */
+};
-/* In tree-dump.c */
+/* In dumpfile.c */
extern char *get_dump_file_name (int);
-extern int dump_enabled_p (int);
extern int dump_initialized_p (int);
extern FILE *dump_begin (int, int *);
extern void dump_end (int, FILE *);
+extern int dump_start (int, int *);
+extern void dump_finish (int);
extern void dump_node (const_tree, int, FILE *);
extern int dump_switch_p (const char *);
+extern int opt_info_switch_p (const char *);
extern const char *dump_flag_name (int);
+extern bool dump_kind_p (int);
+extern void dump_printf (int, const char *, ...) ATTRIBUTE_PRINTF_2;
+extern void dump_printf_loc (int, source_location,
+ const char *, ...) ATTRIBUTE_PRINTF_3;
+extern void dump_basic_block (int, basic_block, int);
+extern void dump_generic_expr_loc (int, source_location, int, tree);
+extern void dump_generic_expr (int, int, tree);
+extern void dump_gimple_stmt_loc (int, source_location, int, gimple, int);
+extern void dump_gimple_stmt (int, int, gimple, int);
+extern void print_combine_total_stats (void);
+extern unsigned int dump_register (const char *, const char *, const char *,
+ int);
+extern bool enable_rtl_dump_file (void);
+
+/* In combine.c */
+extern void dump_combine_total_stats (FILE *);
+/* In cfghooks.c */
+extern void dump_bb (FILE *, basic_block, int, int);
/* Global variables used to communicate with passes. */
extern FILE *dump_file;
@@ -103,16 +147,4 @@ extern const char *dump_file_name;
/* Return the dump_file_info for the given phase. */
extern struct dump_file_info *get_dump_file_info (int);
-/* Define a tree dump switch. */
-struct dump_file_info
-{
- const char *suffix; /* suffix to give output file. */
- const char *swtch; /* command line switch */
- const char *glob; /* command line glob */
- int flags; /* user flags */
- int state; /* state of play */
- int num; /* dump file number */
-};
-
-
#endif /* GCC_DUMPFILE_H */
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index c776f682b..95fc130c3 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -7491,6 +7491,8 @@ value_format (dw_attr_ref a)
return DW_FORM_block1;
case 2:
return DW_FORM_block2;
+ case 4:
+ return DW_FORM_block4;
default:
gcc_unreachable ();
}
@@ -17327,7 +17329,7 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
a BLOCK node representing the function's outermost pair of curly braces,
and any blocks used for the base and member initializers of a C++
constructor function. */
- if (! declaration && TREE_CODE (outer_scope) != ERROR_MARK)
+ if (! declaration && outer_scope && TREE_CODE (outer_scope) != ERROR_MARK)
{
int call_site_note_count = 0;
int tail_call_site_note_count = 0;
@@ -19620,8 +19622,14 @@ dwarf2out_decl (tree decl)
inline" functions as DECL_EXTERNAL, but we need to generate DWARF for
them anyway. Note that the C++ front-end also plays some similar games
for inline function definitions appearing within include files which
- also contain `#pragma interface' pragmas. */
- if (DECL_INITIAL (decl) == NULL_TREE)
+ also contain `#pragma interface' pragmas.
+
+ If we are called from dwarf2out_abstract_function output a DIE
+ anyway. We can end up here this way with early inlining and LTO
+ where the inlined function is output in a different LTRANS unit
+ or not at all. */
+ if (DECL_INITIAL (decl) == NULL_TREE
+ && ! DECL_ABSTRACT (decl))
return;
/* If we're a nested function, initially use a parent of NULL; if we're
diff --git a/gcc/expr.c b/gcc/expr.c
index c180e8d5e..1adea93c3 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -5491,7 +5491,7 @@ categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
{
HOST_WIDE_INT mult = 1;
- if (TREE_CODE (purpose) == RANGE_EXPR)
+ if (purpose && TREE_CODE (purpose) == RANGE_EXPR)
{
tree lo_index = TREE_OPERAND (purpose, 0);
tree hi_index = TREE_OPERAND (purpose, 1);
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index b503c9f4f..d6c261007 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -200,20 +200,4 @@ enum fp_contract_mode {
FP_CONTRACT_FAST = 2
};
-/* Vectorizer verbosity levels. */
-enum vect_verbosity_levels {
- REPORT_NONE,
- REPORT_VECTORIZED_LOCATIONS,
- REPORT_UNVECTORIZED_LOCATIONS,
- REPORT_COST,
- REPORT_ALIGNMENT,
- REPORT_DR_DETAILS,
- REPORT_BAD_FORM_LOOPS,
- REPORT_OUTER_LOOPS,
- REPORT_SLP,
- REPORT_DETAILS,
- /* New verbosity levels should be added before this one. */
- MAX_VERBOSITY_LEVEL
-};
-
#endif /* ! GCC_FLAG_TYPES_H */
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index e1cb45aff..7a3092a42 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,41 @@
+2012-10-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54832
+ * resolve.c (resolve_fl_derived0): Correctly copy the 'class_ok'
+ attribute for proc-ptr components with RESULT variable.
+
+2012-10-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/45521
+ * interface.c (generic_correspondence): Implement additional
+ distinguishability criteria of F08.
+ (compare_actual_formal): Reject data object as actual argument for
+ procedure formal argument.
+
+2012-10-04 Tobias Burnus <burnus@net-b.de>
+
+ * expr.c (scalarize_intrinsic_call): Plug memory leak.
+ * frontend-passes.c (gcc_assert): Extend assert.
+ * interface.c (gfc_compare_derived_types): Fix comparison.
+ (gfc_check_operator_interface): Move up to make this error
+ message reachable.
+ (get_sym_storage_size): Remove always-true checks.
+ * io.c (format_lex): Add comment.
+ (gfc_free_wait): Free memory.
+ * match.c (gfc_match_select_type): Ditto.
+ * matchexpr.c (match_level_3): Ditto.
+ * primary.c (match_string_constant): Ditto.
+ (match_actual_arg): Check return value.
+ * resolve.c (gfc_resolve_substring_charlen,
+ resolve_typebound_generic_call, resolve_typebound_function,
+ resolve_typebound_subroutine): Free memory.
+ * trans-types.c (gfc_get_derived_type): Remove always-true check.
+
+2012-10-02 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54778
+ * interface.c (matching_typebound_op): Check for 'class_ok' attribute.
+
2012-09-30 Janus Weil <janus@gcc.gnu.org>
PR fortran/54667
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 4bba438c2..9ac0fc685 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -2059,6 +2059,8 @@ scalarize_intrinsic_call (gfc_expr *e)
free_expr0 (e);
*e = *expr;
+ /* Free "expr" but not the pointers it contains. */
+ free (expr);
gfc_free_expr (old);
return SUCCESS;
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index 437ed7ec1..0cba9112a 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -1177,7 +1177,7 @@ optimize_trim (gfc_expr *e)
/* Set the end of the reference to the call to len_trim. */
ref->u.ss.end = fcn;
- gcc_assert (*rr == NULL);
+ gcc_assert (rr != NULL && *rr == NULL);
*rr = ref;
return true;
}
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 88689aa47..4822149cc 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -449,7 +449,7 @@ gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2)
/* Make sure that link lists do not put this function into an
endless recursive loop! */
if (!(dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived)
- && !(dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived)
+ && !(dt2->ts.type == BT_DERIVED && derived2 == dt2->ts.u.derived)
&& gfc_compare_types (&dt1->ts, &dt2->ts) == 0)
return 0;
@@ -641,8 +641,12 @@ gfc_check_operator_interface (gfc_symbol *sym, gfc_intrinsic_op op,
&& op != INTRINSIC_NOT)
|| (args == 2 && op == INTRINSIC_NOT))
{
- gfc_error ("Operator interface at %L has the wrong number of arguments",
- &sym->declared_at);
+ if (op == INTRINSIC_ASSIGN)
+ gfc_error ("Assignment operator interface at %L must have "
+ "two arguments", &sym->declared_at);
+ else
+ gfc_error ("Operator interface at %L has the wrong number of arguments",
+ &sym->declared_at);
return false;
}
@@ -656,12 +660,6 @@ gfc_check_operator_interface (gfc_symbol *sym, gfc_intrinsic_op op,
"a SUBROUTINE", &sym->declared_at);
return false;
}
- if (args != 2)
- {
- gfc_error ("Assignment operator interface at %L must have "
- "two arguments", &sym->declared_at);
- return false;
- }
/* Allowed are (per F2003, 12.3.2.1.2 Defined assignments):
- First argument an array with different rank than second,
@@ -934,9 +932,9 @@ count_types_test (gfc_formal_arglist *f1, gfc_formal_arglist *f2,
}
-/* Perform the correspondence test in rule 3 of section F03:16.2.3.
- Returns zero if no argument is found that satisfies rule 3, nonzero
- otherwise. 'p1' and 'p2' are the PASS arguments of both procedures
+/* Perform the correspondence test in rule (3) of F08:C1215.
+ Returns zero if no argument is found that satisfies this rule,
+ nonzero otherwise. 'p1' and 'p2' are the PASS arguments of both procedures
(if applicable).
This test is also not symmetric in f1 and f2 and must be called
@@ -944,13 +942,13 @@ count_types_test (gfc_formal_arglist *f1, gfc_formal_arglist *f2,
argument list with keywords. For example:
INTERFACE FOO
- SUBROUTINE F1(A, B)
- INTEGER :: A ; REAL :: B
- END SUBROUTINE F1
+ SUBROUTINE F1(A, B)
+ INTEGER :: A ; REAL :: B
+ END SUBROUTINE F1
- SUBROUTINE F2(B, A)
- INTEGER :: A ; REAL :: B
- END SUBROUTINE F1
+ SUBROUTINE F2(B, A)
+ INTEGER :: A ; REAL :: B
+ END SUBROUTINE F1
END INTERFACE FOO
At this point, 'CALL FOO(A=1, B=1.0)' is ambiguous. */
@@ -975,7 +973,10 @@ generic_correspondence (gfc_formal_arglist *f1, gfc_formal_arglist *f2,
f2 = f2->next;
if (f2 != NULL && (compare_type_rank (f1->sym, f2->sym)
- || compare_type_rank (f2->sym, f1->sym)))
+ || compare_type_rank (f2->sym, f1->sym))
+ && !((gfc_option.allow_std & GFC_STD_F2008)
+ && ((f1->sym->attr.allocatable && f2->sym->attr.pointer)
+ || (f2->sym->attr.allocatable && f1->sym->attr.pointer))))
goto next;
/* Now search for a disambiguating keyword argument starting at
@@ -986,7 +987,10 @@ generic_correspondence (gfc_formal_arglist *f1, gfc_formal_arglist *f2,
continue;
sym = find_keyword_arg (g->sym->name, f2_save);
- if (sym == NULL || !compare_type_rank (g->sym, sym))
+ if (sym == NULL || !compare_type_rank (g->sym, sym)
+ || ((gfc_option.allow_std & GFC_STD_F2008)
+ && ((sym->attr.allocatable && g->sym->attr.pointer)
+ || (sym->attr.pointer && g->sym->attr.allocatable))))
return 1;
}
@@ -2149,7 +2153,7 @@ get_sym_storage_size (gfc_symbol *sym)
return 0;
for (i = 0; i < sym->as->rank; i++)
{
- if (!sym->as || sym->as->upper[i]->expr_type != EXPR_CONSTANT
+ if (sym->as->upper[i]->expr_type != EXPR_CONSTANT
|| sym->as->lower[i]->expr_type != EXPR_CONSTANT)
return 0;
@@ -2224,9 +2228,7 @@ get_expr_storage_size (gfc_expr *e)
continue;
}
- if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION
- && ref->u.ar.start && ref->u.ar.end && ref->u.ar.stride
- && ref->u.ar.as->upper)
+ if (ref->type == REF_ARRAY && ref->u.ar.type == AR_SECTION)
for (i = 0; i < ref->u.ar.dimen; i++)
{
long int start, end, stride;
@@ -2555,8 +2557,8 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
skip_size_check:
- /* Satisfy 12.4.1.3 by ensuring that a procedure pointer actual argument
- is provided for a procedure pointer formal argument. */
+ /* Satisfy F03:12.4.1.3 by ensuring that a procedure pointer actual
+ argument is provided for a procedure pointer formal argument. */
if (f->sym->attr.proc_pointer
&& !((a->expr->expr_type == EXPR_VARIABLE
&& a->expr->symtree->n.sym->attr.proc_pointer)
@@ -2570,11 +2572,10 @@ compare_actual_formal (gfc_actual_arglist **ap, gfc_formal_arglist *formal,
return 0;
}
- /* Satisfy 12.4.1.2 by ensuring that a procedure actual argument is
+ /* Satisfy F03:12.4.1.3 by ensuring that a procedure actual argument is
provided for a procedure formal argument. */
- if (a->expr->ts.type != BT_PROCEDURE && !gfc_is_proc_ptr_comp (a->expr)
- && a->expr->expr_type == EXPR_VARIABLE
- && f->sym->attr.flavor == FL_PROCEDURE)
+ if (f->sym->attr.flavor == FL_PROCEDURE
+ && gfc_expr_attr (a->expr).flavor != FL_PROCEDURE)
{
if (where)
gfc_error ("Expected a procedure for argument '%s' at %L",
@@ -3386,7 +3387,8 @@ matching_typebound_op (gfc_expr** tb_base,
if (base->expr->ts.type == BT_CLASS)
{
- if (CLASS_DATA (base->expr) == NULL)
+ if (CLASS_DATA (base->expr) == NULL
+ || !gfc_expr_attr (base->expr).class_ok)
continue;
derived = CLASS_DATA (base->expr)->ts.u.derived;
}
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
index 428799c12..447d03f0d 100644
--- a/gcc/fortran/io.c
+++ b/gcc/fortran/io.c
@@ -243,6 +243,8 @@ format_lex (void)
{
case '-':
negative_flag = 1;
+ /* Falls through. */
+
case '+':
c = next_char_not_space (&error);
if (!ISDIGIT (c))
@@ -4117,6 +4119,7 @@ gfc_free_wait (gfc_wait *wait)
gfc_free_expr (wait->iostat);
gfc_free_expr (wait->iomsg);
gfc_free_expr (wait->id);
+ free (wait);
}
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index d46a495ae..06585af94 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -5325,6 +5325,7 @@ gfc_match_select_type (void)
char name[GFC_MAX_SYMBOL_LEN];
bool class_array;
gfc_symbol *sym;
+ gfc_namespace *parent_ns;
m = gfc_match_label ();
if (m == MATCH_ERROR)
@@ -5404,7 +5405,9 @@ gfc_match_select_type (void)
return MATCH_YES;
cleanup:
- gfc_current_ns = gfc_current_ns->parent;
+ parent_ns = gfc_current_ns->parent;
+ gfc_free_namespace (gfc_current_ns);
+ gfc_current_ns = parent_ns;
return m;
}
diff --git a/gcc/fortran/matchexp.c b/gcc/fortran/matchexp.c
index 12d5b2dcb..c1196a880 100644
--- a/gcc/fortran/matchexp.c
+++ b/gcc/fortran/matchexp.c
@@ -543,7 +543,7 @@ match_level_2 (gfc_expr **result)
static match
match_level_3 (gfc_expr **result)
{
- gfc_expr *all, *e, *total;
+ gfc_expr *all, *e, *total = NULL;
locus where;
match m;
@@ -560,12 +560,12 @@ match_level_3 (gfc_expr **result)
m = match_level_2 (&e);
if (m == MATCH_NO)
+ gfc_error (expression_syntax);
+ if (m != MATCH_YES)
{
- gfc_error (expression_syntax);
gfc_free_expr (all);
+ return MATCH_ERROR;
}
- if (m != MATCH_YES)
- return MATCH_ERROR;
total = gfc_concat (all, e);
if (total == NULL)
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index f362f7542..7b64a3c68 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1087,6 +1087,7 @@ got_delim:
if (!gfc_check_character_range (c, kind))
{
+ gfc_free_expr (e);
gfc_error ("Character '%s' in string at %C is not representable "
"in character kind %d", gfc_print_wide_char (c), kind);
return MATCH_ERROR;
@@ -1507,8 +1508,9 @@ match_actual_arg (gfc_expr **result)
if (sym->attr.in_common && !sym->attr.proc_pointer)
{
- gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name,
- &sym->declared_at);
+ if (gfc_add_flavor (&sym->attr, FL_VARIABLE, sym->name,
+ &sym->declared_at) == FAILURE)
+ return MATCH_ERROR;
break;
}
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index 3e23ca2e3..722e03651 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -4964,7 +4964,11 @@ gfc_resolve_substring_charlen (gfc_expr *e)
end = NULL;
if (!start || !end)
- return;
+ {
+ gfc_free_expr (start);
+ gfc_free_expr (end);
+ return;
+ }
/* Length = (end - start +1). */
e->ts.u.cl->length = gfc_subtract (end, start);
@@ -6004,7 +6008,10 @@ resolve_typebound_generic_call (gfc_expr* e, const char **name)
gfc_expr* po;
po = extract_compcall_passed_object (e);
if (!po)
- return FAILURE;
+ {
+ gfc_free_actual_arglist (args);
+ return FAILURE;
+ }
gcc_assert (g->specific->pass_arg_num > 0);
gcc_assert (!g->specific->error);
@@ -6253,7 +6260,10 @@ resolve_typebound_function (gfc_expr* e)
/* Treat the call as if it is a typebound procedure, in order to roll
out the correct name for the specific function. */
if (resolve_compcall (e, &name) == FAILURE)
- return FAILURE;
+ {
+ gfc_free_ref_list (new_ref);
+ return FAILURE;
+ }
ts = e->ts;
if (overridable)
@@ -6374,7 +6384,10 @@ resolve_typebound_subroutine (gfc_code *code)
}
if (resolve_typebound_call (code, &name) == FAILURE)
- return FAILURE;
+ {
+ gfc_free_ref_list (new_ref);
+ return FAILURE;
+ }
ts = code->expr1->ts;
if (overridable)
@@ -12009,6 +12022,7 @@ resolve_fl_derived0 (gfc_symbol *sym)
c->attr.pointer = ifc->result->attr.pointer;
c->attr.dimension = ifc->result->attr.dimension;
c->as = gfc_copy_array_spec (ifc->result->as);
+ c->attr.class_ok = ifc->result->attr.class_ok;
}
else
{
@@ -12017,6 +12031,7 @@ resolve_fl_derived0 (gfc_symbol *sym)
c->attr.pointer = ifc->attr.pointer;
c->attr.dimension = ifc->attr.dimension;
c->as = gfc_copy_array_spec (ifc->as);
+ c->attr.class_ok = ifc->attr.class_ok;
}
c->ts.interface = ifc;
c->attr.function = ifc->attr.function;
@@ -12028,7 +12043,6 @@ resolve_fl_derived0 (gfc_symbol *sym)
c->attr.recursive = ifc->attr.recursive;
c->attr.always_explicit = ifc->attr.always_explicit;
c->attr.ext_attr |= ifc->attr.ext_attr;
- c->attr.class_ok = ifc->attr.class_ok;
/* Replace symbols in array spec. */
if (c->as)
{
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index 3286a5a6f..81b7fa5ca 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -2445,7 +2445,7 @@ gfc_get_derived_type (gfc_symbol * derived)
|| c->ts.u.derived->backend_decl == NULL)
c->ts.u.derived->backend_decl = gfc_get_derived_type (c->ts.u.derived);
- if (c->ts.u.derived && c->ts.u.derived->attr.is_iso_c)
+ if (c->ts.u.derived->attr.is_iso_c)
{
/* Need to copy the modified ts from the derived type. The
typespec was modified because C_PTR/C_FUNPTR are translated
diff --git a/gcc/gcc.c b/gcc/gcc.c
index af3c34acf..bbca6d84e 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1988,7 +1988,10 @@ record_temp_file (const char *filename, int always_delete, int fail_delete)
struct temp_file *temp;
for (temp = failure_delete_queue; temp; temp = temp->next)
if (! filename_cmp (name, temp->name))
- goto already2;
+ {
+ free (name);
+ goto already2;
+ }
temp = XNEW (struct temp_file);
temp->next = failure_delete_queue;
@@ -2462,8 +2465,11 @@ add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
if (target_sysroot_suffix)
- prefix = concat (target_sysroot_suffix, prefix, NULL);
- prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
+ prefix = concat (sysroot_no_trailing_dir_separator,
+ target_sysroot_suffix, prefix, NULL);
+ else
+ prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
+
free (sysroot_no_trailing_dir_separator);
/* We have to override this because GCC's notion of sysroot
@@ -3571,7 +3577,7 @@ process_command (unsigned int decoded_options_count,
{
const char *temp;
char *temp1;
- const char *tooldir_prefix;
+ char *tooldir_prefix, *tooldir_prefix2;
char *(*get_relative_prefix) (const char *, const char *,
const char *) = NULL;
struct cl_option_handlers handlers;
@@ -3920,15 +3926,16 @@ process_command (unsigned int decoded_options_count,
}
gcc_assert (!IS_ABSOLUTE_PATH (tooldir_base_prefix));
- tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
- dir_separator_str, NULL);
+ tooldir_prefix2 = concat (tooldir_base_prefix, spec_machine,
+ dir_separator_str, NULL);
/* Look for tools relative to the location from which the driver is
running, or, if that is not available, the configured prefix. */
tooldir_prefix
= concat (gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
spec_machine, dir_separator_str,
- spec_version, dir_separator_str, tooldir_prefix, NULL);
+ spec_version, dir_separator_str, tooldir_prefix2, NULL);
+ free (tooldir_prefix2);
add_prefix (&exec_prefixes,
concat (tooldir_prefix, "bin", dir_separator_str, NULL),
@@ -3936,6 +3943,7 @@ process_command (unsigned int decoded_options_count,
add_prefix (&startfile_prefixes,
concat (tooldir_prefix, "lib", dir_separator_str, NULL),
"BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
+ free (tooldir_prefix);
#if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
/* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
@@ -4319,6 +4327,7 @@ do_self_spec (const char *spec)
argbuf_copy,
CL_DRIVER, &decoded_options,
&decoded_options_count);
+ free (argbuf_copy);
set_option_handlers (&handlers);
@@ -4740,8 +4749,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
memcpy (tmp, save_temps_prefix, save_temps_length);
memcpy (tmp + save_temps_length, suffix, suffix_length);
tmp[save_temps_length + suffix_length] = '\0';
- temp_filename = save_string (tmp,
- temp_filename_length + 1);
+ temp_filename = save_string (tmp, save_temps_length
+ + suffix_length);
obstack_grow (&obstack, temp_filename,
temp_filename_length);
arg_going = 1;
@@ -5055,6 +5064,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
/* This option is new; add it. */
add_linker_option (string, strlen (string));
+ free (string);
}
break;
@@ -8186,7 +8196,7 @@ static const char *
compare_debug_dump_opt_spec_function (int arg,
const char **argv ATTRIBUTE_UNUSED)
{
- const char *ret;
+ char *ret;
char *name;
int which;
static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
@@ -8240,8 +8250,12 @@ compare_debug_dump_opt_spec_function (int arg,
}
if (*random_seed)
- ret = concat ("%{!frandom-seed=*:-frandom-seed=", random_seed, "} ",
- ret, NULL);
+ {
+ char *tmp = ret;
+ ret = concat ("%{!frandom-seed=*:-frandom-seed=", random_seed, "} ",
+ ret, NULL);
+ free (tmp);
+ }
if (which)
*random_seed = 0;
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 2ae43726b..213567653 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -2810,6 +2810,7 @@ walk_type (type_p t, struct walk_type_data *d)
const char *oldval = d->val;
const char *oldprevval1 = d->prev_val[1];
const char *oldprevval2 = d->prev_val[2];
+ const char *struct_mark_hook = NULL;
const int union_p = t->kind == TYPE_UNION;
int seen_default_p = 0;
options_p o;
@@ -2833,6 +2834,13 @@ walk_type (type_p t, struct walk_type_data *d)
if (!desc && strcmp (o->name, "desc") == 0
&& o->kind == OPTION_STRING)
desc = o->info.string;
+ else if (!struct_mark_hook && strcmp (o->name, "mark_hook") == 0
+ && o->kind == OPTION_STRING)
+ struct_mark_hook = o->info.string;
+
+ if (struct_mark_hook)
+ oprintf (d->of, "%*s%s (&%s);\n",
+ d->indent, "", struct_mark_hook, oldval);
d->prev_val[2] = oldval;
d->prev_val[1] = oldprevval2;
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 424ad550d..677e41f26 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -425,6 +425,14 @@ lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
case GIMPLE_CALL:
{
tree decl = gimple_call_fndecl (stmt);
+ unsigned i;
+
+ for (i = 0; i < gimple_call_num_args (stmt); i++)
+ {
+ tree arg = gimple_call_arg (stmt, i);
+ if (EXPR_P (arg))
+ TREE_SET_BLOCK (arg, data->block);
+ }
if (decl
&& DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index e4550c011..4b3235edf 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -69,7 +69,7 @@ maybe_init_pretty_print (FILE *file)
}
-/* Emit a newline and SPC indentantion spaces to BUFFER. */
+/* Emit a newline and SPC indentation spaces to BUFFER. */
static void
newline_and_indent (pretty_printer *buffer, int spc)
@@ -89,20 +89,20 @@ debug_gimple_stmt (gimple gs)
}
-/* Dump GIMPLE statement G to FILE using SPC indentantion spaces and
- FLAGS as in dump_gimple_stmt. */
+/* Print GIMPLE statement G to FILE using SPC indentation spaces and
+ FLAGS as in pp_gimple_stmt_1. */
void
print_gimple_stmt (FILE *file, gimple g, int spc, int flags)
{
maybe_init_pretty_print (file);
- dump_gimple_stmt (&buffer, g, spc, flags);
+ pp_gimple_stmt_1 (&buffer, g, spc, flags);
pp_newline_and_flush (&buffer);
}
-/* Dump GIMPLE statement G to FILE using SPC indentantion spaces and
- FLAGS as in dump_gimple_stmt. Print only the right-hand side
+/* Print GIMPLE statement G to FILE using SPC indentation spaces and
+ FLAGS as in pp_gimple_stmt_1. Print only the right-hand side
of the statement. */
void
@@ -110,12 +110,12 @@ print_gimple_expr (FILE *file, gimple g, int spc, int flags)
{
flags |= TDF_RHS_ONLY;
maybe_init_pretty_print (file);
- dump_gimple_stmt (&buffer, g, spc, flags);
+ pp_gimple_stmt_1 (&buffer, g, spc, flags);
}
-/* Print the GIMPLE sequence SEQ on BUFFER using SPC indentantion
- spaces and FLAGS as in dump_gimple_stmt.
+/* Print the GIMPLE sequence SEQ on BUFFER using SPC indentation
+ spaces and FLAGS as in pp_gimple_stmt_1.
The caller is responsible for calling pp_flush on BUFFER to finalize
the pretty printer. */
@@ -128,15 +128,15 @@ dump_gimple_seq (pretty_printer *buffer, gimple_seq seq, int spc, int flags)
{
gimple gs = gsi_stmt (i);
INDENT (spc);
- dump_gimple_stmt (buffer, gs, spc, flags);
+ pp_gimple_stmt_1 (buffer, gs, spc, flags);
if (!gsi_one_before_end_p (i))
pp_newline (buffer);
}
}
-/* Dump GIMPLE sequence SEQ to FILE using SPC indentantion spaces and
- FLAGS as in dump_gimple_stmt. */
+/* Print GIMPLE sequence SEQ to FILE using SPC indentation spaces and
+ FLAGS as in pp_gimple_stmt_1. */
void
print_gimple_seq (FILE *file, gimple_seq seq, int spc, int flags)
@@ -245,7 +245,7 @@ dump_gimple_fmt (pretty_printer *buffer, int spc, int flags,
/* Helper for dump_gimple_assign. Print the unary RHS of the
- assignment GS. BUFFER, SPC and FLAGS are as in dump_gimple_stmt. */
+ assignment GS. BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1. */
static void
dump_unary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -329,7 +329,7 @@ dump_unary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
/* Helper for dump_gimple_assign. Print the binary RHS of the
- assignment GS. BUFFER, SPC and FLAGS are as in dump_gimple_stmt. */
+ assignment GS. BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1. */
static void
dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -385,7 +385,7 @@ dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
}
/* Helper for dump_gimple_assign. Print the ternary RHS of the
- assignment GS. BUFFER, SPC and FLAGS are as in dump_gimple_stmt. */
+ assignment GS. BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1. */
static void
dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -470,7 +470,7 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
/* Dump the gimple assignment GS. BUFFER, SPC and FLAGS are as in
- dump_gimple_stmt. */
+ pp_gimple_stmt_1. */
static void
dump_gimple_assign (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -529,7 +529,7 @@ dump_gimple_assign (pretty_printer *buffer, gimple gs, int spc, int flags)
/* Dump the return statement GS. BUFFER, SPC and FLAGS are as in
- dump_gimple_stmt. */
+ pp_gimple_stmt_1. */
static void
dump_gimple_return (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -616,7 +616,7 @@ pp_points_to_solution (pretty_printer *buffer, struct pt_solution *pt)
}
/* Dump the call statement GS. BUFFER, SPC and FLAGS are as in
- dump_gimple_stmt. */
+ pp_gimple_stmt_1. */
static void
dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -749,7 +749,7 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
/* Dump the switch statement GS. BUFFER, SPC and FLAGS are as in
- dump_gimple_stmt. */
+ pp_gimple_stmt_1. */
static void
dump_gimple_switch (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -782,7 +782,7 @@ dump_gimple_switch (pretty_printer *buffer, gimple gs, int spc, int flags)
/* Dump the gimple conditional GS. BUFFER, SPC and FLAGS are as in
- dump_gimple_stmt. */
+ pp_gimple_stmt_1. */
static void
dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -1573,7 +1573,7 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
}
-/* Dump a PHI node PHI. BUFFER, SPC and FLAGS are as in dump_gimple_stmt.
+/* Dump a PHI node PHI. BUFFER, SPC and FLAGS are as in pp_gimple_stmt_1.
The caller is responsible for calling pp_flush on BUFFER to finalize
pretty printer. */
@@ -1807,7 +1807,7 @@ dump_gimple_omp_atomic_store (pretty_printer *buffer, gimple gs, int spc,
/* Dump all the memory operands for statement GS. BUFFER, SPC and
- FLAGS are as in dump_gimple_stmt. */
+ FLAGS are as in pp_gimple_stmt_1. */
static void
dump_gimple_mem_ops (pretty_printer *buffer, gimple gs, int spc, int flags)
@@ -1838,13 +1838,13 @@ dump_gimple_mem_ops (pretty_printer *buffer, gimple gs, int spc, int flags)
}
-/* Dump the gimple statement GS on the pretty printer BUFFER, SPC
+/* Print the gimple statement GS on the pretty printer BUFFER, SPC
spaces of indent. FLAGS specifies details to show in the dump (see
TDF_* in dumpfile.h). The caller is responsible for calling
pp_flush on BUFFER to finalize the pretty printer. */
void
-dump_gimple_stmt (pretty_printer *buffer, gimple gs, int spc, int flags)
+pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
{
if (!gs)
return;
@@ -2253,7 +2253,7 @@ gimple_dump_bb_buff (pretty_printer *buffer, basic_block bb, int indent,
curr_indent = gimple_code (stmt) == GIMPLE_LABEL ? label_indent : indent;
INDENT (curr_indent);
- dump_gimple_stmt (buffer, stmt, curr_indent, flags);
+ pp_gimple_stmt_1 (buffer, stmt, curr_indent, flags);
pp_newline_and_flush (buffer);
gcc_checking_assert (DECL_STRUCT_FUNCTION (current_function_decl));
dump_histograms_for_stmt (DECL_STRUCT_FUNCTION (current_function_decl),
diff --git a/gcc/gimple-pretty-print.h b/gcc/gimple-pretty-print.h
index b7c525dbe..9b6b5592f 100644
--- a/gcc/gimple-pretty-print.h
+++ b/gcc/gimple-pretty-print.h
@@ -31,6 +31,6 @@ extern void debug_gimple_seq (gimple_seq);
extern void print_gimple_seq (FILE *, gimple_seq, int, int);
extern void print_gimple_stmt (FILE *, gimple, int, int);
extern void print_gimple_expr (FILE *, gimple, int, int);
-extern void dump_gimple_stmt (pretty_printer *, gimple, int, int);
+extern void pp_gimple_stmt_1 (pretty_printer *, gimple, int, int);
#endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */
diff --git a/gcc/ginclude/stddef.h b/gcc/ginclude/stddef.h
index fc8cfa674..9f6e7419c 100644
--- a/gcc/ginclude/stddef.h
+++ b/gcc/ginclude/stddef.h
@@ -427,6 +427,13 @@ typedef struct {
#endif
#endif /* C11 or C++11. */
+#if defined(__cplusplus) && __cplusplus >= 201103L
+#ifndef _GXX_NULLPTR_T
+#define _GXX_NULLPTR_T
+ typedef decltype(nullptr) nullptr_t;
+#endif
+#endif /* C++11. */
+
#endif /* _STDDEF_H was defined this time */
#endif /* !_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__
diff --git a/gcc/ginclude/stdint-gcc.h b/gcc/ginclude/stdint-gcc.h
index 22780a15e..64b389930 100644
--- a/gcc/ginclude/stdint-gcc.h
+++ b/gcc/ginclude/stdint-gcc.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -91,7 +91,8 @@ typedef __UINTPTR_TYPE__ uintptr_t;
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
-#if !defined __cplusplus || defined __STDC_LIMIT_MACROS
+#if (!defined __cplusplus || __cplusplus >= 201103L \
+ || defined __STDC_LIMIT_MACROS)
/* 7.18.2 Limits of specified-width integer types */
@@ -229,9 +230,11 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#undef WINT_MIN
#define WINT_MIN __WINT_MIN__
-#endif /* !defined __cplusplus || defined __STDC_LIMIT_MACROS */
+#endif /* (!defined __cplusplus || __cplusplus >= 201103L
+ || defined __STDC_LIMIT_MACROS) */
-#if !defined __cplusplus || defined __STDC_CONSTANT_MACROS
+#if (!defined __cplusplus || __cplusplus >= 201103L \
+ || defined __STDC_CONSTANT_MACROS)
#undef INT8_C
#define INT8_C(c) __INT8_C(c)
@@ -254,6 +257,7 @@ typedef __UINTMAX_TYPE__ uintmax_t;
#undef UINTMAX_C
#define UINTMAX_C(c) __UINTMAX_C(c)
-#endif /* !defined __cplusplus || defined __STDC_CONSTANT_MACROS */
+#endif /* (!defined __cplusplus || __cplusplus >= 201103L
+ || defined __STDC_CONSTANT_MACROS) */
#endif /* _GCC_STDINT_H */
diff --git a/gcc/ginclude/stdint-wrap.h b/gcc/ginclude/stdint-wrap.h
index e45f8198b..83b6f70c8 100644
--- a/gcc/ginclude/stdint-wrap.h
+++ b/gcc/ginclude/stdint-wrap.h
@@ -1,5 +1,11 @@
#ifndef _GCC_WRAP_STDINT_H
#if __STDC_HOSTED__
+# if defined __cplusplus && __cplusplus >= 201103L
+# undef __STDC_LIMIT_MACROS
+# define __STDC_LIMIT_MACROS
+# undef __STDC_CONSTANT_MACROS
+# define __STDC_CONSTANT_MACROS
+# endif
# include_next <stdint.h>
#else
# include "stdint-gcc.h"
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index f6b9715d4..ab2bb7cf2 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -1631,12 +1631,16 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
// Note that INIT was already parsed with the old name bindings, so
// we don't have to worry that it will accidentally refer to the
- // newly declared variables.
+ // newly declared variables. But we do have to worry about a mix of
+ // newly declared variables and old variables if the old variables
+ // appear in the initializations.
Expression_list::const_iterator pexpr;
if (init != NULL)
pexpr = init->begin();
bool any_new = false;
+ Expression_list* vars = new Expression_list();
+ Expression_list* vals = new Expression_list();
for (Typed_identifier_list::const_iterator p = til->begin();
p != til->end();
++p)
@@ -1644,7 +1648,7 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
if (init != NULL)
go_assert(pexpr != init->end());
this->init_var(*p, type, init == NULL ? NULL : *pexpr, is_coloneq,
- false, &any_new);
+ false, &any_new, vars, vals);
if (init != NULL)
++pexpr;
}
@@ -1652,6 +1656,7 @@ Parse::init_vars(const Typed_identifier_list* til, Type* type,
go_assert(pexpr == init->end());
if (is_coloneq && !any_new)
error_at(location, "variables redeclared but no variable is new");
+ this->finish_init_vars(vars, vals, location);
}
// See if we need to initialize a list of variables from a function
@@ -1674,13 +1679,15 @@ Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
Named_object* first_var = NULL;
unsigned int index = 0;
bool any_new = false;
+ Expression_list* ivars = new Expression_list();
+ Expression_list* ivals = new Expression_list();
for (Typed_identifier_list::const_iterator pv = vars->begin();
pv != vars->end();
++pv, ++index)
{
Expression* init = Expression::make_call_result(call, index);
Named_object* no = this->init_var(*pv, type, init, is_coloneq, false,
- &any_new);
+ &any_new, ivars, ivals);
if (this->gogo_->in_global_scope() && no->is_variable())
{
@@ -1700,6 +1707,8 @@ Parse::init_vars_from_call(const Typed_identifier_list* vars, Type* type,
if (is_coloneq && !any_new)
error_at(location, "variables redeclared but no variable is new");
+ this->finish_init_vars(ivars, ivals, location);
+
return true;
}
@@ -1725,7 +1734,7 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
Typed_identifier_list::const_iterator p = vars->begin();
Expression* init = type == NULL ? index : NULL;
Named_object* val_no = this->init_var(*p, type, init, is_coloneq,
- type == NULL, &any_new);
+ type == NULL, &any_new, NULL, NULL);
if (type == NULL && any_new && val_no->is_variable())
val_no->var_value()->set_type_from_init_tuple();
Expression* val_var = Expression::make_var_reference(val_no, location);
@@ -1735,7 +1744,7 @@ Parse::init_vars_from_map(const Typed_identifier_list* vars, Type* type,
if (var_type == NULL)
var_type = Type::lookup_bool_type();
Named_object* no = this->init_var(*p, var_type, NULL, is_coloneq, false,
- &any_new);
+ &any_new, NULL, NULL);
Expression* present_var = Expression::make_var_reference(no, location);
if (is_coloneq && !any_new)
@@ -1790,7 +1799,7 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
Typed_identifier_list::const_iterator p = vars->begin();
Expression* init = type == NULL ? receive : NULL;
Named_object* val_no = this->init_var(*p, type, init, is_coloneq,
- type == NULL, &any_new);
+ type == NULL, &any_new, NULL, NULL);
if (type == NULL && any_new && val_no->is_variable())
val_no->var_value()->set_type_from_init_tuple();
Expression* val_var = Expression::make_var_reference(val_no, location);
@@ -1800,7 +1809,7 @@ Parse::init_vars_from_receive(const Typed_identifier_list* vars, Type* type,
if (var_type == NULL)
var_type = Type::lookup_bool_type();
Named_object* no = this->init_var(*p, var_type, NULL, is_coloneq, false,
- &any_new);
+ &any_new, NULL, NULL);
Expression* received_var = Expression::make_var_reference(no, location);
if (is_coloneq && !any_new)
@@ -1857,7 +1866,7 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
if (var_type == NULL)
var_type = type_guard->type();
Named_object* val_no = this->init_var(*p, var_type, NULL, is_coloneq, false,
- &any_new);
+ &any_new, NULL, NULL);
Expression* val_var = Expression::make_var_reference(val_no, location);
++p;
@@ -1865,7 +1874,7 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
if (var_type == NULL)
var_type = Type::lookup_bool_type();
Named_object* no = this->init_var(*p, var_type, NULL, is_coloneq, false,
- &any_new);
+ &any_new, NULL, NULL);
Expression* ok_var = Expression::make_var_reference(no, location);
Expression* texpr = type_guard->expr();
@@ -1904,7 +1913,8 @@ Parse::init_vars_from_type_guard(const Typed_identifier_list* vars,
Named_object*
Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init,
- bool is_coloneq, bool type_from_init, bool* is_new)
+ bool is_coloneq, bool type_from_init, bool* is_new,
+ Expression_list* vars, Expression_list* vals)
{
Location location = tid.location();
@@ -1946,9 +1956,9 @@ Parse::init_var(const Typed_identifier& tid, Type* type, Expression* init,
// like v, ok := x.(int).
if (!type_from_init && init != NULL)
{
- Expression *v = Expression::make_var_reference(no, location);
- Statement *s = Statement::make_assignment(v, init, location);
- this->gogo_->add_statement(s);
+ go_assert(vars != NULL && vals != NULL);
+ vars->push_back(Expression::make_var_reference(no, location));
+ vals->push_back(init);
}
return no;
}
@@ -1983,6 +1993,36 @@ Parse::create_dummy_global(Type* type, Expression* init,
return this->gogo_->add_variable(buf, var);
}
+// Finish the variable initialization by executing any assignments to
+// existing variables when using :=. These must be done as a tuple
+// assignment in case of something like n, a, b := 1, b, a.
+
+void
+Parse::finish_init_vars(Expression_list* vars, Expression_list* vals,
+ Location location)
+{
+ if (vars->empty())
+ {
+ delete vars;
+ delete vals;
+ }
+ else if (vars->size() == 1)
+ {
+ go_assert(!this->gogo_->in_global_scope());
+ this->gogo_->add_statement(Statement::make_assignment(vars->front(),
+ vals->front(),
+ location));
+ delete vars;
+ delete vals;
+ }
+ else
+ {
+ go_assert(!this->gogo_->in_global_scope());
+ this->gogo_->add_statement(Statement::make_tuple_assignment(vars, vals,
+ location));
+ }
+}
+
// SimpleVarDecl = identifier ":=" Expression .
// We've already seen the identifier.
@@ -3315,6 +3355,61 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
bool* is_type_switch)
{
const Token* token = this->peek_token();
+
+ // There is a complex parse for <- chan. The choices are
+ // Convert x to type <- chan int:
+ // (<- chan int)(x)
+ // Receive from (x converted to type chan <- chan int):
+ // (<- chan <- chan int (x))
+ // Convert x to type <- chan (<- chan int).
+ // (<- chan <- chan int)(x)
+ if (token->is_op(OPERATOR_CHANOP))
+ {
+ Location location = token->location();
+ if (this->advance_token()->is_keyword(KEYWORD_CHAN))
+ {
+ Expression* expr = this->primary_expr(false, may_be_composite_lit,
+ NULL);
+ if (expr->is_error_expression())
+ return expr;
+ else if (!expr->is_type_expression())
+ return Expression::make_receive(expr, location);
+ else
+ {
+ if (expr->type()->is_error_type())
+ return expr;
+
+ // We picked up "chan TYPE", but it is not a type
+ // conversion.
+ Channel_type* ct = expr->type()->channel_type();
+ if (ct == NULL)
+ {
+ // This is probably impossible.
+ error_at(location, "expected channel type");
+ return Expression::make_error(location);
+ }
+ else if (ct->may_receive())
+ {
+ // <- chan TYPE.
+ Type* t = Type::make_channel_type(false, true,
+ ct->element_type());
+ return Expression::make_type(t, location);
+ }
+ else
+ {
+ // <- chan <- TYPE. Because we skipped the leading
+ // <-, we parsed this as chan <- TYPE. With the
+ // leading <-, we parse it as <- chan (<- TYPE).
+ Type *t = this->reassociate_chan_direction(ct, location);
+ return Expression::make_type(t, location);
+ }
+ }
+ }
+
+ this->unget_token(Token::make_operator_token(OPERATOR_CHANOP, location));
+ token = this->peek_token();
+ }
+
if (token->is_op(OPERATOR_PLUS)
|| token->is_op(OPERATOR_MINUS)
|| token->is_op(OPERATOR_NOT)
@@ -3327,14 +3422,6 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
Operator op = token->op();
this->advance_token();
- if (op == OPERATOR_CHANOP
- && this->peek_token()->is_keyword(KEYWORD_CHAN))
- {
- // This is "<- chan" which must be the start of a type.
- this->unget_token(Token::make_operator_token(op, location));
- return Expression::make_type(this->type(), location);
- }
-
Expression* expr = this->unary_expr(false, may_be_composite_lit, NULL);
if (expr->is_error_expression())
;
@@ -3354,6 +3441,32 @@ Parse::unary_expr(bool may_be_sink, bool may_be_composite_lit,
is_type_switch);
}
+// This is called for the obscure case of
+// (<- chan <- chan int)(x)
+// In unary_expr we remove the leading <- and parse the remainder,
+// which gives us
+// chan <- (chan int)
+// When we add the leading <- back in, we really want
+// <- chan (<- chan int)
+// This means that we need to reassociate.
+
+Type*
+Parse::reassociate_chan_direction(Channel_type *ct, Location location)
+{
+ Channel_type* ele = ct->element_type()->channel_type();
+ if (ele == NULL)
+ {
+ error_at(location, "parse error");
+ return Type::make_error_type();
+ }
+ Type* sub = ele;
+ if (ele->may_send())
+ sub = Type::make_channel_type(false, true, ele->element_type());
+ else
+ sub = this->reassociate_chan_direction(ele, location);
+ return Type::make_channel_type(false, true, sub);
+}
+
// Statement =
// Declaration | LabeledStmt | SimpleStmt |
// GoStmt | ReturnStmt | BreakStmt | ContinueStmt | GotoStmt |
@@ -5040,7 +5153,8 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
bool any_new = false;
const Typed_identifier* pti = &til->front();
- Named_object* no = this->init_var(*pti, NULL, expr, true, true, &any_new);
+ Named_object* no = this->init_var(*pti, NULL, expr, true, true, &any_new,
+ NULL, NULL);
if (any_new && no->is_variable())
no->var_value()->set_type_from_range_index();
p_range_clause->index = Expression::make_var_reference(no, location);
@@ -5051,7 +5165,7 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
{
pti = &til->back();
bool is_new = false;
- no = this->init_var(*pti, NULL, expr, true, true, &is_new);
+ no = this->init_var(*pti, NULL, expr, true, true, &is_new, NULL, NULL);
if (is_new && no->is_variable())
no->var_value()->set_type_from_range_value();
if (is_new)
diff --git a/gcc/go/gofrontend/parse.h b/gcc/go/gofrontend/parse.h
index 3139f7e89..a355b7d2b 100644
--- a/gcc/go/gofrontend/parse.h
+++ b/gcc/go/gofrontend/parse.h
@@ -14,6 +14,7 @@ class Named_object;
class Type;
class Typed_identifier;
class Typed_identifier_list;
+class Channel_type;
class Function_type;
class Block;
class Expression;
@@ -205,8 +206,11 @@ class Parse
Expression*, bool is_coloneq,
Location);
Named_object* init_var(const Typed_identifier&, Type*, Expression*,
- bool is_coloneq, bool type_from_init, bool* is_new);
+ bool is_coloneq, bool type_from_init, bool* is_new,
+ Expression_list* vars, Expression_list* vals);
Named_object* create_dummy_global(Type*, Expression*, Location);
+ void finish_init_vars(Expression_list* vars, Expression_list* vals,
+ Location);
void simple_var_decl_or_assignment(const std::string&, Location,
bool may_be_composite_lit,
Range_clause*, Type_switch*);
@@ -229,6 +233,7 @@ class Parse
bool expression_may_start_here();
Expression* unary_expr(bool may_be_sink, bool may_be_composite_lit,
bool* is_type_switch);
+ Type* reassociate_chan_direction(Channel_type*, Location);
Expression* qualified_expr(Expression*, Location);
Expression* id_to_expression(const std::string&, Location);
void statement(Label*);
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 3ae54a438..1736a3265 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -4919,14 +4919,15 @@ Struct_type::write_equal_function(Gogo* gogo, Named_type* name)
void
Struct_type::do_reflection(Gogo* gogo, std::string* ret) const
{
- ret->append("struct { ");
+ ret->append("struct {");
for (Struct_field_list::const_iterator p = this->fields_->begin();
p != this->fields_->end();
++p)
{
if (p != this->fields_->begin())
- ret->append("; ");
+ ret->push_back(';');
+ ret->push_back(' ');
if (p->is_anonymous())
ret->push_back('?');
else
@@ -4959,7 +4960,10 @@ Struct_type::do_reflection(Gogo* gogo, std::string* ret) const
}
}
- ret->append(" }");
+ if (!this->fields_->empty())
+ ret->push_back(' ');
+
+ ret->push_back('}');
}
// Mangled name.
@@ -8390,6 +8394,7 @@ Named_type::do_reflection(Gogo* gogo, std::string* ret) const
}
if (this->in_function_ != NULL)
{
+ ret->push_back('\t');
ret->append(Gogo::unpack_hidden_name(this->in_function_->name()));
ret->push_back('$');
if (this->in_function_index_ > 0)
@@ -8399,6 +8404,7 @@ Named_type::do_reflection(Gogo* gogo, std::string* ret) const
ret->append(buf);
ret->push_back('$');
}
+ ret->push_back('\t');
}
ret->append(Gogo::unpack_hidden_name(this->named_object_->name()));
}
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 31ecec9af..6cea94225 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -3312,14 +3312,12 @@ do_estimate_edge_time (struct cgraph_edge *edge)
VEC_free (tree, heap, known_binfos);
VEC_free (ipa_agg_jump_function_p, heap, known_aggs);
- ret = (((gcov_type)time
- - es->call_stmt_time) * edge->frequency
- + CGRAPH_FREQ_BASE / 2) / CGRAPH_FREQ_BASE;
+ ret = RDIV ((gcov_type)time * edge->frequency,
+ CGRAPH_FREQ_BASE);
/* When caching, update the cache entry. */
if (edge_growth_cache)
{
- int ret_size;
if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache)
<= edge->uid)
VEC_safe_grow_cleared (edge_growth_cache_entry, heap, edge_growth_cache,
@@ -3327,10 +3325,8 @@ do_estimate_edge_time (struct cgraph_edge *edge)
VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).time
= ret + (ret >= 0);
- ret_size = size - es->call_stmt_size;
- gcc_checking_assert (es->call_stmt_size);
VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).size
- = ret_size + (ret_size >= 0);
+ = size + (size >= 0);
VEC_index (edge_growth_cache_entry, edge_growth_cache, edge->uid).hints
= hints + 1;
}
@@ -3338,11 +3334,11 @@ do_estimate_edge_time (struct cgraph_edge *edge)
}
-/* Estimate the growth of the caller when inlining EDGE.
+/* Return estimated callee growth after inlining EDGE.
Only to be called via estimate_edge_size. */
int
-do_estimate_edge_growth (struct cgraph_edge *edge)
+do_estimate_edge_size (struct cgraph_edge *edge)
{
int size;
struct cgraph_node *callee;
@@ -3375,8 +3371,7 @@ do_estimate_edge_growth (struct cgraph_edge *edge)
VEC_free (tree, heap, known_vals);
VEC_free (tree, heap, known_binfos);
VEC_free (ipa_agg_jump_function_p, heap, known_aggs);
- gcc_checking_assert (inline_edge_summary (edge)->call_stmt_size);
- return size - inline_edge_summary (edge)->call_stmt_size;
+ return size;
}
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index ec9cf4d13..df8b3a7e2 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -201,7 +201,7 @@ void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
int do_estimate_growth (struct cgraph_node *);
void inline_merge_summary (struct cgraph_edge *edge);
void inline_update_overall_summary (struct cgraph_node *node);
-int do_estimate_edge_growth (struct cgraph_edge *edge);
+int do_estimate_edge_size (struct cgraph_edge *edge);
int do_estimate_edge_time (struct cgraph_edge *edge);
inline_hints do_estimate_edge_hints (struct cgraph_edge *edge);
void initialize_growth_caches (void);
@@ -245,20 +245,31 @@ estimate_growth (struct cgraph_node *node)
}
-/* Return estimated callee growth after inlining EDGE. */
+/* Return estimated size of the inline sequence of EDGE. */
static inline int
-estimate_edge_growth (struct cgraph_edge *edge)
+estimate_edge_size (struct cgraph_edge *edge)
{
int ret;
if ((int)VEC_length (edge_growth_cache_entry, edge_growth_cache) <= edge->uid
|| !(ret = VEC_index (edge_growth_cache_entry,
edge_growth_cache,
edge->uid).size))
- return do_estimate_edge_growth (edge);
+ return do_estimate_edge_size (edge);
return ret - (ret > 0);
}
+/* Return estimated callee growth after inlining EDGE. */
+
+static inline int
+estimate_edge_growth (struct cgraph_edge *edge)
+{
+#ifdef ENABLE_CHECKING
+ gcc_checking_assert (inline_edge_summary (edge)->call_stmt_size);
+#endif
+ return (estimate_edge_size (edge)
+ - inline_edge_summary (edge)->call_stmt_size);
+}
/* Return estimated callee runtime increase after inlning
EDGE. */
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index e1d1c4928..6750c1138 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1059,6 +1059,7 @@ split_function (struct split_point *split_point)
gimple last_stmt = NULL;
unsigned int i;
tree arg, ddef;
+ VEC(tree, gc) **debug_args = NULL;
if (dump_file)
{
@@ -1232,6 +1233,83 @@ split_function (struct split_point *split_point)
gimple_set_block (call, DECL_INITIAL (current_function_decl));
VEC_free (tree, heap, args_to_pass);
+ /* For optimized away parameters, add on the caller side
+ before the call
+ DEBUG D#X => parm_Y(D)
+ stmts and associate D#X with parm in decl_debug_args_lookup
+ vector to say for debug info that if parameter parm had been passed,
+ it would have value parm_Y(D). */
+ if (args_to_skip)
+ for (parm = DECL_ARGUMENTS (current_function_decl), num = 0;
+ parm; parm = DECL_CHAIN (parm), num++)
+ if (bitmap_bit_p (args_to_skip, num)
+ && is_gimple_reg (parm))
+ {
+ tree ddecl;
+ gimple def_temp;
+
+ /* This needs to be done even without MAY_HAVE_DEBUG_STMTS,
+ otherwise if it didn't exist before, we'd end up with
+ different SSA_NAME_VERSIONs between -g and -g0. */
+ arg = get_or_create_ssa_default_def (cfun, parm);
+ if (!MAY_HAVE_DEBUG_STMTS)
+ continue;
+
+ if (debug_args == NULL)
+ debug_args = decl_debug_args_insert (node->symbol.decl);
+ ddecl = make_node (DEBUG_EXPR_DECL);
+ DECL_ARTIFICIAL (ddecl) = 1;
+ TREE_TYPE (ddecl) = TREE_TYPE (parm);
+ DECL_MODE (ddecl) = DECL_MODE (parm);
+ VEC_safe_push (tree, gc, *debug_args, DECL_ORIGIN (parm));
+ VEC_safe_push (tree, gc, *debug_args, ddecl);
+ def_temp = gimple_build_debug_bind (ddecl, unshare_expr (arg),
+ call);
+ gsi_insert_after (&gsi, def_temp, GSI_NEW_STMT);
+ }
+ /* And on the callee side, add
+ DEBUG D#Y s=> parm
+ DEBUG var => D#Y
+ stmts to the first bb where var is a VAR_DECL created for the
+ optimized away parameter in DECL_INITIAL block. This hints
+ in the debug info that var (whole DECL_ORIGIN is the parm PARM_DECL)
+ is optimized away, but could be looked up at the call site
+ as value of D#X there. */
+ if (debug_args != NULL)
+ {
+ unsigned int i;
+ tree var, vexpr;
+ gimple_stmt_iterator cgsi;
+ gimple def_temp;
+
+ push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
+ var = BLOCK_VARS (DECL_INITIAL (node->symbol.decl));
+ i = VEC_length (tree, *debug_args);
+ cgsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
+ do
+ {
+ i -= 2;
+ while (var != NULL_TREE
+ && DECL_ABSTRACT_ORIGIN (var)
+ != VEC_index (tree, *debug_args, i))
+ var = TREE_CHAIN (var);
+ if (var == NULL_TREE)
+ break;
+ vexpr = make_node (DEBUG_EXPR_DECL);
+ parm = VEC_index (tree, *debug_args, i);
+ DECL_ARTIFICIAL (vexpr) = 1;
+ TREE_TYPE (vexpr) = TREE_TYPE (parm);
+ DECL_MODE (vexpr) = DECL_MODE (parm);
+ def_temp = gimple_build_debug_source_bind (vexpr, parm,
+ NULL);
+ gsi_insert_before (&cgsi, def_temp, GSI_SAME_STMT);
+ def_temp = gimple_build_debug_bind (var, vexpr, NULL);
+ gsi_insert_before (&cgsi, def_temp, GSI_SAME_STMT);
+ }
+ while (i);
+ pop_cfun ();
+ }
+
/* We avoid address being taken on any variable used by split part,
so return slot optimization is always possible. Moreover this is
required to make DECL_BY_REFERENCE work. */
diff --git a/gcc/ira-build.c b/gcc/ira-build.c
index dba1d467a..1181813d9 100644
--- a/gcc/ira-build.c
+++ b/gcc/ira-build.c
@@ -3047,11 +3047,10 @@ update_conflict_hard_reg_costs (void)
{
reg_class_t aclass = ALLOCNO_CLASS (a);
reg_class_t pref = reg_preferred_class (ALLOCNO_REGNO (a));
-
- if (reg_class_size[(int) pref] != 1)
+ int singleton = ira_class_singleton[pref][ALLOCNO_MODE (a)];
+ if (singleton < 0)
continue;
- index = ira_class_hard_reg_index[(int) aclass]
- [ira_class_hard_regs[(int) pref][0]];
+ index = ira_class_hard_reg_index[(int) aclass][singleton];
if (index < 0)
continue;
if (ALLOCNO_CONFLICT_HARD_REG_COSTS (a) == NULL
diff --git a/gcc/ira-color.c b/gcc/ira-color.c
index ea933be99..fc2e4e8b2 100644
--- a/gcc/ira-color.c
+++ b/gcc/ira-color.c
@@ -1023,10 +1023,9 @@ setup_profitable_hard_regs (void)
CLEAR_HARD_REG_SET (data->profitable_hard_regs);
else
{
+ mode = ALLOCNO_MODE (a);
COPY_HARD_REG_SET (data->profitable_hard_regs,
- reg_class_contents[aclass]);
- AND_COMPL_HARD_REG_SET (data->profitable_hard_regs,
- ira_no_alloc_regs);
+ ira_useful_class_mode_regs[aclass][mode]);
nobj = ALLOCNO_NUM_OBJECTS (a);
for (k = 0; k < nobj; k++)
{
diff --git a/gcc/ira-int.h b/gcc/ira-int.h
index 8d44e35df..bde69861e 100644
--- a/gcc/ira-int.h
+++ b/gcc/ira-int.h
@@ -816,6 +816,20 @@ struct target_ira_int {
values for given mode are zero. */
HARD_REG_SET x_ira_prohibited_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES];
+ /* Index [CL][M] contains R if R appears somewhere in a register of the form:
+
+ (reg:M R'), R' not in x_ira_prohibited_class_mode_regs[CL][M]
+
+ For example, if:
+
+ - (reg:M 2) is valid and occupies two registers;
+ - register 2 belongs to CL; and
+ - register 3 belongs to the same pressure class as CL
+
+ then (reg:M 2) contributes to [CL][M] and registers 2 and 3 will be
+ in the set. */
+ HARD_REG_SET x_ira_useful_class_mode_regs[N_REG_CLASSES][NUM_MACHINE_MODES];
+
/* The value is number of elements in the subsequent array. */
int x_ira_important_classes_num;
@@ -902,6 +916,8 @@ extern struct target_ira_int *this_target_ira_int;
(this_target_ira_int->x_ira_class_hard_reg_index)
#define ira_prohibited_class_mode_regs \
(this_target_ira_int->x_ira_prohibited_class_mode_regs)
+#define ira_useful_class_mode_regs \
+ (this_target_ira_int->x_ira_useful_class_mode_regs)
#define ira_important_classes_num \
(this_target_ira_int->x_ira_important_classes_num)
#define ira_important_classes \
diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c
index 0de1b81b7..853832e3c 100644
--- a/gcc/ira-lives.c
+++ b/gcc/ira-lives.c
@@ -849,9 +849,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
next_cl = (c == 'r'
? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, constraints));
- if ((cl != NO_REGS && next_cl != cl)
- || (ira_class_hard_regs_num[next_cl]
- > ira_reg_class_max_nregs[next_cl][GET_MODE (op)]))
+ if (cl == NO_REGS
+ ? ira_class_singleton[next_cl][GET_MODE (op)] < 0
+ : (ira_class_singleton[cl][GET_MODE (op)]
+ != ira_class_singleton[next_cl][GET_MODE (op)]))
return NO_REGS;
cl = next_cl;
break;
@@ -861,10 +862,10 @@ single_reg_class (const char *constraints, rtx op, rtx equiv_const)
next_cl
= single_reg_class (recog_data.constraints[c - '0'],
recog_data.operand[c - '0'], NULL_RTX);
- if ((cl != NO_REGS && next_cl != cl)
- || next_cl == NO_REGS
- || (ira_class_hard_regs_num[next_cl]
- > ira_reg_class_max_nregs[next_cl][GET_MODE (op)]))
+ if (cl == NO_REGS
+ ? ira_class_singleton[next_cl][GET_MODE (op)] < 0
+ : (ira_class_singleton[cl][GET_MODE (op)]
+ != ira_class_singleton[next_cl][GET_MODE (op)]))
return NO_REGS;
cl = next_cl;
break;
@@ -939,13 +940,14 @@ ira_implicitly_set_insn_hard_regs (HARD_REG_SET *set)
cl = (c == 'r'
? GENERAL_REGS
: REG_CLASS_FROM_CONSTRAINT (c, p));
- if (cl != NO_REGS
+ if (cl != NO_REGS)
+ {
/* There is no register pressure problem if all of the
regs in this class are fixed. */
- && ira_class_hard_regs_num[cl] != 0
- && (ira_class_hard_regs_num[cl]
- <= ira_reg_class_max_nregs[cl][mode]))
- IOR_HARD_REG_SET (*set, reg_class_contents[cl]);
+ int regno = ira_class_singleton[cl][mode];
+ if (regno >= 0)
+ add_to_hard_reg_set (set, mode, regno);
+ }
break;
}
}
@@ -989,8 +991,7 @@ process_single_reg_class_operands (bool in_p, int freq)
operand_a = ira_curr_regno_allocno_map[regno];
aclass = ALLOCNO_CLASS (operand_a);
- if (ira_class_subset_p[cl][aclass]
- && ira_class_hard_regs_num[cl] != 0)
+ if (ira_class_subset_p[cl][aclass])
{
/* View the desired allocation of OPERAND as:
@@ -1004,7 +1005,8 @@ process_single_reg_class_operands (bool in_p, int freq)
HOST_WIDE_INT offset;
xmode = recog_data.operand_mode[i];
- xregno = ira_class_hard_regs[cl][0];
+ xregno = ira_class_singleton[cl][xmode];
+ gcc_assert (xregno >= 0);
ymode = ALLOCNO_MODE (operand_a);
offset = subreg_lowpart_offset (ymode, xmode);
yregno = simplify_subreg_regno (xregno, xmode, offset, ymode);
diff --git a/gcc/ira.c b/gcc/ira.c
index ad0ae0a8e..4a7dcb520 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1451,16 +1451,21 @@ setup_reg_class_nregs (void)
-/* Set up IRA_PROHIBITED_CLASS_MODE_REGS. */
+/* Set up IRA_PROHIBITED_CLASS_MODE_REGS and IRA_CLASS_SINGLETON.
+ This function is called once IRA_CLASS_HARD_REGS has been initialized. */
static void
setup_prohibited_class_mode_regs (void)
{
- int j, k, hard_regno, cl;
+ int j, k, hard_regno, cl, last_hard_regno, count;
for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--)
{
+ COPY_HARD_REG_SET (temp_hard_regset, reg_class_contents[cl]);
+ AND_COMPL_HARD_REG_SET (temp_hard_regset, no_unit_alloc_regs);
for (j = 0; j < NUM_MACHINE_MODES; j++)
{
+ count = 0;
+ last_hard_regno = -1;
CLEAR_HARD_REG_SET (ira_prohibited_class_mode_regs[cl][j]);
for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
{
@@ -1468,7 +1473,14 @@ setup_prohibited_class_mode_regs (void)
if (! HARD_REGNO_MODE_OK (hard_regno, (enum machine_mode) j))
SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
hard_regno);
+ else if (in_hard_reg_set_p (temp_hard_regset,
+ (enum machine_mode) j, hard_regno))
+ {
+ last_hard_regno = hard_regno;
+ count++;
+ }
}
+ ira_class_singleton[cl][j] = (count == 1 ? last_hard_regno : -1);
}
}
}
@@ -1483,29 +1495,36 @@ clarify_prohibited_class_mode_regs (void)
for (cl = (int) N_REG_CLASSES - 1; cl >= 0; cl--)
for (j = 0; j < NUM_MACHINE_MODES; j++)
- for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
- {
- hard_regno = ira_class_hard_regs[cl][k];
- if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno))
- continue;
- nregs = hard_regno_nregs[hard_regno][j];
- if (hard_regno + nregs > FIRST_PSEUDO_REGISTER)
- {
- SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
- hard_regno);
- continue;
- }
- pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)];
- for (nregs-- ;nregs >= 0; nregs--)
- if (((enum reg_class) pclass
- != ira_pressure_class_translate[REGNO_REG_CLASS
- (hard_regno + nregs)]))
+ {
+ CLEAR_HARD_REG_SET (ira_useful_class_mode_regs[cl][j]);
+ for (k = ira_class_hard_regs_num[cl] - 1; k >= 0; k--)
+ {
+ hard_regno = ira_class_hard_regs[cl][k];
+ if (TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j], hard_regno))
+ continue;
+ nregs = hard_regno_nregs[hard_regno][j];
+ if (hard_regno + nregs > FIRST_PSEUDO_REGISTER)
{
SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
hard_regno);
- break;
+ continue;
}
- }
+ pclass = ira_pressure_class_translate[REGNO_REG_CLASS (hard_regno)];
+ for (nregs-- ;nregs >= 0; nregs--)
+ if (((enum reg_class) pclass
+ != ira_pressure_class_translate[REGNO_REG_CLASS
+ (hard_regno + nregs)]))
+ {
+ SET_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
+ hard_regno);
+ break;
+ }
+ if (!TEST_HARD_REG_BIT (ira_prohibited_class_mode_regs[cl][j],
+ hard_regno))
+ add_to_hard_reg_set (&ira_useful_class_mode_regs[cl][j],
+ (enum machine_mode) j, hard_regno);
+ }
+ }
}
/* Allocate and initialize IRA_REGISTER_MOVE_COST, IRA_MAY_MOVE_IN_COST
diff --git a/gcc/ira.h b/gcc/ira.h
index d53db4e0c..6870c4bf3 100644
--- a/gcc/ira.h
+++ b/gcc/ira.h
@@ -79,6 +79,10 @@ struct target_ira {
class. */
int x_ira_class_hard_regs_num[N_REG_CLASSES];
+ /* If class CL has a single allocatable register of mode M,
+ index [CL][M] gives the number of that register, otherwise it is -1. */
+ short x_ira_class_singleton[N_REG_CLASSES][MAX_MACHINE_MODE];
+
/* Function specific hard registers can not be used for the register
allocation. */
HARD_REG_SET x_ira_no_alloc_regs;
@@ -117,6 +121,8 @@ extern struct target_ira *this_target_ira;
(this_target_ira->x_ira_class_hard_regs)
#define ira_class_hard_regs_num \
(this_target_ira->x_ira_class_hard_regs_num)
+#define ira_class_singleton \
+ (this_target_ira->x_ira_class_singleton)
#define ira_no_alloc_regs \
(this_target_ira->x_ira_no_alloc_regs)
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index f96ed3d36..4f952f59b 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -72,13 +72,17 @@ enum LTO_symtab_tags
LTO_symtab_last_tag
};
-/* Create a new symtab encoder. */
+/* Create a new symtab encoder.
+ if FOR_INPUT, the encoder allocate only datastructures needed
+ to read the symtab. */
lto_symtab_encoder_t
-lto_symtab_encoder_new (void)
+lto_symtab_encoder_new (bool for_input)
{
lto_symtab_encoder_t encoder = XCNEW (struct lto_symtab_encoder_d);
- encoder->map = pointer_map_create ();
+
+ if (!for_input)
+ encoder->map = pointer_map_create ();
encoder->nodes = NULL;
return encoder;
}
@@ -90,7 +94,8 @@ void
lto_symtab_encoder_delete (lto_symtab_encoder_t encoder)
{
VEC_free (lto_encoder_entry, heap, encoder->nodes);
- pointer_map_destroy (encoder->map);
+ if (encoder->map)
+ pointer_map_destroy (encoder->map);
free (encoder);
}
@@ -106,6 +111,15 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
int ref;
void **slot;
+ if (!encoder->map)
+ {
+ lto_encoder_entry entry = {node, false, false, false};
+
+ ref = VEC_length (lto_encoder_entry, encoder->nodes);
+ VEC_safe_push (lto_encoder_entry, heap, encoder->nodes, entry);
+ return ref;
+ }
+
slot = pointer_map_contains (encoder->map, node);
if (!slot || !*slot)
{
@@ -688,7 +702,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
lto_symtab_encoder_t encoder;
lto_symtab_encoder_iterator lsei;
- encoder = lto_symtab_encoder_new ();
+ encoder = lto_symtab_encoder_new (false);
/* Go over all entries in the IN_ENCODER and duplicate them to
ENCODER. At the same time insert masters of clones so
@@ -1316,7 +1330,7 @@ input_symtab (void)
if (!ib)
fatal_error ("cannot find LTO cgraph in %s", file_data->file_name);
input_profile_summary (ib, file_data);
- file_data->symtab_node_encoder = lto_symtab_encoder_new ();
+ file_data->symtab_node_encoder = lto_symtab_encoder_new (true);
nodes = input_cgraph_1 (file_data, ib);
lto_destroy_simple_input_block (file_data, LTO_section_symtab_nodes,
ib, data, len);
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index afe49517e..083db74f9 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1285,11 +1285,9 @@ produce_symtab (struct output_block *ob)
struct streamer_tree_cache_d *cache = ob->writer_cache;
char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
struct pointer_set_t *seen;
- struct cgraph_node *node;
- struct varpool_node *vnode;
struct lto_output_stream stream;
lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
- int i;
+ lto_symtab_encoder_iterator lsei;
lto_begin_section (section_name, false);
free (section_name);
@@ -1297,78 +1295,26 @@ produce_symtab (struct output_block *ob)
seen = pointer_set_create ();
memset (&stream, 0, sizeof (stream));
- /* Write all functions.
- First write all defined functions and then write all used functions.
- This is done so only to handle duplicated symbols in cgraph. */
- for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
+ /* Write the symbol table.
+ First write everything defined and then all declarations.
+ This is neccesary to handle cases where we have duplicated symbols. */
+ for (lsei = lsei_start (encoder);
+ !lsei_end_p (lsei); lsei_next (&lsei))
{
- if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
- continue;
- node = cgraph (lto_symtab_encoder_deref (encoder, i));
- if (DECL_EXTERNAL (node->symbol.decl))
- continue;
- if (DECL_COMDAT (node->symbol.decl)
- && cgraph_comdat_can_be_unshared_p (node))
- continue;
- if ((node->alias && !node->thunk.alias) || node->global.inlined_to)
+ symtab_node node = lsei_node (lsei);
+
+ if (!symtab_real_symbol_p (node) || DECL_EXTERNAL (node->symbol.decl))
continue;
write_symbol (cache, &stream, node->symbol.decl, seen, false);
}
- for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
+ for (lsei = lsei_start (encoder);
+ !lsei_end_p (lsei); lsei_next (&lsei))
{
- if (!symtab_function_p (lto_symtab_encoder_deref (encoder, i)))
- continue;
- node = cgraph (lto_symtab_encoder_deref (encoder, i));
- if (!DECL_EXTERNAL (node->symbol.decl))
- continue;
- /* We keep around unused extern inlines in order to be able to inline
- them indirectly or via vtables. Do not output them to symbol
- table: they end up being undefined and just consume space. */
- if (!node->symbol.address_taken && !node->callers)
- continue;
- if (DECL_COMDAT (node->symbol.decl)
- && cgraph_comdat_can_be_unshared_p (node))
- continue;
- if ((node->alias && !node->thunk.alias) || node->global.inlined_to)
- continue;
- write_symbol (cache, &stream, node->symbol.decl, seen, false);
- }
+ symtab_node node = lsei_node (lsei);
- /* Write all variables. */
- for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
- {
- if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
- continue;
- vnode = varpool (lto_symtab_encoder_deref (encoder, i));
- if (DECL_EXTERNAL (vnode->symbol.decl))
- continue;
- /* COMDAT virtual tables can be unshared. Do not declare them
- in the LTO symbol table to prevent linker from forcing them
- into the output. */
- if (DECL_COMDAT (vnode->symbol.decl)
- && !vnode->symbol.force_output
- && vnode->finalized
- && DECL_VIRTUAL_P (vnode->symbol.decl))
- continue;
- if (vnode->alias && !vnode->alias_of)
- continue;
- write_symbol (cache, &stream, vnode->symbol.decl, seen, false);
- }
- for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
- {
- if (!symtab_variable_p (lto_symtab_encoder_deref (encoder, i)))
- continue;
- vnode = varpool (lto_symtab_encoder_deref (encoder, i));
- if (!DECL_EXTERNAL (vnode->symbol.decl))
+ if (!symtab_real_symbol_p (node) || !DECL_EXTERNAL (node->symbol.decl))
continue;
- if (DECL_COMDAT (vnode->symbol.decl)
- && !vnode->symbol.force_output
- && vnode->finalized
- && DECL_VIRTUAL_P (vnode->symbol.decl))
- continue;
- if (vnode->alias && !vnode->alias_of)
- continue;
- write_symbol (cache, &stream, vnode->symbol.decl, seen, false);
+ write_symbol (cache, &stream, node->symbol.decl, seen, false);
}
lto_write_stream (&stream);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 059959e73..b2f8d30ff 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -833,7 +833,7 @@ void lto_output_location (struct output_block *, location_t);
/* In lto-cgraph.c */
-lto_symtab_encoder_t lto_symtab_encoder_new (void);
+lto_symtab_encoder_t lto_symtab_encoder_new (bool);
int lto_symtab_encoder_encode (lto_symtab_encoder_t, symtab_node);
void lto_symtab_encoder_delete (lto_symtab_encoder_t);
bool lto_symtab_encoder_delete_node (lto_symtab_encoder_t, symtab_node);
@@ -860,12 +860,9 @@ lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
/* In lto-symtab.c. */
-extern void lto_symtab_register_decl (tree, ld_plugin_symbol_resolution_t,
- struct lto_file_decl_data *);
extern void lto_symtab_merge_decls (void);
extern void lto_symtab_merge_cgraph_nodes (void);
extern tree lto_symtab_prevailing_decl (tree decl);
-extern enum ld_plugin_symbol_resolution lto_symtab_get_resolution (tree decl);
extern GTY(()) VEC(tree,gc) *lto_global_var_decls;
@@ -873,11 +870,6 @@ extern GTY(()) VEC(tree,gc) *lto_global_var_decls;
extern void lto_write_options (void);
-/* In lto-wpa-fixup.c */
-void lto_mark_nothrow_fndecl (tree);
-void lto_fixup_nothrow_decls (void);
-
-
/* Statistics gathered during LTO, WPA and LTRANS. */
extern struct lto_stats_d lto_stats;
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index cd8ca67b0..25c0b22dc 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -32,40 +32,6 @@ along with GCC; see the file COPYING3. If not see
/* Vector to keep track of external variables we've seen so far. */
VEC(tree,gc) *lto_global_var_decls;
-/* Registers DECL with the LTO symbol table as having resolution RESOLUTION
- and read from FILE_DATA. */
-
-void
-lto_symtab_register_decl (tree decl,
- ld_plugin_symbol_resolution_t resolution,
- struct lto_file_decl_data *file_data)
-{
- symtab_node node;
-
- /* Check that declarations reaching this function do not have
- properties inconsistent with having external linkage. If any of
- these asertions fail, then the object file reader has failed to
- detect these cases and issue appropriate error messages. */
- gcc_assert (decl
- && TREE_PUBLIC (decl)
- && (TREE_CODE (decl) == VAR_DECL
- || TREE_CODE (decl) == FUNCTION_DECL)
- && DECL_ASSEMBLER_NAME_SET_P (decl));
- if (TREE_CODE (decl) == VAR_DECL
- && DECL_INITIAL (decl))
- gcc_assert (!DECL_EXTERNAL (decl)
- || (TREE_STATIC (decl) && TREE_READONLY (decl)));
- if (TREE_CODE (decl) == FUNCTION_DECL)
- gcc_assert (!DECL_ABSTRACT (decl));
-
- node = symtab_get_node (decl);
- if (node)
- {
- node->symbol.resolution = resolution;
- gcc_assert (node->symbol.lto_file_data == file_data);
- }
-}
-
/* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
all edges and removing the old node. */
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 7c437d6c9..7218f4873 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,17 @@
+2012-10-07 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (read_cgraph_and_symbols): Release type merging hash early;
+ release input encoders.
+ * lto-partition.c (new_partition): Update for new lto_symtab_encoder_new.
+
+2012-10-06 Jan Hubicka <jh@suse.cz>
+
+ PR lto/54790
+ * lto.c (resolution_map): New static var.
+ (register_resolution): New function.
+ (lto_register_var_decl_in_symtab): Use it.
+ (read_cgraph_and_symbols): Copy resolutions into the symtab.
+
2012-09-20 Martin Jambor <mjambor@suse.cz>
* lto.c (lto_materialize_function): Call push_struct_function and
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index b1310335a..32243fb83 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -99,7 +99,7 @@ static ltrans_partition
new_partition (const char *name)
{
ltrans_partition part = XCNEW (struct ltrans_partition_def);
- part->encoder = lto_symtab_encoder_new ();
+ part->encoder = lto_symtab_encoder_new (false);
part->name = name;
part->insns = 0;
VEC_safe_push (ltrans_partition, heap, ltrans_partitions, part);
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 44718537b..d880c8a20 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1692,6 +1692,19 @@ get_resolution (struct data_in *data_in, unsigned index)
return LDPR_UNKNOWN;
}
+/* Map assigning declarations their resolutions. */
+static pointer_map_t *resolution_map;
+
+/* We need to record resolutions until symbol table is read. */
+static void
+register_resolution (tree decl, enum ld_plugin_symbol_resolution resolution)
+{
+ if (resolution == LDPR_UNKNOWN)
+ return;
+ if (!resolution_map)
+ resolution_map = pointer_map_create ();
+ *pointer_map_insert (resolution_map, decl) = (void *)(size_t)resolution;
+}
/* Register DECL with the global symbol table and change its
name if necessary to avoid name clashes for static globals across
@@ -1730,8 +1743,7 @@ lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl)
unsigned ix;
if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
gcc_unreachable ();
- lto_symtab_register_decl (decl, get_resolution (data_in, ix),
- data_in->file_data);
+ register_resolution (decl, get_resolution (data_in, ix));
}
}
@@ -1789,8 +1801,7 @@ lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl)
unsigned ix;
if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
gcc_unreachable ();
- lto_symtab_register_decl (decl, get_resolution (data_in, ix),
- data_in->file_data);
+ register_resolution (decl, get_resolution (data_in, ix));
}
}
@@ -2935,6 +2946,17 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
if (resolution_file_name)
fclose (resolution);
+ /* Free gimple type merging datastructures. */
+ htab_delete (gimple_types);
+ gimple_types = NULL;
+ htab_delete (type_hash_cache);
+ type_hash_cache = NULL;
+ free (type_pair_cache);
+ type_pair_cache = NULL;
+ gimple_type_leader = NULL;
+ free_gimple_type_tables ();
+ ggc_collect ();
+
/* Set the hooks so that all of the ipa passes can read in their data. */
lto_set_in_hooks (all_file_decl_data, get_section_data, free_section_data);
@@ -2946,6 +2968,24 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
timevar_push (TV_IPA_LTO_CGRAPH_IO);
/* Read the symtab. */
input_symtab ();
+
+ /* Store resolutions into the symbol table. */
+ if (resolution_map)
+ {
+ void **res;
+ symtab_node snode;
+
+ FOR_EACH_SYMBOL (snode)
+ if (symtab_real_symbol_p (snode)
+ && (res = pointer_map_contains (resolution_map,
+ snode->symbol.decl)))
+ snode->symbol.resolution
+ = (enum ld_plugin_symbol_resolution)(size_t)*res;
+
+ pointer_map_destroy (resolution_map);
+ resolution_map = NULL;
+ }
+
timevar_pop (TV_IPA_LTO_CGRAPH_IO);
if (!quiet_flag)
@@ -2960,18 +3000,10 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
if (seen_error ())
fatal_error ("errors during merging of translation units");
- /* Fixup all decls and types and free the type hash tables. */
+ /* Fixup all decls. */
lto_fixup_decls (all_file_decl_data);
htab_delete (tree_with_vars);
tree_with_vars = NULL;
- htab_delete (gimple_types);
- gimple_types = NULL;
- htab_delete (type_hash_cache);
- type_hash_cache = NULL;
- free (type_pair_cache);
- type_pair_cache = NULL;
- gimple_type_leader = NULL;
- free_gimple_type_tables ();
ggc_collect ();
timevar_pop (TV_IPA_LTO_DECL_MERGE);
@@ -2986,6 +3018,13 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
else
ipa_read_summaries ();
+ for (i = 0; all_file_decl_data[i]; i++)
+ {
+ gcc_assert (all_file_decl_data[i]->symtab_node_encoder);
+ lto_symtab_encoder_delete (all_file_decl_data[i]->symtab_node_encoder);
+ all_file_decl_data[i]->symtab_node_encoder = NULL;
+ }
+
/* Finally merge the cgraph according to the decl merging decisions. */
timevar_push (TV_IPA_LTO_CGRAPH_MERGE);
if (cgraph_dump_file)
diff --git a/gcc/machmode.h b/gcc/machmode.h
index bdaf1bee2..b95d05b09 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -217,6 +217,11 @@ extern const unsigned char mode_inner[NUM_MACHINE_MODES];
#define GET_MODE_UNIT_BITSIZE(MODE) \
((unsigned short) (GET_MODE_UNIT_SIZE (MODE) * BITS_PER_UNIT))
+#define GET_MODE_UNIT_PRECISION(MODE) \
+ (GET_MODE_INNER (MODE) == VOIDmode \
+ ? GET_MODE_PRECISION (MODE) \
+ : GET_MODE_PRECISION (GET_MODE_INNER (MODE)))
+
/* Get the number of units in the object. */
extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
diff --git a/gcc/optabs.c b/gcc/optabs.c
index cdd5d6976..8a6c6a330 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -7733,10 +7733,15 @@ maybe_emit_op (const struct atomic_op_functions *optab, rtx target, rtx mem,
CODE is the operation being performed (OP)
MEMMODEL is the memory model variant to use.
AFTER is true to return the result of the operation (OP_fetch).
- AFTER is false to return the value before the operation (fetch_OP). */
-rtx
-expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
- enum memmodel model, bool after)
+ AFTER is false to return the value before the operation (fetch_OP).
+
+ This function will *only* generate instructions if there is a direct
+ optab. No compare and swap loops or libcalls will be generated. */
+
+static rtx
+expand_atomic_fetch_op_no_fallback (rtx target, rtx mem, rtx val,
+ enum rtx_code code, enum memmodel model,
+ bool after)
{
enum machine_mode mode = GET_MODE (mem);
struct atomic_op_functions optab;
@@ -7809,13 +7814,66 @@ expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
}
}
+ /* No direct opcode can be generated. */
+ return NULL_RTX;
+}
+
+
+
+/* This function expands an atomic fetch_OP or OP_fetch operation:
+ TARGET is an option place to stick the return value. const0_rtx indicates
+ the result is unused.
+ atomically fetch MEM, perform the operation with VAL and return it to MEM.
+ CODE is the operation being performed (OP)
+ MEMMODEL is the memory model variant to use.
+ AFTER is true to return the result of the operation (OP_fetch).
+ AFTER is false to return the value before the operation (fetch_OP). */
+rtx
+expand_atomic_fetch_op (rtx target, rtx mem, rtx val, enum rtx_code code,
+ enum memmodel model, bool after)
+{
+ enum machine_mode mode = GET_MODE (mem);
+ rtx result;
+ bool unused_result = (target == const0_rtx);
+
+ result = expand_atomic_fetch_op_no_fallback (target, mem, val, code, model,
+ after);
+
+ if (result)
+ return result;
+
+ /* Add/sub can be implemented by doing the reverse operation with -(val). */
+ if (code == PLUS || code == MINUS)
+ {
+ rtx tmp;
+ enum rtx_code reverse = (code == PLUS ? MINUS : PLUS);
+
+ start_sequence ();
+ tmp = expand_simple_unop (mode, NEG, val, NULL_RTX, true);
+ result = expand_atomic_fetch_op_no_fallback (target, mem, tmp, reverse,
+ model, after);
+ if (result)
+ {
+ /* PLUS worked so emit the insns and return. */
+ tmp = get_insns ();
+ end_sequence ();
+ emit_insn (tmp);
+ return result;
+ }
+
+ /* PLUS did not work, so throw away the negation code and continue. */
+ end_sequence ();
+ }
+
/* Try the __sync libcalls only if we can't do compare-and-swap inline. */
if (!can_compare_and_swap_p (mode, false))
{
rtx libfunc;
bool fixup = false;
enum rtx_code orig_code = code;
+ struct atomic_op_functions optab;
+ get_atomic_op_for_code (&optab, code);
libfunc = optab_libfunc (after ? optab.fetch_after
: optab.fetch_before, mode);
if (libfunc == NULL
diff --git a/gcc/opts-global.c b/gcc/opts-global.c
index b93d56fcd..ccbfeef24 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -233,6 +233,40 @@ read_cmdline_options (struct gcc_options *opts, struct gcc_options *opts_set,
}
}
+/* Handle -ftree-vectorizer-verbose=ARG by remapping it to -fopt-info.
+ It remaps the old verbosity values as following:
+
+ REPORT_NONE ==> No dump is output
+ REPORT_VECTORIZED_LOCATIONS ==> "-optimized"
+ REPORT_UNVECTORIZED_LOCATIONS ==> "-missed"
+
+ Any higher verbosity levels get mapped to "-optall" flags. */
+
+static void
+dump_remap_tree_vectorizer_verbose (const char *arg)
+{
+ int value = atoi (arg);
+ const char *remapped_opt_info = NULL;
+
+ switch (value)
+ {
+ case 0:
+ break;
+ case 1:
+ remapped_opt_info = "optimized";
+ break;
+ case 2:
+ remapped_opt_info = "missed";
+ break;
+ default:
+ remapped_opt_info = "optall";
+ break;
+ }
+
+ if (remapped_opt_info)
+ opt_info_switch_p (remapped_opt_info);
+}
+
/* Language mask determined at initialization. */
static unsigned int initial_lang_mask;
@@ -322,6 +356,9 @@ handle_common_deferred_options (void)
if (flag_dump_all_passed)
enable_rtl_dump_file ();
+ if (flag_opt_info)
+ opt_info_switch_p (NULL);
+
FOR_EACH_VEC_ELT (cl_deferred_option, vec, i, opt)
{
switch (opt->opt_index)
@@ -351,6 +388,12 @@ handle_common_deferred_options (void)
error ("unrecognized command line option %<-fdump-%s%>", opt->arg);
break;
+ case OPT_fopt_info_:
+ if (!opt_info_switch_p (opt->arg))
+ error ("unrecognized command line option %<-fopt-info%s%>",
+ opt->arg);
+ break;
+
case OPT_fenable_:
case OPT_fdisable_:
if (opt->opt_index == OPT_fenable_)
@@ -410,6 +453,10 @@ handle_common_deferred_options (void)
stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt->arg));
break;
+ case OPT_ftree_vectorizer_verbose_:
+ dump_remap_tree_vectorizer_verbose (opt->arg);
+ break;
+
default:
gcc_unreachable ();
}
diff --git a/gcc/opts.c b/gcc/opts.c
index 5ab9ad9c4..ccfe3c70a 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -139,19 +139,6 @@ set_struct_debug_option (struct gcc_options *opts, location_t loc,
}
}
-/* Handle -ftree-vectorizer-verbose=VAL for options OPTS. */
-
-static void
-vect_set_verbosity_level (struct gcc_options *opts, int val)
-{
- if (val < MAX_VERBOSITY_LEVEL)
- opts->x_user_vect_verbosity_level = (enum vect_verbosity_levels) val;
- else
- opts->x_user_vect_verbosity_level
- = (enum vect_verbosity_levels) (MAX_VERBOSITY_LEVEL - 1);
-}
-
-
/* Strip off a legitimate source ending from the input string NAME of
length LEN. Rather than having to know the names used by all of
our front ends, we strip off an ending of a period followed by
@@ -1488,6 +1475,8 @@ common_handle_option (struct gcc_options *opts,
strip_off_ending (tmp, strlen (tmp));
if (tmp[0])
opts->x_aux_base_name = tmp;
+ else
+ free (tmp);
}
break;
@@ -1559,6 +1548,11 @@ common_handle_option (struct gcc_options *opts,
diagnostic_set_caret_max_width (dc, value);
break;
+ case OPT_fopt_info:
+ case OPT_fopt_info_:
+ /* Deferred. */
+ break;
+
case OPT_fpack_struct_:
if (value <= 0 || (value & (value - 1)) || value > 16)
error_at (loc,
@@ -1694,7 +1688,9 @@ common_handle_option (struct gcc_options *opts,
break;
case OPT_ftree_vectorizer_verbose_:
- vect_set_verbosity_level (opts, value);
+ /* -ftree-vectorizer-verbose is deprecated. It is defined in
+ -terms of fopt-info=N. */
+ /* Deferred. */
break;
case OPT_g:
diff --git a/gcc/passes.c b/gcc/passes.c
index ba4e98e06..27bdb8294 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -231,27 +231,23 @@ finish_optimization_passes (void)
timevar_push (TV_DUMP);
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
- dump_file = dump_begin (pass_profile.pass.static_pass_number, NULL);
+ dump_start (pass_profile.pass.static_pass_number, NULL);
end_branch_prob ();
- if (dump_file)
- dump_end (pass_profile.pass.static_pass_number, dump_file);
+ dump_finish (pass_profile.pass.static_pass_number);
}
if (optimize > 0)
{
- dump_file = dump_begin (pass_combine.pass.static_pass_number, NULL);
- if (dump_file)
- {
- dump_combine_total_stats (dump_file);
- dump_end (pass_combine.pass.static_pass_number, dump_file);
- }
+ dump_start (pass_profile.pass.static_pass_number, NULL);
+ print_combine_total_stats ();
+ dump_finish (pass_combine.pass.static_pass_number);
}
/* Do whatever is necessary to finish printing the graphs. */
if (graph_dump_format != no_graph)
for (i = TDI_end; (dfi = get_dump_file_info (i)) != NULL; ++i)
if (dump_initialized_p (i)
- && (dfi->flags & TDF_GRAPH) != 0
+ && (dfi->pflags & TDF_GRAPH) != 0
&& (name = get_dump_file_name (i)) != NULL)
{
finish_graph_dump_file (name);
@@ -1238,9 +1234,9 @@ register_pass (struct register_pass_info *pass_info)
else
tdi = TDI_rtl_all;
/* Check if dump-all flag is specified. */
- if (get_dump_file_info (tdi)->state)
+ if (get_dump_file_info (tdi)->pstate)
get_dump_file_info (added_pass_nodes->pass->static_pass_number)
- ->state = get_dump_file_info (tdi)->state;
+ ->pstate = get_dump_file_info (tdi)->pstate;
XDELETE (added_pass_nodes);
added_pass_nodes = next_node;
}
@@ -1782,6 +1778,209 @@ execute_function_dump (void *data ATTRIBUTE_UNUSED)
}
}
+/* Make statistic about profile consistency. */
+
+struct profile_record
+{
+ int num_mismatched_freq_in[2];
+ int num_mismatched_freq_out[2];
+ int num_mismatched_count_in[2];
+ int num_mismatched_count_out[2];
+ bool run;
+ gcov_type time[2];
+ int size[2];
+};
+
+static struct profile_record *profile_record;
+
+static void
+check_profile_consistency (int index, int subpass, bool run)
+{
+ basic_block bb;
+ edge_iterator ei;
+ edge e;
+ int sum;
+ gcov_type lsum;
+
+ if (index == -1)
+ return;
+ if (!profile_record)
+ profile_record = XCNEWVEC (struct profile_record,
+ passes_by_id_size);
+ gcc_assert (index < passes_by_id_size && index >= 0);
+ gcc_assert (subpass < 2);
+ profile_record[index].run |= run;
+
+ FOR_ALL_BB (bb)
+ {
+ if (bb != EXIT_BLOCK_PTR_FOR_FUNCTION (cfun)
+ && profile_status != PROFILE_ABSENT)
+ {
+ sum = 0;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ sum += e->probability;
+ if (EDGE_COUNT (bb->succs) && abs (sum - REG_BR_PROB_BASE) > 100)
+ profile_record[index].num_mismatched_freq_out[subpass]++;
+ lsum = 0;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ lsum += e->count;
+ if (EDGE_COUNT (bb->succs)
+ && (lsum - bb->count > 100 || lsum - bb->count < -100))
+ profile_record[index].num_mismatched_count_out[subpass]++;
+ }
+ if (bb != ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)
+ && profile_status != PROFILE_ABSENT)
+ {
+ sum = 0;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ sum += EDGE_FREQUENCY (e);
+ if (abs (sum - bb->frequency) > 100
+ || (MAX (sum, bb->frequency) > 10
+ && abs ((sum - bb->frequency) * 100 / (MAX (sum, bb->frequency) + 1)) > 10))
+ profile_record[index].num_mismatched_freq_in[subpass]++;
+ lsum = 0;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ lsum += e->count;
+ if (lsum - bb->count > 100 || lsum - bb->count < -100)
+ profile_record[index].num_mismatched_count_in[subpass]++;
+ }
+ if (bb == ENTRY_BLOCK_PTR_FOR_FUNCTION (cfun)
+ || bb == EXIT_BLOCK_PTR_FOR_FUNCTION (cfun))
+ continue;
+ if ((cfun && (cfun->curr_properties & PROP_trees)))
+ {
+ gimple_stmt_iterator i;
+
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
+ {
+ profile_record[index].size[subpass]
+ += estimate_num_insns (gsi_stmt (i), &eni_size_weights);
+ if (profile_status == PROFILE_READ)
+ profile_record[index].time[subpass]
+ += estimate_num_insns (gsi_stmt (i),
+ &eni_time_weights) * bb->count;
+ else if (profile_status == PROFILE_GUESSED)
+ profile_record[index].time[subpass]
+ += estimate_num_insns (gsi_stmt (i),
+ &eni_time_weights) * bb->frequency;
+ }
+ }
+ else if (cfun && (cfun->curr_properties & PROP_rtl))
+ {
+ rtx insn;
+ for (insn = NEXT_INSN (BB_HEAD (bb)); insn && insn != NEXT_INSN (BB_END (bb));
+ insn = NEXT_INSN (insn))
+ if (INSN_P (insn))
+ {
+ profile_record[index].size[subpass]
+ += insn_rtx_cost (PATTERN (insn), false);
+ if (profile_status == PROFILE_READ)
+ profile_record[index].time[subpass]
+ += insn_rtx_cost (PATTERN (insn), true) * bb->count;
+ else if (profile_status == PROFILE_GUESSED)
+ profile_record[index].time[subpass]
+ += insn_rtx_cost (PATTERN (insn), true) * bb->frequency;
+ }
+ }
+ }
+}
+
+/* Output profile consistency. */
+
+void
+dump_profile_report (void)
+{
+ int i, j;
+ int last_freq_in = 0, last_count_in = 0, last_freq_out = 0, last_count_out = 0;
+ gcov_type last_time = 0, last_size = 0;
+ double rel_time_change, rel_size_change;
+ int last_reported = 0;
+
+ if (!profile_record)
+ return;
+ fprintf (stderr, "\nProfile consistency report:\n\n");
+ fprintf (stderr, "Pass name |mismatch in |mismated out|Overall\n");
+ fprintf (stderr, " |freq count |freq count |size time\n");
+
+ for (i = 0; i < passes_by_id_size; i++)
+ for (j = 0 ; j < 2; j++)
+ if (profile_record[i].run)
+ {
+ if (last_time)
+ rel_time_change = (profile_record[i].time[j]
+ - (double)last_time) * 100 / (double)last_time;
+ else
+ rel_time_change = 0;
+ if (last_size)
+ rel_size_change = (profile_record[i].size[j]
+ - (double)last_size) * 100 / (double)last_size;
+ else
+ rel_size_change = 0;
+
+ if (profile_record[i].num_mismatched_freq_in[j] != last_freq_in
+ || profile_record[i].num_mismatched_freq_out[j] != last_freq_out
+ || profile_record[i].num_mismatched_count_in[j] != last_count_in
+ || profile_record[i].num_mismatched_count_out[j] != last_count_out
+ || rel_time_change || rel_size_change)
+ {
+ last_reported = i;
+ fprintf (stderr, "%-20s %s",
+ passes_by_id [i]->name,
+ j ? "(after TODO)" : " ");
+ if (profile_record[i].num_mismatched_freq_in[j] != last_freq_in)
+ fprintf (stderr, "| %+5i",
+ profile_record[i].num_mismatched_freq_in[j]
+ - last_freq_in);
+ else
+ fprintf (stderr, "| ");
+ if (profile_record[i].num_mismatched_count_in[j] != last_count_in)
+ fprintf (stderr, " %+5i",
+ profile_record[i].num_mismatched_count_in[j]
+ - last_count_in);
+ else
+ fprintf (stderr, " ");
+ if (profile_record[i].num_mismatched_freq_out[j] != last_freq_out)
+ fprintf (stderr, "| %+5i",
+ profile_record[i].num_mismatched_freq_out[j]
+ - last_freq_out);
+ else
+ fprintf (stderr, "| ");
+ if (profile_record[i].num_mismatched_count_out[j] != last_count_out)
+ fprintf (stderr, " %+5i",
+ profile_record[i].num_mismatched_count_out[j]
+ - last_count_out);
+ else
+ fprintf (stderr, " ");
+
+ /* Size/time units change across gimple and RTL. */
+ if (i == pass_expand.pass.static_pass_number)
+ fprintf (stderr, "|----------");
+ else
+ {
+ if (rel_size_change)
+ fprintf (stderr, "| %+8.4f%%", rel_size_change);
+ else
+ fprintf (stderr, "| ");
+ if (rel_time_change)
+ fprintf (stderr, " %+8.4f%%", rel_time_change);
+ }
+ fprintf (stderr, "\n");
+ last_freq_in = profile_record[i].num_mismatched_freq_in[j];
+ last_freq_out = profile_record[i].num_mismatched_freq_out[j];
+ last_count_in = profile_record[i].num_mismatched_count_in[j];
+ last_count_out = profile_record[i].num_mismatched_count_out[j];
+ }
+ else if (j && last_reported != i)
+ {
+ last_reported = i;
+ fprintf (stderr, "%-20s ------------| | |\n",
+ passes_by_id [i]->name);
+ }
+ last_time = profile_record[i].time[j];
+ last_size = profile_record[i].size[j];
+ }
+}
+
/* Perform all TODO actions that ought to be done on each function. */
static void
@@ -1945,7 +2144,7 @@ pass_init_dump_file (struct opt_pass *pass)
{
bool initializing_dump = !dump_initialized_p (pass->static_pass_number);
dump_file_name = get_dump_file_name (pass->static_pass_number);
- dump_file = dump_begin (pass->static_pass_number, &dump_flags);
+ dump_start (pass->static_pass_number, &dump_flags);
if (dump_file && current_function_decl)
dump_function_header (dump_file, current_function_decl, dump_flags);
return initializing_dump;
@@ -1967,11 +2166,7 @@ pass_fini_dump_file (struct opt_pass *pass)
dump_file_name = NULL;
}
- if (dump_file)
- {
- dump_end (pass->static_pass_number, dump_file);
- dump_file = NULL;
- }
+ dump_finish (pass->static_pass_number);
}
/* After executing the pass, apply expected changes to the function
@@ -2050,9 +2245,14 @@ execute_one_ipa_transform_pass (struct cgraph_node *node,
if (pass->tv_id != TV_NONE)
timevar_pop (pass->tv_id);
+ if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
+ check_profile_consistency (pass->static_pass_number, 0, true);
+
/* Run post-pass cleanup and verification. */
execute_todo (todo_after);
verify_interpass_invariants ();
+ if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
+ check_profile_consistency (pass->static_pass_number, 1, true);
do_per_function (execute_function_dump, NULL);
pass_fini_dump_file (pass);
@@ -2152,6 +2352,13 @@ execute_one_pass (struct opt_pass *pass)
if (!gate_status)
{
+ /* Run so passes selectively disabling themselves on a given function
+ are not miscounted. */
+ if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
+ {
+ check_profile_consistency (pass->static_pass_number, 0, false);
+ check_profile_consistency (pass->static_pass_number, 1, false);
+ }
current_pass = NULL;
return false;
}
@@ -2213,13 +2420,19 @@ execute_one_pass (struct opt_pass *pass)
&& (cfun->curr_properties & (PROP_cfg | PROP_rtl))
== (PROP_cfg | PROP_rtl))
{
- get_dump_file_info (pass->static_pass_number)->flags |= TDF_GRAPH;
+ get_dump_file_info (pass->static_pass_number)->pflags |= TDF_GRAPH;
dump_flags |= TDF_GRAPH;
clean_graph_dump_file (dump_file_name);
}
+ if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
+ check_profile_consistency (pass->static_pass_number, 0, true);
+
/* Run post-pass cleanup and verification. */
execute_todo (todo_after | pass->todo_flags_finish);
+ if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
+ check_profile_consistency (pass->static_pass_number, 1, true);
+
verify_interpass_invariants ();
do_per_function (execute_function_dump, NULL);
if (pass->type == IPA_PASS)
@@ -2331,7 +2544,7 @@ ipa_write_summaries (void)
if (!flag_generate_lto || seen_error ())
return;
- encoder = lto_symtab_encoder_new ();
+ encoder = lto_symtab_encoder_new (false);
/* Create the callgraph set in the same order used in
cgraph_expand_all_functions. This mostly facilitates debugging,
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index cdd85001b..076036c5c 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -839,6 +839,8 @@ static struct reg_pref *reg_pref;
/* Current size of reg_info. */
static int reg_info_size;
+/* Max_reg_num still last resize_reg_info call. */
+static int max_regno_since_last_resize;
/* Return the reg_class in which pseudo reg number REGNO is best allocated.
This function is sometimes called before the info has been computed.
@@ -849,6 +851,7 @@ reg_preferred_class (int regno)
if (reg_pref == 0)
return GENERAL_REGS;
+ gcc_assert (regno < reg_info_size);
return (enum reg_class) reg_pref[regno].prefclass;
}
@@ -858,6 +861,7 @@ reg_alternate_class (int regno)
if (reg_pref == 0)
return ALL_REGS;
+ gcc_assert (regno < reg_info_size);
return (enum reg_class) reg_pref[regno].altclass;
}
@@ -868,45 +872,64 @@ reg_allocno_class (int regno)
if (reg_pref == 0)
return NO_REGS;
+ gcc_assert (regno < reg_info_size);
return (enum reg_class) reg_pref[regno].allocnoclass;
}
-/* Allocate space for reg info. */
+/* Allocate space for reg info and initilize it. */
static void
allocate_reg_info (void)
{
- reg_info_size = max_reg_num ();
+ int i;
+
+ max_regno_since_last_resize = max_reg_num ();
+ reg_info_size = max_regno_since_last_resize * 3 / 2 + 1;
gcc_assert (! reg_pref && ! reg_renumber);
reg_renumber = XNEWVEC (short, reg_info_size);
reg_pref = XCNEWVEC (struct reg_pref, reg_info_size);
memset (reg_renumber, -1, reg_info_size * sizeof (short));
+ for (i = 0; i < reg_info_size; i++)
+ {
+ reg_pref[i].prefclass = GENERAL_REGS;
+ reg_pref[i].altclass = ALL_REGS;
+ reg_pref[i].allocnoclass = GENERAL_REGS;
+ }
}
-/* Resize reg info. The new elements will be uninitialized. Return
- TRUE if new elements (for new pseudos) were added. */
+/* Resize reg info. The new elements will be initialized. Return TRUE
+ if new pseudos were added since the last call. */
bool
resize_reg_info (void)
{
- int old;
+ int old, i;
+ bool change_p;
if (reg_pref == NULL)
{
allocate_reg_info ();
return true;
}
- if (reg_info_size == max_reg_num ())
- return false;
+ change_p = max_regno_since_last_resize != max_reg_num ();
+ max_regno_since_last_resize = max_reg_num ();
+ if (reg_info_size >= max_reg_num ())
+ return change_p;
old = reg_info_size;
- reg_info_size = max_reg_num ();
+ reg_info_size = max_reg_num () * 3 / 2 + 1;
gcc_assert (reg_pref && reg_renumber);
reg_renumber = XRESIZEVEC (short, reg_renumber, reg_info_size);
reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, reg_info_size);
memset (reg_pref + old, -1,
(reg_info_size - old) * sizeof (struct reg_pref));
memset (reg_renumber + old, -1, (reg_info_size - old) * sizeof (short));
+ for (i = old; i < reg_info_size; i++)
+ {
+ reg_pref[i].prefclass = GENERAL_REGS;
+ reg_pref[i].altclass = ALL_REGS;
+ reg_pref[i].allocnoclass = GENERAL_REGS;
+ }
return true;
}
@@ -938,6 +961,7 @@ reginfo_init (void)
/* This prevents dump_reg_info from losing if called
before reginfo is run. */
reg_pref = NULL;
+ reg_info_size = max_regno_since_last_resize = 0;
/* No more global register variables may be declared. */
no_global_reg_vars = 1;
return 1;
@@ -964,7 +988,7 @@ struct rtl_opt_pass pass_reginfo_init =
-/* Set up preferred, alternate, and cover classes for REGNO as
+/* Set up preferred, alternate, and allocno classes for REGNO as
PREFCLASS, ALTCLASS, and ALLOCNOCLASS. */
void
setup_reg_classes (int regno,
@@ -973,7 +997,7 @@ setup_reg_classes (int regno,
{
if (reg_pref == NULL)
return;
- gcc_assert (reg_info_size == max_reg_num ());
+ gcc_assert (reg_info_size >= max_reg_num ());
reg_pref[regno].prefclass = prefclass;
reg_pref[regno].altclass = altclass;
reg_pref[regno].allocnoclass = allocnoclass;
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 6625a53a6..936a1317b 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -4816,10 +4816,10 @@ find_mem (struct mem_inc_info *mii, rtx *address_of_x)
void
find_modifiable_mems (rtx head, rtx tail)
{
- rtx insn;
+ rtx insn, next_tail = NEXT_INSN (tail);
int success_in_block = 0;
- for (insn = head; insn != tail; insn = NEXT_INSN (insn))
+ for (insn = head; insn != next_tail; insn = NEXT_INSN (insn))
{
struct mem_inc_info mii;
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index af85ccc08..95cf1860a 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -564,6 +564,212 @@ simplify_replace_rtx (rtx x, const_rtx old_rtx, rtx new_rtx)
return simplify_replace_fn_rtx (x, old_rtx, 0, new_rtx);
}
+/* Try to simplify a MODE truncation of OP, which has OP_MODE.
+ Only handle cases where the truncated value is inherently an rvalue.
+
+ RTL provides two ways of truncating a value:
+
+ 1. a lowpart subreg. This form is only a truncation when both
+ the outer and inner modes (here MODE and OP_MODE respectively)
+ are scalar integers, and only then when the subreg is used as
+ an rvalue.
+
+ It is only valid to form such truncating subregs if the
+ truncation requires no action by the target. The onus for
+ proving this is on the creator of the subreg -- e.g. the
+ caller to simplify_subreg or simplify_gen_subreg -- and typically
+ involves either TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode.
+
+ 2. a TRUNCATE. This form handles both scalar and compound integers.
+
+ The first form is preferred where valid. However, the TRUNCATE
+ handling in simplify_unary_operation turns the second form into the
+ first form when TRULY_NOOP_TRUNCATION_MODES_P or truncated_to_mode allow,
+ so it is generally safe to form rvalue truncations using:
+
+ simplify_gen_unary (TRUNCATE, ...)
+
+ and leave simplify_unary_operation to work out which representation
+ should be used.
+
+ Because of the proof requirements on (1), simplify_truncation must
+ also use simplify_gen_unary (TRUNCATE, ...) to truncate parts of OP,
+ regardless of whether the outer truncation came from a SUBREG or a
+ TRUNCATE. For example, if the caller has proven that an SImode
+ truncation of:
+
+ (and:DI X Y)
+
+ is a no-op and can be represented as a subreg, it does not follow
+ that SImode truncations of X and Y are also no-ops. On a target
+ like 64-bit MIPS that requires SImode values to be stored in
+ sign-extended form, an SImode truncation of:
+
+ (and:DI (reg:DI X) (const_int 63))
+
+ is trivially a no-op because only the lower 6 bits can be set.
+ However, X is still an arbitrary 64-bit number and so we cannot
+ assume that truncating it too is a no-op. */
+
+static rtx
+simplify_truncation (enum machine_mode mode, rtx op,
+ enum machine_mode op_mode)
+{
+ unsigned int precision = GET_MODE_UNIT_PRECISION (mode);
+ unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode);
+ gcc_assert (precision <= op_precision);
+
+ /* Optimize truncations of zero and sign extended values. */
+ if (GET_CODE (op) == ZERO_EXTEND
+ || GET_CODE (op) == SIGN_EXTEND)
+ {
+ /* There are three possibilities. If MODE is the same as the
+ origmode, we can omit both the extension and the subreg.
+ If MODE is not larger than the origmode, we can apply the
+ truncation without the extension. Finally, if the outermode
+ is larger than the origmode, we can just extend to the appropriate
+ mode. */
+ enum machine_mode origmode = GET_MODE (XEXP (op, 0));
+ if (mode == origmode)
+ return XEXP (op, 0);
+ else if (precision <= GET_MODE_UNIT_PRECISION (origmode))
+ return simplify_gen_unary (TRUNCATE, mode,
+ XEXP (op, 0), origmode);
+ else
+ return simplify_gen_unary (GET_CODE (op), mode,
+ XEXP (op, 0), origmode);
+ }
+
+ /* Simplify (truncate:SI (op:DI (x:DI) (y:DI)))
+ to (op:SI (truncate:SI (x:DI)) (truncate:SI (x:DI))). */
+ if (GET_CODE (op) == PLUS
+ || GET_CODE (op) == MINUS
+ || GET_CODE (op) == MULT)
+ {
+ rtx op0 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), op_mode);
+ if (op0)
+ {
+ rtx op1 = simplify_gen_unary (TRUNCATE, mode, XEXP (op, 1), op_mode);
+ if (op1)
+ return simplify_gen_binary (GET_CODE (op), mode, op0, op1);
+ }
+ }
+
+ /* Simplify (truncate:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C)) into
+ to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
+ the outer subreg is effectively a truncation to the original mode. */
+ if ((GET_CODE (op) == LSHIFTRT
+ || GET_CODE (op) == ASHIFTRT)
+ /* Ensure that OP_MODE is at least twice as wide as MODE
+ to avoid the possibility that an outer LSHIFTRT shifts by more
+ than the sign extension's sign_bit_copies and introduces zeros
+ into the high bits of the result. */
+ && 2 * precision <= op_precision
+ && CONST_INT_P (XEXP (op, 1))
+ && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
+ && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
+ && INTVAL (XEXP (op, 1)) < precision)
+ return simplify_gen_binary (ASHIFTRT, mode,
+ XEXP (XEXP (op, 0), 0), XEXP (op, 1));
+
+ /* Likewise (truncate:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C)) into
+ to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
+ the outer subreg is effectively a truncation to the original mode. */
+ if ((GET_CODE (op) == LSHIFTRT
+ || GET_CODE (op) == ASHIFTRT)
+ && CONST_INT_P (XEXP (op, 1))
+ && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
+ && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
+ && INTVAL (XEXP (op, 1)) < precision)
+ return simplify_gen_binary (LSHIFTRT, mode,
+ XEXP (XEXP (op, 0), 0), XEXP (op, 1));
+
+ /* Likewise (truncate:QI (ashift:SI (zero_extend:SI (x:QI)) C)) into
+ to (ashift:QI (x:QI) C), where C is a suitable small constant and
+ the outer subreg is effectively a truncation to the original mode. */
+ if (GET_CODE (op) == ASHIFT
+ && CONST_INT_P (XEXP (op, 1))
+ && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
+ || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
+ && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode
+ && INTVAL (XEXP (op, 1)) < precision)
+ return simplify_gen_binary (ASHIFT, mode,
+ XEXP (XEXP (op, 0), 0), XEXP (op, 1));
+
+ /* Recognize a word extraction from a multi-word subreg. */
+ if ((GET_CODE (op) == LSHIFTRT
+ || GET_CODE (op) == ASHIFTRT)
+ && SCALAR_INT_MODE_P (mode)
+ && SCALAR_INT_MODE_P (op_mode)
+ && precision >= BITS_PER_WORD
+ && 2 * precision <= op_precision
+ && CONST_INT_P (XEXP (op, 1))
+ && (INTVAL (XEXP (op, 1)) & (precision - 1)) == 0
+ && INTVAL (XEXP (op, 1)) >= 0
+ && INTVAL (XEXP (op, 1)) < op_precision)
+ {
+ int byte = subreg_lowpart_offset (mode, op_mode);
+ int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
+ return simplify_gen_subreg (mode, XEXP (op, 0), op_mode,
+ (WORDS_BIG_ENDIAN
+ ? byte - shifted_bytes
+ : byte + shifted_bytes));
+ }
+
+ /* If we have a TRUNCATE of a right shift of MEM, make a new MEM
+ and try replacing the TRUNCATE and shift with it. Don't do this
+ if the MEM has a mode-dependent address. */
+ if ((GET_CODE (op) == LSHIFTRT
+ || GET_CODE (op) == ASHIFTRT)
+ && SCALAR_INT_MODE_P (op_mode)
+ && MEM_P (XEXP (op, 0))
+ && CONST_INT_P (XEXP (op, 1))
+ && (INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (mode)) == 0
+ && INTVAL (XEXP (op, 1)) > 0
+ && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (op_mode)
+ && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
+ MEM_ADDR_SPACE (XEXP (op, 0)))
+ && ! MEM_VOLATILE_P (XEXP (op, 0))
+ && (GET_MODE_SIZE (mode) >= UNITS_PER_WORD
+ || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
+ {
+ int byte = subreg_lowpart_offset (mode, op_mode);
+ int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
+ return adjust_address_nv (XEXP (op, 0), mode,
+ (WORDS_BIG_ENDIAN
+ ? byte - shifted_bytes
+ : byte + shifted_bytes));
+ }
+
+ /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
+ (OP:SI foo:SI) if OP is NEG or ABS. */
+ if ((GET_CODE (op) == ABS
+ || GET_CODE (op) == NEG)
+ && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
+ || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
+ && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
+ return simplify_gen_unary (GET_CODE (op), mode,
+ XEXP (XEXP (op, 0), 0), mode);
+
+ /* (truncate:A (subreg:B (truncate:C X) 0)) is
+ (truncate:A X). */
+ if (GET_CODE (op) == SUBREG
+ && SCALAR_INT_MODE_P (mode)
+ && SCALAR_INT_MODE_P (op_mode)
+ && SCALAR_INT_MODE_P (GET_MODE (SUBREG_REG (op)))
+ && GET_CODE (SUBREG_REG (op)) == TRUNCATE
+ && subreg_lowpart_p (op))
+ return simplify_gen_unary (TRUNCATE, mode, XEXP (SUBREG_REG (op), 0),
+ GET_MODE (XEXP (SUBREG_REG (op), 0)));
+
+ /* (truncate:A (truncate:B X)) is (truncate:A X). */
+ if (GET_CODE (op) == TRUNCATE)
+ return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0),
+ GET_MODE (XEXP (op, 0)));
+
+ return NULL_RTX;
+}
+
/* Try to simplify a unary operation CODE whose output mode is to be
MODE with input operand OP whose mode was originally OP_MODE.
Return zero if no simplification can be made. */
@@ -815,50 +1021,34 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
break;
case TRUNCATE:
- /* We can't handle truncation to a partial integer mode here
- because we don't know the real bitsize of the partial
- integer mode. */
- if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
- break;
-
- /* (truncate:SI ({sign,zero}_extend:DI foo:SI)) == foo:SI. */
- if ((GET_CODE (op) == SIGN_EXTEND
- || GET_CODE (op) == ZERO_EXTEND)
- && GET_MODE (XEXP (op, 0)) == mode)
- return XEXP (op, 0);
+ /* Don't optimize (lshiftrt (mult ...)) as it would interfere
+ with the umulXi3_highpart patterns. */
+ if (GET_CODE (op) == LSHIFTRT
+ && GET_CODE (XEXP (op, 0)) == MULT)
+ break;
- /* (truncate:SI (OP:DI ({sign,zero}_extend:DI foo:SI))) is
- (OP:SI foo:SI) if OP is NEG or ABS. */
- if ((GET_CODE (op) == ABS
- || GET_CODE (op) == NEG)
- && (GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
- || GET_CODE (XEXP (op, 0)) == ZERO_EXTEND)
- && GET_MODE (XEXP (XEXP (op, 0), 0)) == mode)
- return simplify_gen_unary (GET_CODE (op), mode,
- XEXP (XEXP (op, 0), 0), mode);
+ if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT)
+ {
+ if (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op)))
+ return rtl_hooks.gen_lowpart_no_emit (mode, op);
+ /* We can't handle truncation to a partial integer mode here
+ because we don't know the real bitsize of the partial
+ integer mode. */
+ break;
+ }
- /* (truncate:A (subreg:B (truncate:C X) 0)) is
- (truncate:A X). */
- if (GET_CODE (op) == SUBREG
- && GET_CODE (SUBREG_REG (op)) == TRUNCATE
- && subreg_lowpart_p (op))
- return simplify_gen_unary (TRUNCATE, mode, XEXP (SUBREG_REG (op), 0),
- GET_MODE (XEXP (SUBREG_REG (op), 0)));
+ if (GET_MODE (op) != VOIDmode)
+ {
+ temp = simplify_truncation (mode, op, GET_MODE (op));
+ if (temp)
+ return temp;
+ }
/* If we know that the value is already truncated, we can
- replace the TRUNCATE with a SUBREG. Note that this is also
- valid if TRULY_NOOP_TRUNCATION is false for the corresponding
- modes we just have to apply a different definition for
- truncation. But don't do this for an (LSHIFTRT (MULT ...))
- since this will cause problems with the umulXi3_highpart
- patterns. */
- if ((TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
- ? (num_sign_bit_copies (op, GET_MODE (op))
- > (unsigned int) (GET_MODE_PRECISION (GET_MODE (op))
- - GET_MODE_PRECISION (mode)))
- : truncated_to_mode (mode, op))
- && ! (GET_CODE (op) == LSHIFTRT
- && GET_CODE (XEXP (op, 0)) == MULT))
+ replace the TRUNCATE with a SUBREG. */
+ if (GET_MODE_NUNITS (mode) == 1
+ && (TRULY_NOOP_TRUNCATION_MODES_P (mode, GET_MODE (op))
+ || truncated_to_mode (mode, op)))
return rtl_hooks.gen_lowpart_no_emit (mode, op);
/* A truncate of a comparison can be replaced with a subreg if
@@ -873,6 +1063,7 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op)
/* A truncate of a memory is just loading the low part of the memory
if we are not changing the meaning of the address. */
if (GET_CODE (op) == MEM
+ && !VECTOR_MODE_P (mode)
&& !MEM_VOLATILE_P (op)
&& !mode_dependent_address_p (XEXP (op, 0), MEM_ADDR_SPACE (op)))
return rtl_hooks.gen_lowpart_no_emit (mode, op);
@@ -3246,6 +3437,23 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
return gen_rtx_CONST_VECTOR (mode, v);
}
+ /* Recognize the identity. */
+ if (GET_MODE (trueop0) == mode)
+ {
+ bool maybe_ident = true;
+ for (int i = 0; i < XVECLEN (trueop1, 0); i++)
+ {
+ rtx j = XVECEXP (trueop1, 0, i);
+ if (!CONST_INT_P (j) || INTVAL (j) != i)
+ {
+ maybe_ident = false;
+ break;
+ }
+ }
+ if (maybe_ident)
+ return trueop0;
+ }
+
/* If we build {a,b} then permute it, build the result directly. */
if (XVECLEN (trueop1, 0) == 2
&& CONST_INT_P (XVECEXP (trueop1, 0, 0))
@@ -3371,6 +3579,24 @@ simplify_binary_operation_1 (enum rtx_code code, enum machine_mode mode,
return gen_rtx_CONST_VECTOR (mode, v);
}
+
+ /* Try to merge VEC_SELECTs from the same vector into a single one. */
+ if (GET_CODE (trueop0) == VEC_SELECT
+ && GET_CODE (trueop1) == VEC_SELECT
+ && rtx_equal_p (XEXP (trueop0, 0), XEXP (trueop1, 0)))
+ {
+ rtx par0 = XEXP (trueop0, 1);
+ rtx par1 = XEXP (trueop1, 1);
+ int len0 = XVECLEN (par0, 0);
+ int len1 = XVECLEN (par1, 0);
+ rtvec vec = rtvec_alloc (len0 + len1);
+ for (int i = 0; i < len0; i++)
+ RTVEC_ELT (vec, i) = XVECEXP (par0, 0, i);
+ for (int i = 0; i < len1; i++)
+ RTVEC_ELT (vec, len0 + i) = XVECEXP (par1, 0, i);
+ return simplify_gen_binary (VEC_SELECT, mode, XEXP (trueop0, 0),
+ gen_rtx_PARALLEL (VOIDmode, vec));
+ }
}
return 0;
@@ -5560,14 +5786,6 @@ simplify_subreg (enum machine_mode outermode, rtx op,
return NULL_RTX;
}
- /* Merge implicit and explicit truncations. */
-
- if (GET_CODE (op) == TRUNCATE
- && GET_MODE_SIZE (outermode) < GET_MODE_SIZE (innermode)
- && subreg_lowpart_offset (outermode, innermode) == byte)
- return simplify_gen_unary (TRUNCATE, outermode, XEXP (op, 0),
- GET_MODE (XEXP (op, 0)));
-
/* SUBREG of a hard register => just change the register number
and/or mode. If the hard register is not valid in that mode,
suppress this simplification. If the hard register is the stack,
@@ -5653,138 +5871,23 @@ simplify_subreg (enum machine_mode outermode, rtx op,
return NULL_RTX;
}
- /* Optimize SUBREG truncations of zero and sign extended values. */
- if ((GET_CODE (op) == ZERO_EXTEND
- || GET_CODE (op) == SIGN_EXTEND)
- && SCALAR_INT_MODE_P (innermode)
- && GET_MODE_PRECISION (outermode) < GET_MODE_PRECISION (innermode))
+ /* A SUBREG resulting from a zero extension may fold to zero if
+ it extracts higher bits that the ZERO_EXTEND's source bits. */
+ if (GET_CODE (op) == ZERO_EXTEND)
{
unsigned int bitpos = subreg_lsb_1 (outermode, innermode, byte);
-
- /* If we're requesting the lowpart of a zero or sign extension,
- there are three possibilities. If the outermode is the same
- as the origmode, we can omit both the extension and the subreg.
- If the outermode is not larger than the origmode, we can apply
- the truncation without the extension. Finally, if the outermode
- is larger than the origmode, but both are integer modes, we
- can just extend to the appropriate mode. */
- if (bitpos == 0)
- {
- enum machine_mode origmode = GET_MODE (XEXP (op, 0));
- if (outermode == origmode)
- return XEXP (op, 0);
- if (GET_MODE_PRECISION (outermode) <= GET_MODE_PRECISION (origmode))
- return simplify_gen_subreg (outermode, XEXP (op, 0), origmode,
- subreg_lowpart_offset (outermode,
- origmode));
- if (SCALAR_INT_MODE_P (outermode))
- return simplify_gen_unary (GET_CODE (op), outermode,
- XEXP (op, 0), origmode);
- }
-
- /* A SUBREG resulting from a zero extension may fold to zero if
- it extracts higher bits that the ZERO_EXTEND's source bits. */
- if (GET_CODE (op) == ZERO_EXTEND
- && bitpos >= GET_MODE_PRECISION (GET_MODE (XEXP (op, 0))))
+ if (bitpos >= GET_MODE_PRECISION (GET_MODE (XEXP (op, 0))))
return CONST0_RTX (outermode);
}
- /* Simplify (subreg:QI (lshiftrt:SI (sign_extend:SI (x:QI)) C), 0) into
- to (ashiftrt:QI (x:QI) C), where C is a suitable small constant and
- the outer subreg is effectively a truncation to the original mode. */
- if ((GET_CODE (op) == LSHIFTRT
- || GET_CODE (op) == ASHIFTRT)
- && SCALAR_INT_MODE_P (outermode)
- && SCALAR_INT_MODE_P (innermode)
- /* Ensure that OUTERMODE is at least twice as wide as the INNERMODE
- to avoid the possibility that an outer LSHIFTRT shifts by more
- than the sign extension's sign_bit_copies and introduces zeros
- into the high bits of the result. */
- && (2 * GET_MODE_PRECISION (outermode)) <= GET_MODE_PRECISION (innermode)
- && CONST_INT_P (XEXP (op, 1))
- && GET_CODE (XEXP (op, 0)) == SIGN_EXTEND
- && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
- && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (outermode)
- && subreg_lsb_1 (outermode, innermode, byte) == 0)
- return simplify_gen_binary (ASHIFTRT, outermode,
- XEXP (XEXP (op, 0), 0), XEXP (op, 1));
-
- /* Likewise (subreg:QI (lshiftrt:SI (zero_extend:SI (x:QI)) C), 0) into
- to (lshiftrt:QI (x:QI) C), where C is a suitable small constant and
- the outer subreg is effectively a truncation to the original mode. */
- if ((GET_CODE (op) == LSHIFTRT
- || GET_CODE (op) == ASHIFTRT)
- && SCALAR_INT_MODE_P (outermode)
- && SCALAR_INT_MODE_P (innermode)
- && GET_MODE_PRECISION (outermode) < GET_MODE_PRECISION (innermode)
- && CONST_INT_P (XEXP (op, 1))
- && GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
- && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
- && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (outermode)
- && subreg_lsb_1 (outermode, innermode, byte) == 0)
- return simplify_gen_binary (LSHIFTRT, outermode,
- XEXP (XEXP (op, 0), 0), XEXP (op, 1));
-
- /* Likewise (subreg:QI (ashift:SI (zero_extend:SI (x:QI)) C), 0) into
- to (ashift:QI (x:QI) C), where C is a suitable small constant and
- the outer subreg is effectively a truncation to the original mode. */
- if (GET_CODE (op) == ASHIFT
- && SCALAR_INT_MODE_P (outermode)
+ if (SCALAR_INT_MODE_P (outermode)
&& SCALAR_INT_MODE_P (innermode)
&& GET_MODE_PRECISION (outermode) < GET_MODE_PRECISION (innermode)
- && CONST_INT_P (XEXP (op, 1))
- && (GET_CODE (XEXP (op, 0)) == ZERO_EXTEND
- || GET_CODE (XEXP (op, 0)) == SIGN_EXTEND)
- && GET_MODE (XEXP (XEXP (op, 0), 0)) == outermode
- && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (outermode)
- && subreg_lsb_1 (outermode, innermode, byte) == 0)
- return simplify_gen_binary (ASHIFT, outermode,
- XEXP (XEXP (op, 0), 0), XEXP (op, 1));
-
- /* Recognize a word extraction from a multi-word subreg. */
- if ((GET_CODE (op) == LSHIFTRT
- || GET_CODE (op) == ASHIFTRT)
- && SCALAR_INT_MODE_P (innermode)
- && GET_MODE_PRECISION (outermode) >= BITS_PER_WORD
- && GET_MODE_PRECISION (innermode) >= (2 * GET_MODE_PRECISION (outermode))
- && CONST_INT_P (XEXP (op, 1))
- && (INTVAL (XEXP (op, 1)) & (GET_MODE_PRECISION (outermode) - 1)) == 0
- && INTVAL (XEXP (op, 1)) >= 0
- && INTVAL (XEXP (op, 1)) < GET_MODE_PRECISION (innermode)
&& byte == subreg_lowpart_offset (outermode, innermode))
{
- int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
- return simplify_gen_subreg (outermode, XEXP (op, 0), innermode,
- (WORDS_BIG_ENDIAN
- ? byte - shifted_bytes
- : byte + shifted_bytes));
- }
-
- /* If we have a lowpart SUBREG of a right shift of MEM, make a new MEM
- and try replacing the SUBREG and shift with it. Don't do this if
- the MEM has a mode-dependent address or if we would be widening it. */
-
- if ((GET_CODE (op) == LSHIFTRT
- || GET_CODE (op) == ASHIFTRT)
- && SCALAR_INT_MODE_P (innermode)
- && MEM_P (XEXP (op, 0))
- && CONST_INT_P (XEXP (op, 1))
- && GET_MODE_SIZE (outermode) < GET_MODE_SIZE (GET_MODE (op))
- && (INTVAL (XEXP (op, 1)) % GET_MODE_BITSIZE (outermode)) == 0
- && INTVAL (XEXP (op, 1)) > 0
- && INTVAL (XEXP (op, 1)) < GET_MODE_BITSIZE (innermode)
- && ! mode_dependent_address_p (XEXP (XEXP (op, 0), 0),
- MEM_ADDR_SPACE (XEXP (op, 0)))
- && ! MEM_VOLATILE_P (XEXP (op, 0))
- && byte == subreg_lowpart_offset (outermode, innermode)
- && (GET_MODE_SIZE (outermode) >= UNITS_PER_WORD
- || WORDS_BIG_ENDIAN == BYTES_BIG_ENDIAN))
- {
- int shifted_bytes = INTVAL (XEXP (op, 1)) / BITS_PER_UNIT;
- return adjust_address_nv (XEXP (op, 0), outermode,
- (WORDS_BIG_ENDIAN
- ? byte - shifted_bytes
- : byte + shifted_bytes));
+ rtx tem = simplify_truncation (outermode, op, innermode);
+ if (tem)
+ return tem;
}
return NULL_RTX;
diff --git a/gcc/statistics.c b/gcc/statistics.c
index 55ec981f3..1b3eefbd2 100644
--- a/gcc/statistics.c
+++ b/gcc/statistics.c
@@ -255,7 +255,7 @@ void
statistics_init (void)
{
statistics_dump_file = dump_begin (statistics_dump_nr, NULL);
- statistics_dump_flags = get_dump_file_info (statistics_dump_nr)->flags;
+ statistics_dump_flags = get_dump_file_info (statistics_dump_nr)->pflags;
}
/* Lookup or add a statistics counter in the hashtable HASH with ID, VAL
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8b0c58df8..a1c4a3272 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,206 @@
+2012-10-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51422
+ * g++.dg/cpp0x/lambda/lambda-ice8.C: New.
+
+2012-10-07 Richard Sandiford <rdsandiford@googlemail.com>
+ Sandra Loosemore <sandra@codesourcery.com>
+
+ * gcc.target/mips/madd-9.c: Force code to be tuned for the 4kc
+ and test that the accumulator is initialized using MULT.
+ * gcc.target/mips/mips32-dsp-accinit-1.c: New test.
+ * gcc.target/mips/mips32-dsp-accinit-2.c: Likewise.
+
+2012-10-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52764
+ * g++.dg/cpp0x/stdint.C: New.
+
+2012-10-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54249
+ * g++.dg/cpp0x/stddef.C: New.
+
+2012-10-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54832
+ * gfortran.dg/typebound_operator_17.f90: New.
+
+2012-10-06 Jan Hubicka <jh@suse.cz>
+
+ PR lto/53831
+ PR lto/54776
+ * g++.dg/lto/v1-plugin-api-not-supported.C: New testcase.
+
+2012-10-06 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/lto/resolutions_0.c: New testcase.
+
+2012-10-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/45521
+ * gfortran.dg/generic_25.f90: New.
+ * gfortran.dg/generic_26.f90: New.
+ * gfortran.dg/generic_27.f90: New.
+
+2012-10-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54760
+ * gcc.target/sh/pr54760-1.c: New.
+
+2012-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ * g++.dg/torture/Wsizeof-pointer-memaccess1.C: New test.
+ * g++.dg/torture/Wsizeof-pointer-memaccess2.C: New test.
+ * g++.dg/warn/Wsign-compare-5.C: New test.
+ * g++.dg/warn/Wsizeof-pointer-memaccess-1.C: New test.
+ * g++.dg/warn/Wnull-conversion-1.C: For c++11 add dg-error.
+ * g++.dg/ext/builtin30.C: New test.
+ * g++.dg/ext/vla12.C: New test.
+ * gcc.dg/builtins-85.c: New test.
+
+ PR debug/54519
+ * gcc.dg/guality/pr54519-1.c: New test.
+ * gcc.dg/guality/pr54519-2.c: New test.
+ * gcc.dg/guality/pr54519-3.c: New test.
+ * gcc.dg/guality/pr54519-4.c: New test.
+ * gcc.dg/guality/pr54519-5.c: New test.
+ * gcc.dg/guality/pr54519-6.c: New test.
+
+2012-10-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/50893
+ * g++.dg/cpp0x/defaulted38.C: New.
+
+2012-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/33763
+ * c-c++-common/pr33763.c: New test.
+
+ PR tree-optimization/54810
+ * gcc.dg/tree-ssa/vrp85.c: New test.
+
+2012-10-04 David Edelsohn <dje.gcc@gmail.com>
+
+ * gcc.dg/ucnid-7.c: Skip on AIX.
+ * gcc.dg/ucnid-8.c: Same.
+ * gcc.dg/ucnid-10.c: Same.
+ * gcc.dg/ucnid-13.c: Same.
+ * gcc.dg/attr-alias-3.c: Same.
+ * gcc.dg/attr-alias-5.c: Same.
+ * gcc.dg/torture/pr51106-2.c: Same.
+ * gcc.dg/vmx/3b-13.c: Use valid splat index.
+
+2012-10-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52233
+ * g++.dg/cpp0x/alias-decl-23.C: New.
+
+2012-10-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53403
+ * g++.dg/template/friend53.C: New.
+
+2012-10-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * lib/gcc-dg.exp (cleanup-ada-spec): New procedure.
+ * lib/scanasm.exp (get_ada_spec_filename): Likewise.
+ (scan-ada-spec): Likewise.
+ (scan-ada-spec-not): Likewise.
+ * gcc.dg/dump-ada-spec-1.c: New test.
+ * g++.dg/other/dump-ada-spec-1.C: Likewise.
+
+2012-10-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/lto/20120723_0.c: Skip on SPARC 32-bit.
+
+2012-10-04 Florian Weimer <fweimer@redhat.com>
+
+ * c-c++-common/cpp/diagnostic-pragma-1.c: New testcase.
+
+2012-10-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54323
+ * g++.dg/cpp0x/pr54323.C: New.
+
+2012-10-04 Richard Guenther <rguenther@suse.de>
+
+ PR middle-end/54735
+ * g++.dg/torture/pr54735.C: New testcase.
+
+2012-10-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR rtl-optimization/54739
+ * gcc.dg/lower-subreg-1.c: Also skip on SPARC.
+
+2012-10-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/51244
+ * gcc.target/sh/pr51244-12.c: New.
+
+2012-10-03 Dehao Chen <dehao@google.com>
+
+ PR middle-end/54782
+ * gcc.dg/pr54782.c: New test.
+
+2012-10-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/54777
+ * g++.dg/cpp0x/constexpr-ref4.C: New test.
+
+2012-10-02 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/54778
+ * gfortran.dg/class_53.f90: New.
+
+2012-10-02 Alexandre Oliva <aoliva@redhat.com>
+
+ PR debug/54551
+ * gcc.dg/guality/pr54551.c: New.
+
+2012-10-02 Pat Haugen <pthaugen@us.ibm.com>
+
+ * gcc.target/powerpc/pr46728-1.c: Accept xssqrtdp.
+ * gcc.target/powerpc/pr46728-2.c: Likewise.
+
+2012-10-02 Sharad Singhai <singhai@google.com>
+
+ PR testsuite/54772
+ * gfortran.dg/vect/vect.exp: Change verbose vectorizor dump options
+ to fix test failures caused by r191883.
+ * gcc.dg/tree-ssa/gen-vect-11.c: Likewise.
+ * gcc.dg/tree-ssa/gen-vect-2.c: Likewise.
+ * gcc.dg/tree-ssa/gen-vect-32.c: Likewise.
+ * gcc.dg/tree-ssa/gen-vect-25.c: Likewise.
+ * gcc.dg/tree-ssa/gen-vect-11a.c: Likewise.
+ * gcc.dg/tree-ssa/gen-vect-26.c: Likewise.
+ * gcc.dg/tree-ssa/gen-vect-11b.c: Likewise.
+ * gcc.dg/tree-ssa/gen-vect-11c.c: Likewise.
+ * gcc.dg/tree-ssa/gen-vect-28.c: Likewise.
+
+2012-09-30 Sharad Singhai <singhai@google.com>
+
+ * testsuite/gcc.target/i386/vect-double-1.c: Fix test.
+
+2012-10-01 Andrew MacLeod <amacleod@redhat.com>
+
+ PR target/54087
+ * gcc.dg/pr54087.c: New testcase for atomic_sub -> atomic_add when
+ atomic_sub fails.
+
+2012-10-01 Uros Bizjak <ubizjak@gmail.com>
+
+ PR rtl-optimization/54457
+ * gcc.target/i386/pr54457.c: New test.
+
+2012-10-01 Ulrich Weigand <ulrich.weigand@linaro.org>
+
+ * gcc.dg/lower-subreg-1.c: Disable on arm*-*-* targets.
+
+2012-10-01 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.target/i386/vect-rebuild.c: New testcase.
+
2012-09-30 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/pad-10.c (foo2): Return x - z.
diff --git a/gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c b/gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c
new file mode 100644
index 000000000..9867c94a8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/diagnostic-pragma-1.c
@@ -0,0 +1,11 @@
+// { dg-do compile }
+
+#pragma GCC warning "warn-a" // { dg-warning warn-a }
+#pragma GCC error "err-b" // { dg-error err-b }
+
+#define CONST1 _Pragma("GCC warning \"warn-c\"") 1
+#define CONST2 _Pragma("GCC error \"err-d\"") 2
+
+char a[CONST1]; // { dg-warning warn-c }
+char b[CONST2]; // { dg-error err-d }
+
diff --git a/gcc/testsuite/c-c++-common/pr33763.c b/gcc/testsuite/c-c++-common/pr33763.c
new file mode 100644
index 000000000..dbdfa77fc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr33763.c
@@ -0,0 +1,60 @@
+/* PR tree-optimization/33763 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef struct
+{
+ void *a;
+ void *b;
+} T;
+extern void *foo (const char *, const char *);
+extern void *bar (void *, const char *, T);
+extern int baz (const char *, int);
+
+extern inline __attribute__ ((always_inline, gnu_inline)) int
+baz (const char *x, int y)
+{
+ return 2;
+}
+
+int
+baz (const char *x, int y)
+{
+ return 1;
+}
+
+int xa, xb;
+
+static void *
+inl (const char *x, const char *y)
+{
+ T t = { &xa, &xb };
+ int *f = (int *) __builtin_malloc (sizeof (int));
+ const char *z;
+ int o = 0;
+ void *r = 0;
+
+ for (z = y; *z; z++)
+ {
+ if (*z == 'r')
+ o |= 1;
+ if (*z == 'w')
+ o |= 2;
+ }
+ if (o == 1)
+ *f = baz (x, 0);
+ if (o == 2)
+ *f = baz (x, 1);
+ if (o == 3)
+ *f = baz (x, 2);
+
+ if (o && *f > 0)
+ r = bar (f, "w", t);
+ return r;
+}
+
+void *
+foo (const char *x, const char *y)
+{
+ return inl (x, y);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-23.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-23.C
new file mode 100644
index 000000000..0e4ba45aa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-23.C
@@ -0,0 +1,17 @@
+// PR c++/52233
+// { dg-do compile { target c++11 } }
+
+template <typename t>
+struct foo
+{
+ template <template <typename...> class... xs>
+ using type = int;
+};
+
+template <typename t, template <typename...> class... xs>
+struct bar
+{
+ using type = typename foo<t>::template type<xs...>;
+};
+
+bar<int, foo> x;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ref4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref4.C
new file mode 100644
index 000000000..6ae355a27
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ref4.C
@@ -0,0 +1,18 @@
+// PR c++/54777
+// { dg-options -std=c++0x }
+
+struct S
+{
+ int s[1];
+ constexpr const int &foo (unsigned i) { return (i < 1 ? 0 : throw 1), s[i]; }
+ constexpr const int &bar (unsigned i) { return i < 1 ? s[i] : (throw 0, s[i]); }
+};
+
+int
+main ()
+{
+ constexpr S a {};
+ constexpr int i = a.foo (0);
+ constexpr int j = a.bar (0);
+ static_assert (i == j, "Ouch");
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted38.C b/gcc/testsuite/g++.dg/cpp0x/defaulted38.C
new file mode 100644
index 000000000..39424f641
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted38.C
@@ -0,0 +1,14 @@
+// PR c++/50893
+// { dg-do compile { target c++11 } }
+
+class Base
+{
+ public:
+ virtual ~Base() = default;
+};
+
+class Derived : public Base
+{
+ public:
+ virtual ~Derived() = default;
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice8.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice8.C
new file mode 100644
index 000000000..00078d53b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice8.C
@@ -0,0 +1,10 @@
+// PR c++/51422
+// { dg-do compile { target c++11 } }
+
+template<typename> struct A {};
+
+void foo()
+{
+ [i] { A<decltype(i)>(); }; // { dg-error "not declared|invalid" }
+ [i] { A<decltype(i)>(); }; // { dg-error "invalid" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr54323.C b/gcc/testsuite/g++.dg/cpp0x/pr54323.C
new file mode 100644
index 000000000..71b6c7192
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr54323.C
@@ -0,0 +1,37 @@
+// PR c++/54323
+// { dg-do compile { target c++11 } }
+
+template<bool, typename T = void>
+struct enable_if { };
+
+template<typename T>
+struct enable_if<true, T>
+{ typedef T type; };
+
+template<template<typename> class CRTP, typename T>
+class Base
+{
+public:
+ template<template<typename> class CRTP0, typename T0, class>
+ friend int func(const Base<CRTP0, T0>& rhs);
+
+protected:
+ int n;
+};
+
+template<template<typename> class CRTP0, typename T0,
+ class = typename enable_if<true>::type>
+int func(const Base<CRTP0, T0>& rhs)
+{
+ return rhs.n;
+}
+
+template<typename T>
+class Derived : public Base<Derived, T> {};
+
+int main()
+{
+ Derived<int> x;
+ func(x);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/stddef.C b/gcc/testsuite/g++.dg/cpp0x/stddef.C
new file mode 100644
index 000000000..dad9200cc
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/stddef.C
@@ -0,0 +1,6 @@
+// PR c++/54249
+// { dg-do compile { target c++11 } }
+
+#include <stddef.h>
+
+::nullptr_t n;
diff --git a/gcc/testsuite/g++.dg/cpp0x/stdint.C b/gcc/testsuite/g++.dg/cpp0x/stdint.C
new file mode 100644
index 000000000..434d45824
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/stdint.C
@@ -0,0 +1,135 @@
+// PR c++/52764
+// { dg-require-effective-target stdint_types }
+// { dg-do compile { target c++11 } }
+
+#include <stdint.h>
+
+#ifdef __INT8_TYPE__
+# if (!defined INT8_MAX \
+ || !defined INT8_MIN)
+# error
+# endif
+#endif
+#ifdef __UINT8_TYPE__
+# if !defined UINT8_MAX
+# error
+# endif
+#endif
+#ifdef __INT16_TYPE__
+# if (!defined INT16_MAX \
+ || !defined INT16_MIN)
+# error
+# endif
+#endif
+#ifdef __UINT16_TYPE__
+# if !defined UINT16_MAX
+# error
+# endif
+#endif
+#ifdef __INT32_TYPE__
+# if (!defined INT32_MAX \
+ || !defined INT32_MIN)
+# error
+# endif
+#endif
+#ifdef __UINT32_TYPE__
+# if !defined UINT32_MAX
+# error
+# endif
+#endif
+#ifdef __INT64_TYPE__
+# if (!defined INT64_MAX \
+ || !defined INT64_MIN)
+# error
+# endif
+#endif
+#ifdef __UINT64_TYPE__
+# if !defined UINT64_MAX
+# error
+# endif
+#endif
+
+#if (!defined INT_LEAST8_MAX \
+ || !defined INT_LEAST8_MIN \
+ || !defined UINT_LEAST8_MAX \
+ || !defined INT_LEAST16_MAX \
+ || !defined INT_LEAST16_MIN \
+ || !defined UINT_LEAST16_MAX \
+ || !defined INT_LEAST32_MAX \
+ || !defined INT_LEAST32_MIN \
+ || !defined UINT_LEAST32_MAX \
+ || !defined INT_LEAST64_MAX \
+ || !defined INT_LEAST64_MIN \
+ || !defined UINT_LEAST64_MAX)
+#error
+#endif
+
+#if (!defined INT_FAST8_MAX \
+ || !defined INT_FAST8_MIN \
+ || !defined UINT_FAST8_MAX \
+ || !defined INT_FAST16_MAX \
+ || !defined INT_FAST16_MIN \
+ || !defined UINT_FAST16_MAX \
+ || !defined INT_FAST32_MAX \
+ || !defined INT_FAST32_MIN \
+ || !defined UINT_FAST32_MAX \
+ || !defined INT_FAST64_MAX \
+ || !defined INT_FAST64_MIN \
+ || !defined UINT_FAST64_MAX)
+#error
+#endif
+
+#ifdef __INTPTR_TYPE__
+# if (!defined INTPTR_MAX \
+ || !defined INTPTR_MIN)
+# error
+# endif
+#endif
+#ifdef __UINTPTR_TYPE__
+# if !defined UINTPTR_MAX
+# error
+# endif
+#endif
+
+#if (!defined INTMAX_MAX \
+ || !defined INTMAX_MIN \
+ || !defined UINTMAX_MAX)
+#error
+#endif
+
+#if (!defined PTRDIFF_MAX \
+ || !defined PTRDIFF_MIN)
+#error
+#endif
+
+#if (!defined SIG_ATOMIC_MAX \
+ || !defined SIG_ATOMIC_MIN)
+#error
+#endif
+
+#if !defined SIZE_MAX
+#error
+#endif
+
+#if (!defined WCHAR_MAX \
+ || !defined WCHAR_MIN)
+#error
+#endif
+
+#if (!defined WINT_MAX \
+ || !defined WINT_MIN)
+#error
+#endif
+
+#if (!defined INT8_C \
+ || !defined INT16_C \
+ || !defined INT32_C \
+ || !defined INT64_C \
+ || !defined UINT8_C \
+ || !defined UINT16_C \
+ || !defined UINT32_C \
+ || !defined UINT64_C \
+ || !defined INTMAX_C \
+ || !defined UINTMAX_C)
+#error
+#endif
diff --git a/gcc/testsuite/g++.dg/ext/builtin30.C b/gcc/testsuite/g++.dg/ext/builtin30.C
new file mode 100644
index 000000000..d0a75fb17
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/builtin30.C
@@ -0,0 +1,27 @@
+// { dg-do compile }
+// { dg-options "-O2" }
+
+typedef __SIZE_TYPE__ size_t;
+extern "C" {
+extern void __chk_fail (void);
+extern int snprintf (char *, size_t, const char *, ...);
+extern inline __attribute__((gnu_inline, always_inline)) int snprintf (char *a, size_t b, const char *fmt, ...)
+{
+ if (__builtin_object_size (a, 0) != -1UL && __builtin_object_size (a, 0) < b)
+ __chk_fail ();
+ return __builtin_snprintf (a, b, fmt, __builtin_va_arg_pack ());
+}
+extern int snprintf (char *, size_t, const char *, ...) __asm ("mysnprintf");
+}
+
+char buf[10];
+
+int
+main (void)
+{
+ snprintf (buf, 10, "%d%d\n", 10, 10);
+ return 0;
+}
+
+// { dg-final { scan-assembler "mysnprintf" } }
+// { dg-final { scan-assembler-not "__chk_fail" } }
diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C b/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
index 4300d1ab1..b8133909a 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/pragma-override1.C
@@ -1,7 +1,7 @@
/* Test that #pragma GCC visibility does not override class member specific settings. */
/* { dg-do compile } */
/* { dg-require-visibility "internal" } */
-/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } } } } */
+/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } { ! *-*-darwin* } } } }*/
/* { dg-final { scan-assembler "\\.(internal|hidden).*Foo.methodEv" { target *-*-solaris2* } } } */
#pragma GCC visibility push(hidden)
diff --git a/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C b/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
index f566cd2f4..3ceaf4a25 100644
--- a/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
+++ b/gcc/testsuite/g++.dg/ext/visibility/pragma-override2.C
@@ -1,7 +1,7 @@
/* Test that #pragma GCC visibility does not override class member specific settings. */
/* { dg-do compile } */
/* { dg-require-visibility "internal" } */
-/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } } } } */
+/* { dg-final { scan-assembler "\\.internal.*Foo.methodEv" { target { ! *-*-solaris2* } { ! *-*-darwin* } } } } */
/* { dg-final { scan-assembler "\\.(internal|hidden).*Foo.methodEv" { target *-*-solaris2* } } } */
#pragma GCC visibility push(hidden)
diff --git a/gcc/testsuite/g++.dg/ext/vla12.C b/gcc/testsuite/g++.dg/ext/vla12.C
new file mode 100644
index 000000000..bca836507
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/vla12.C
@@ -0,0 +1,28 @@
+// VLA sizeof test
+// { dg-do compile }
+// { dg-options "" }
+
+int
+f1 (int i)
+{
+ char a[sizeof (i) + 6 + i];
+ char b[sizeof (a) + 1];
+ return sizeof (b);
+}
+
+int
+f2 (int i)
+{
+ char a[sizeof (i) + 6 + i];
+ char b[sizeof (a)];
+ return sizeof (b);
+}
+
+int
+f3 (int i)
+{
+ char a[sizeof (i) + 6 + i];
+ char b[sizeof (i) + i];
+ char c[sizeof (a) + sizeof (b) + 7];
+ return sizeof (c);
+}
diff --git a/gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C b/gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C
new file mode 100644
index 000000000..f79dfae5c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lto/v1-plugin-api-not-supported_0.C
@@ -0,0 +1,54 @@
+// { dg-lto-do run }
+// { dg-require-linker-plugin "" }
+// { dg-lto-options {{-O2 -fuse-linker-plugin -fno-early-inlining}}
+
+extern "C" void abort (void);
+extern "C" void linker_error ();
+
+class A
+{
+public:
+ int data;
+ virtual int foo (int i)
+ {
+ return i + 1;
+ }
+};
+
+class B : public A
+{
+public:
+ virtual int foo (int i)
+ {
+ return i + 2;
+ }
+};
+
+class C : public A
+{
+public:
+ virtual int foo (int i)
+ {
+ linker_error ();
+ return i + 3;
+ }
+};
+
+
+static int middleman (class A *obj, int i)
+{
+ return obj->foo (i);
+}
+
+int __attribute__ ((noinline,noclone)) get_input(void)
+{
+ return 1;
+}
+
+int main (int argc, char *argv[])
+{
+ class B b;
+ if (middleman (&b, get_input ()) != 3)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/other/dump-ada-spec-1.C b/gcc/testsuite/g++.dg/other/dump-ada-spec-1.C
new file mode 100644
index 000000000..eb249e798
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/dump-ada-spec-1.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-ada-spec" } */
+
+struct S
+{
+ int i;
+};
+
+/* { dg-final { scan-ada-spec "type S is record" } } */
+/* { dg-final { cleanup-ada-spec } } */
diff --git a/gcc/testsuite/g++.dg/template/friend53.C b/gcc/testsuite/g++.dg/template/friend53.C
new file mode 100644
index 000000000..6cbbb2b09
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend53.C
@@ -0,0 +1,23 @@
+// PR c++/53403
+
+template <typename T>
+class Foo
+{
+ typedef void type;
+ template <typename U> friend void f();
+public:
+ Foo() {}
+};
+
+template class Foo<void>;
+
+template <typename T>
+void f()
+{
+ typedef Foo<void>::type type;
+}
+
+int main()
+{
+ f<void>();
+}
diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
new file mode 100644
index 000000000..c57096cc0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess1.C
@@ -0,0 +1,702 @@
+// Test -Wsizeof-pointer-memaccess warnings.
+// { dg-do compile }
+// { dg-options "-Wall" }
+// Test just twice, once with -O0 non-fortified, once with -O2 fortified.
+// { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O2" } }
+// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
+
+extern "C" {
+
+typedef __SIZE_TYPE__ size_t;
+extern void *memset (void *, int, size_t);
+extern void *memcpy (void *__restrict, const void *__restrict, size_t);
+extern void *memmove (void *__restrict, const void *__restrict, size_t);
+extern int memcmp (const void *, const void *, size_t);
+extern char *strncpy (char *__restrict, const char *__restrict, size_t);
+extern char *strncat (char *__restrict, const char *__restrict, size_t);
+extern char *strndup (const char *, size_t);
+extern int strncmp (const char *, const char *, size_t);
+extern int strncasecmp (const char *, const char *, size_t);
+
+#ifdef __OPTIMIZE__
+# define bos(ptr) __builtin_object_size (ptr, 1)
+# define bos0(ptr) __builtin_object_size (ptr, 0)
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline void *
+memset (void *dest, int c, size_t len)
+{
+ return __builtin___memset_chk (dest, c, len, bos0 (dest));
+}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline void *
+memcpy (void *__restrict dest, const void *__restrict src, size_t len)
+{
+ return __builtin___memcpy_chk (dest, src, len, bos0 (dest));
+}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline void *
+memmove (void *dest, const void *src, size_t len)
+{
+ return __builtin___memmove_chk (dest, src, len, bos0 (dest));
+}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+strncpy (char *__restrict dest, const char *__restrict src, size_t len)
+{
+ return __builtin___strncpy_chk (dest, src, len, bos (dest));
+}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+strncat (char *dest, const char *src, size_t len)
+{
+ return __builtin___strncat_chk (dest, src, len, bos (dest));
+}
+#endif
+
+}
+
+struct A { short a, b; int c, d; long e, f; };
+typedef struct A TA;
+typedef struct A *PA;
+typedef TA *PTA;
+struct B {};
+typedef struct B TB;
+typedef struct B *PB;
+typedef TB *PTB;
+typedef int X[3][3][3];
+
+int
+f1 (void *x, int z)
+{
+ struct A a, *pa1 = &a;
+ TA *pa2 = &a;
+ PA pa3 = &a;
+ PTA pa4 = &a;
+ memset (&a, 0, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memset (pa1, 0, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pa2, 0, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pa3, 0, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pa4, 0, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pa1, 0, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pa2, 0, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pa3, 0, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pa4, 0, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memcpy (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memcpy (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pa1, x, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pa4, x, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memcpy (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memcpy (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pa1, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pa4, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ memmove (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memmove (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pa1, x, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pa4, x, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memmove (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memmove (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pa1, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ // These are correct, no warning.
+ memset (&a, 0, sizeof a);
+ memset (&a, 0, sizeof (a));
+ memset (&a, 0, sizeof (struct A));
+ memset (&a, 0, sizeof (const struct A));
+ memset (&a, 0, sizeof (volatile struct A));
+ memset (&a, 0, sizeof (volatile const struct A));
+ memset (&a, 0, sizeof (TA));
+ memset (&a, 0, sizeof (__typeof (*&a)));
+ memset (pa1, 0, sizeof (*pa1));
+ memset (pa2, 0, sizeof (*pa3));
+ memset (pa3, 0, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memset ((void *) &a, 0, sizeof (&a));
+ memset ((char *) &a, 0, sizeof (&a));
+ memset (&a, 0, sizeof (&a) + 0);
+ memset (&a, 0, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ memcpy (&a, x, sizeof a);
+ memcpy (&a, x, sizeof (a));
+ memcpy (&a, x, sizeof (struct A));
+ memcpy (&a, x, sizeof (const struct A));
+ memcpy (&a, x, sizeof (volatile struct A));
+ memcpy (&a, x, sizeof (volatile const struct A));
+ memcpy (&a, x, sizeof (TA));
+ memcpy (&a, x, sizeof (__typeof (*&a)));
+ memcpy (pa1, x, sizeof (*pa1));
+ memcpy (pa2, x, sizeof (*pa3));
+ memcpy (pa3, x, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy ((void *) &a, x, sizeof (&a));
+ memcpy ((char *) &a, x, sizeof (&a));
+ memcpy (&a, x, sizeof (&a) + 0);
+ memcpy (&a, x, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ memcpy (x, &a, sizeof a);
+ memcpy (x, &a, sizeof (a));
+ memcpy (x, &a, sizeof (struct A));
+ memcpy (x, &a, sizeof (const struct A));
+ memcpy (x, &a, sizeof (volatile struct A));
+ memcpy (x, &a, sizeof (volatile const struct A));
+ memcpy (x, &a, sizeof (TA));
+ memcpy (x, &a, sizeof (__typeof (*&a)));
+ memcpy (x, pa1, sizeof (*pa1));
+ memcpy (x, pa2, sizeof (*pa3));
+ memcpy (x, pa3, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy (x, (void *) &a, sizeof (&a));
+ memcpy (x, (char *) &a, sizeof (&a));
+ memcpy (x, &a, sizeof (&a) + 0);
+ memcpy (x, &a, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ memmove (&a, x, sizeof a);
+ memmove (&a, x, sizeof (a));
+ memmove (&a, x, sizeof (struct A));
+ memmove (&a, x, sizeof (const struct A));
+ memmove (&a, x, sizeof (volatile struct A));
+ memmove (&a, x, sizeof (volatile const struct A));
+ memmove (&a, x, sizeof (TA));
+ memmove (&a, x, sizeof (__typeof (*&a)));
+ memmove (pa1, x, sizeof (*pa1));
+ memmove (pa2, x, sizeof (*pa3));
+ memmove (pa3, x, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memmove ((void *) &a, x, sizeof (&a));
+ memmove ((char *) &a, x, sizeof (&a));
+ memmove (&a, x, sizeof (&a) + 0);
+ memmove (&a, x, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ memmove (x, &a, sizeof a);
+ memmove (x, &a, sizeof (a));
+ memmove (x, &a, sizeof (struct A));
+ memmove (x, &a, sizeof (const struct A));
+ memmove (x, &a, sizeof (volatile struct A));
+ memmove (x, &a, sizeof (volatile const struct A));
+ memmove (x, &a, sizeof (TA));
+ memmove (x, &a, sizeof (__typeof (*&a)));
+ memmove (x, pa1, sizeof (*pa1));
+ memmove (x, pa2, sizeof (*pa3));
+ memmove (x, pa3, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memmove (x, (void *) &a, sizeof (&a));
+ memmove (x, (char *) &a, sizeof (&a));
+ memmove (x, &a, sizeof (&a) + 0);
+ memmove (x, &a, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ z += memcmp (&a, x, sizeof a);
+ z += memcmp (&a, x, sizeof (a));
+ z += memcmp (&a, x, sizeof (struct A));
+ z += memcmp (&a, x, sizeof (const struct A));
+ z += memcmp (&a, x, sizeof (volatile struct A));
+ z += memcmp (&a, x, sizeof (volatile const struct A));
+ z += memcmp (&a, x, sizeof (TA));
+ z += memcmp (&a, x, sizeof (__typeof (*&a)));
+ z += memcmp (pa1, x, sizeof (*pa1));
+ z += memcmp (pa2, x, sizeof (*pa3));
+ z += memcmp (pa3, x, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp ((void *) &a, x, sizeof (&a));
+ z += memcmp ((char *) &a, x, sizeof (&a));
+ z += memcmp (&a, x, sizeof (&a) + 0);
+ z += memcmp (&a, x, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ z += memcmp (x, &a, sizeof a);
+ z += memcmp (x, &a, sizeof (a));
+ z += memcmp (x, &a, sizeof (struct A));
+ z += memcmp (x, &a, sizeof (const struct A));
+ z += memcmp (x, &a, sizeof (volatile struct A));
+ z += memcmp (x, &a, sizeof (volatile const struct A));
+ z += memcmp (x, &a, sizeof (TA));
+ z += memcmp (x, &a, sizeof (__typeof (*&a)));
+ z += memcmp (x, pa1, sizeof (*pa1));
+ z += memcmp (x, pa2, sizeof (*pa3));
+ z += memcmp (x, pa3, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp (x, (void *) &a, sizeof (&a));
+ z += memcmp (x, (char *) &a, sizeof (&a));
+ z += memcmp (x, &a, sizeof (&a) + 0);
+ z += memcmp (x, &a, 0 + sizeof (&a));
+
+ return z;
+}
+
+int
+f2 (void *x, int z)
+{
+ struct B b, *pb1 = &b;
+ TB *pb2 = &b;
+ PB pb3 = &b;
+ PTB pb4 = &b;
+ memset (&b, 0, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memset (pb1, 0, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pb2, 0, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pb3, 0, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pb4, 0, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pb1, 0, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pb2, 0, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pb3, 0, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pb4, 0, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memcpy (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memcpy (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pb1, x, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pb4, x, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memcpy (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memcpy (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pb1, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pb4, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ memmove (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memmove (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pb1, x, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pb4, x, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memmove (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memmove (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pb1, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ // These are correct, no warning.
+ memset (&b, 0, sizeof b);
+ memset (&b, 0, sizeof (b));
+ memset (&b, 0, sizeof (struct B));
+ memset (&b, 0, sizeof (const struct B));
+ memset (&b, 0, sizeof (volatile struct B));
+ memset (&b, 0, sizeof (volatile const struct B));
+ memset (&b, 0, sizeof (TB));
+ memset (&b, 0, sizeof (__typeof (*&b)));
+ memset (pb1, 0, sizeof (*pb1));
+ memset (pb2, 0, sizeof (*pb3));
+ memset (pb3, 0, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memset ((void *) &b, 0, sizeof (&b));
+ memset ((char *) &b, 0, sizeof (&b));
+ memset (&b, 0, sizeof (&b) + 0);
+ memset (&b, 0, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ memcpy (&b, x, sizeof b);
+ memcpy (&b, x, sizeof (b));
+ memcpy (&b, x, sizeof (struct B));
+ memcpy (&b, x, sizeof (const struct B));
+ memcpy (&b, x, sizeof (volatile struct B));
+ memcpy (&b, x, sizeof (volatile const struct B));
+ memcpy (&b, x, sizeof (TB));
+ memcpy (&b, x, sizeof (__typeof (*&b)));
+ memcpy (pb1, x, sizeof (*pb1));
+ memcpy (pb2, x, sizeof (*pb3));
+ memcpy (pb3, x, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy ((void *) &b, x, sizeof (&b));
+ memcpy ((char *) &b, x, sizeof (&b));
+ memcpy (&b, x, sizeof (&b) + 0);
+ memcpy (&b, x, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ memcpy (x, &b, sizeof b);
+ memcpy (x, &b, sizeof (b));
+ memcpy (x, &b, sizeof (struct B));
+ memcpy (x, &b, sizeof (const struct B));
+ memcpy (x, &b, sizeof (volatile struct B));
+ memcpy (x, &b, sizeof (volatile const struct B));
+ memcpy (x, &b, sizeof (TB));
+ memcpy (x, &b, sizeof (__typeof (*&b)));
+ memcpy (x, pb1, sizeof (*pb1));
+ memcpy (x, pb2, sizeof (*pb3));
+ memcpy (x, pb3, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy (x, (void *) &b, sizeof (&b));
+ memcpy (x, (char *) &b, sizeof (&b));
+ memcpy (x, &b, sizeof (&b) + 0);
+ memcpy (x, &b, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ memmove (&b, x, sizeof b);
+ memmove (&b, x, sizeof (b));
+ memmove (&b, x, sizeof (struct B));
+ memmove (&b, x, sizeof (const struct B));
+ memmove (&b, x, sizeof (volatile struct B));
+ memmove (&b, x, sizeof (volatile const struct B));
+ memmove (&b, x, sizeof (TB));
+ memmove (&b, x, sizeof (__typeof (*&b)));
+ memmove (pb1, x, sizeof (*pb1));
+ memmove (pb2, x, sizeof (*pb3));
+ memmove (pb3, x, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memmove ((void *) &b, x, sizeof (&b));
+ memmove ((char *) &b, x, sizeof (&b));
+ memmove (&b, x, sizeof (&b) + 0);
+ memmove (&b, x, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ memmove (x, &b, sizeof b);
+ memmove (x, &b, sizeof (b));
+ memmove (x, &b, sizeof (struct B));
+ memmove (x, &b, sizeof (const struct B));
+ memmove (x, &b, sizeof (volatile struct B));
+ memmove (x, &b, sizeof (volatile const struct B));
+ memmove (x, &b, sizeof (TB));
+ memmove (x, &b, sizeof (__typeof (*&b)));
+ memmove (x, pb1, sizeof (*pb1));
+ memmove (x, pb2, sizeof (*pb3));
+ memmove (x, pb3, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memmove (x, (void *) &b, sizeof (&b));
+ memmove (x, (char *) &b, sizeof (&b));
+ memmove (x, &b, sizeof (&b) + 0);
+ memmove (x, &b, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ z += memcmp (&b, x, sizeof b);
+ z += memcmp (&b, x, sizeof (b));
+ z += memcmp (&b, x, sizeof (struct B));
+ z += memcmp (&b, x, sizeof (const struct B));
+ z += memcmp (&b, x, sizeof (volatile struct B));
+ z += memcmp (&b, x, sizeof (volatile const struct B));
+ z += memcmp (&b, x, sizeof (TB));
+ z += memcmp (&b, x, sizeof (__typeof (*&b)));
+ z += memcmp (pb1, x, sizeof (*pb1));
+ z += memcmp (pb2, x, sizeof (*pb3));
+ z += memcmp (pb3, x, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp ((void *) &b, x, sizeof (&b));
+ z += memcmp ((char *) &b, x, sizeof (&b));
+ z += memcmp (&b, x, sizeof (&b) + 0);
+ z += memcmp (&b, x, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ z += memcmp (x, &b, sizeof b);
+ z += memcmp (x, &b, sizeof (b));
+ z += memcmp (x, &b, sizeof (struct B));
+ z += memcmp (x, &b, sizeof (const struct B));
+ z += memcmp (x, &b, sizeof (volatile struct B));
+ z += memcmp (x, &b, sizeof (volatile const struct B));
+ z += memcmp (x, &b, sizeof (TB));
+ z += memcmp (x, &b, sizeof (__typeof (*&b)));
+ z += memcmp (x, pb1, sizeof (*pb1));
+ z += memcmp (x, pb2, sizeof (*pb3));
+ z += memcmp (x, pb3, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp (x, (void *) &b, sizeof (&b));
+ z += memcmp (x, (char *) &b, sizeof (&b));
+ z += memcmp (x, &b, sizeof (&b) + 0);
+ z += memcmp (x, &b, 0 + sizeof (&b));
+
+ return z;
+}
+
+int
+f3 (void *x, char *y, int z, X w)
+{
+ unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
+ char buf1[7];
+ signed char buf2[z + 32];
+ long buf3[17];
+ int *buf4[9];
+ signed char *y2 = buf2;
+ char c;
+ char *y3;
+ memset (y, 0, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memset (y1, 0, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memset (y2, 0, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memset (&c, 0, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memset (w, 0, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+
+ memcpy (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memcpy (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memcpy (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memcpy (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memcpy (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+
+ memcpy (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memcpy (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memcpy (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memcpy (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memcpy (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+
+ memmove (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memmove (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memmove (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memmove (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memmove (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+
+ memmove (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memmove (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memmove (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+
+ z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+
+ z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+
+ // These are correct, no warning.
+ memset (y, 0, sizeof (*y));
+ memset (y1, 0, sizeof (*y2));
+ memset (buf1, 0, sizeof buf1);
+ memset (buf3, 0, sizeof (buf3));
+ memset (&buf3[0], 0, sizeof (buf3));
+ memset (&buf4[0], 0, sizeof (buf4));
+ memset (w, 0, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memset ((void *) y, 0, sizeof (y));
+ memset ((char *) y1, 0, sizeof (y2));
+ memset (y, 0, sizeof (y) + 0);
+ memset (y1, 0, 0 + sizeof (y2));
+ memset ((void *) &c, 0, sizeof (&c));
+ memset ((signed char *) &c, 0, sizeof (&c));
+ memset (&c, 0, sizeof (&c) + 0);
+ memset (&c, 0, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ memcpy (y, x, sizeof (*y));
+ memcpy (y1, x, sizeof (*y2));
+ memcpy (buf1, x, sizeof buf1);
+ memcpy (buf3, x, sizeof (buf3));
+ memcpy (&buf3[0], x, sizeof (buf3));
+ memcpy (&buf4[0], x, sizeof (buf4));
+ memcpy (&y3, y, sizeof (y3));
+ memcpy ((char *) &y3, y, sizeof (y3));
+ memcpy (w, x, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy ((void *) y, x, sizeof (y));
+ memcpy ((char *) y1, x, sizeof (y2));
+ memcpy (y, x, sizeof (y) + 0);
+ memcpy (y1, x, 0 + sizeof (y2));
+ memcpy ((void *) &c, x, sizeof (&c));
+ memcpy ((signed char *) &c, x, sizeof (&c));
+ memcpy (&c, x, sizeof (&c) + 0);
+ memcpy (&c, x, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ memcpy (x, y, sizeof (*y));
+ memcpy (x, y1, sizeof (*y2));
+ memcpy (x, buf1, sizeof buf1);
+ memcpy (x, buf3, sizeof (buf3));
+ memcpy (x, &buf3[0], sizeof (buf3));
+ memcpy (x, &buf4[0], sizeof (buf4));
+ memcpy (y, &y3, sizeof (y3));
+ memcpy (y, (char *) &y3, sizeof (y3));
+ memcpy (x, w, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy (x, (void *) y, sizeof (y));
+ memcpy (x, (char *) y1, sizeof (y2));
+ memcpy (x, y, sizeof (y) + 0);
+ memcpy (x, y1, 0 + sizeof (y2));
+ memcpy (x, (void *) &c, sizeof (&c));
+ memcpy (x, (signed char *) &c, sizeof (&c));
+ memcpy (x, &c, sizeof (&c) + 0);
+ memcpy (x, &c, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ memmove (y, x, sizeof (*y));
+ memmove (y1, x, sizeof (*y2));
+ memmove (buf1, x, sizeof buf1);
+ memmove (buf3, x, sizeof (buf3));
+ memmove (&buf3[0], x, sizeof (buf3));
+ memmove (&buf4[0], x, sizeof (buf4));
+ memmove (&y3, y, sizeof (y3));
+ memmove ((char *) &y3, y, sizeof (y3));
+ memmove (w, x, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memmove ((void *) y, x, sizeof (y));
+ memmove ((char *) y1, x, sizeof (y2));
+ memmove (y, x, sizeof (y) + 0);
+ memmove (y1, x, 0 + sizeof (y2));
+ memmove ((void *) &c, x, sizeof (&c));
+ memmove ((signed char *) &c, x, sizeof (&c));
+ memmove (&c, x, sizeof (&c) + 0);
+ memmove (&c, x, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ memmove (x, y, sizeof (*y));
+ memmove (x, y1, sizeof (*y2));
+ memmove (x, buf1, sizeof buf1);
+ memmove (x, buf3, sizeof (buf3));
+ memmove (x, &buf3[0], sizeof (buf3));
+ memmove (x, &buf4[0], sizeof (buf4));
+ memmove (y, &y3, sizeof (y3));
+ memmove (y, (char *) &y3, sizeof (y3));
+ memmove (x, w, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memmove (x, (void *) y, sizeof (y));
+ memmove (x, (char *) y1, sizeof (y2));
+ memmove (x, y, sizeof (y) + 0);
+ memmove (x, y1, 0 + sizeof (y2));
+ memmove (x, (void *) &c, sizeof (&c));
+ memmove (x, (signed char *) &c, sizeof (&c));
+ memmove (x, &c, sizeof (&c) + 0);
+ memmove (x, &c, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ z += memcmp (y, x, sizeof (*y));
+ z += memcmp (y1, x, sizeof (*y2));
+ z += memcmp (buf1, x, sizeof buf1);
+ z += memcmp (buf3, x, sizeof (buf3));
+ z += memcmp (&buf3[0], x, sizeof (buf3));
+ z += memcmp (&buf4[0], x, sizeof (buf4));
+ z += memcmp (&y3, y, sizeof (y3));
+ z += memcmp ((char *) &y3, y, sizeof (y3));
+ z += memcmp (w, x, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp ((void *) y, x, sizeof (y));
+ z += memcmp ((char *) y1, x, sizeof (y2));
+ z += memcmp (y, x, sizeof (y) + 0);
+ z += memcmp (y1, x, 0 + sizeof (y2));
+ z += memcmp ((void *) &c, x, sizeof (&c));
+ z += memcmp ((signed char *) &c, x, sizeof (&c));
+ z += memcmp (&c, x, sizeof (&c) + 0);
+ z += memcmp (&c, x, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ z += memcmp (x, y, sizeof (*y));
+ z += memcmp (x, y1, sizeof (*y2));
+ z += memcmp (x, buf1, sizeof buf1);
+ z += memcmp (x, buf3, sizeof (buf3));
+ z += memcmp (x, &buf3[0], sizeof (buf3));
+ z += memcmp (x, &buf4[0], sizeof (buf4));
+ z += memcmp (y, &y3, sizeof (y3));
+ z += memcmp (y, (char *) &y3, sizeof (y3));
+ z += memcmp (x, w, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp (x, (void *) y, sizeof (y));
+ z += memcmp (x, (char *) y1, sizeof (y2));
+ z += memcmp (x, y, sizeof (y) + 0);
+ z += memcmp (x, y1, 0 + sizeof (y2));
+ z += memcmp (x, (void *) &c, sizeof (&c));
+ z += memcmp (x, (signed char *) &c, sizeof (&c));
+ z += memcmp (x, &c, sizeof (&c) + 0);
+ z += memcmp (x, &c, 0 + sizeof (&c));
+
+ return z;
+}
+
+int
+f4 (char *x, char **y, int z)
+{
+ const char *s1 = "foobarbaz";
+ const char *s2 = "abcde12345678";
+ strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+
+ // These are correct, no warning.
+ const char s3[] = "foobarbaz";
+ const char s4[] = "abcde12345678";
+ strncpy (x, s3, sizeof (s3));
+ strncat (x, s4, sizeof (s4));
+ y[1] = strndup (s3, sizeof (s3));
+ z += strncmp (s3, s4, sizeof (s3));
+ z += strncmp (s3, s4, sizeof (s4));
+ z += strncasecmp (s3, s4, sizeof (s3));
+ z += strncasecmp (s3, s4, sizeof (s4));
+
+ return z;
+}
+
+// { dg-prune-output "\[\n\r\]*will always overflow\[\n\r\]*" }
diff --git a/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
new file mode 100644
index 000000000..d5a29d8f5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/Wsizeof-pointer-memaccess2.C
@@ -0,0 +1,716 @@
+// Test -Wsizeof-pointer-memaccess warnings.
+// { dg-do compile }
+// { dg-options "-Wall" }
+// Test just twice, once with -O0 non-fortified, once with -O2 fortified.
+// { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O2" } }
+// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
+
+extern "C" {
+
+typedef __SIZE_TYPE__ size_t;
+extern void *memset (void *, int, size_t);
+extern void *memcpy (void *__restrict, const void *__restrict, size_t);
+extern void *memmove (void *__restrict, const void *__restrict, size_t);
+extern int memcmp (const void *, const void *, size_t);
+extern char *strncpy (char *__restrict, const char *__restrict, size_t);
+extern char *strncat (char *__restrict, const char *__restrict, size_t);
+extern char *strndup (const char *, size_t);
+extern int strncmp (const char *, const char *, size_t);
+extern int strncasecmp (const char *, const char *, size_t);
+
+#ifdef __OPTIMIZE__
+# define bos(ptr) __builtin_object_size (ptr, 1)
+# define bos0(ptr) __builtin_object_size (ptr, 0)
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline void *
+memset (void *dest, int c, size_t len)
+{
+ return __builtin___memset_chk (dest, c, len, bos0 (dest));
+}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline void *
+memcpy (void *__restrict dest, const void *__restrict src, size_t len)
+{
+ return __builtin___memcpy_chk (dest, src, len, bos0 (dest));
+}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline void *
+memmove (void *dest, const void *src, size_t len)
+{
+ return __builtin___memmove_chk (dest, src, len, bos0 (dest));
+}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+strncpy (char *__restrict dest, const char *__restrict src, size_t len)
+{
+ return __builtin___strncpy_chk (dest, src, len, bos (dest));
+}
+
+__attribute__((__always_inline__, __gnu_inline__, __artificial__))
+extern inline char *
+strncat (char *dest, const char *src, size_t len)
+{
+ return __builtin___strncat_chk (dest, src, len, bos (dest));
+}
+#endif
+
+}
+
+struct A { short a, b; int c, d; long e, f; };
+typedef struct A TA;
+typedef struct A *PA;
+typedef TA *PTA;
+struct B {};
+typedef struct B TB;
+typedef struct B *PB;
+typedef TB *PTB;
+typedef int X[3][3][3];
+
+template <int N>
+int
+f1 (void *x, int z)
+{
+ struct A a, *pa1 = &a;
+ TA *pa2 = &a;
+ PA pa3 = &a;
+ PTA pa4 = &a;
+ memset (&a, 0, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memset (pa1, 0, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pa2, 0, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pa3, 0, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pa4, 0, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pa1, 0, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pa2, 0, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pa3, 0, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pa4, 0, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memcpy (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memcpy (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pa1, x, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pa4, x, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memcpy (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memcpy (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pa1, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pa4, sizeof (__typeof (pa4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ memmove (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memmove (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pa1, x, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pa4, x, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memmove (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memmove (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pa1, sizeof (struct A *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pa4, sizeof (__typeof (pa4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (&a, x, sizeof (&a)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ z += memcmp (pa1, x, sizeof (pa1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pa2, x, sizeof pa2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pa3, x, sizeof (pa3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pa4, x, sizeof pa4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pa1, x, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa2, x, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pa3, x, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &a, sizeof (&a)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ z += memcmp (x, pa1, sizeof (pa1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pa2, sizeof pa2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pa3, sizeof (pa3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pa4, sizeof pa4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pa1, sizeof (struct A *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa2, sizeof (PTA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pa3, sizeof (PA)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ // These are correct, no warning.
+ memset (&a, 0, sizeof a);
+ memset (&a, 0, sizeof (a));
+ memset (&a, 0, sizeof (struct A));
+ memset (&a, 0, sizeof (const struct A));
+ memset (&a, 0, sizeof (volatile struct A));
+ memset (&a, 0, sizeof (volatile const struct A));
+ memset (&a, 0, sizeof (TA));
+ memset (&a, 0, sizeof (__typeof (*&a)));
+ memset (pa1, 0, sizeof (*pa1));
+ memset (pa2, 0, sizeof (*pa3));
+ memset (pa3, 0, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memset ((void *) &a, 0, sizeof (&a));
+ memset ((char *) &a, 0, sizeof (&a));
+ memset (&a, 0, sizeof (&a) + 0);
+ memset (&a, 0, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ memcpy (&a, x, sizeof a);
+ memcpy (&a, x, sizeof (a));
+ memcpy (&a, x, sizeof (struct A));
+ memcpy (&a, x, sizeof (const struct A));
+ memcpy (&a, x, sizeof (volatile struct A));
+ memcpy (&a, x, sizeof (volatile const struct A));
+ memcpy (&a, x, sizeof (TA));
+ memcpy (&a, x, sizeof (__typeof (*&a)));
+ memcpy (pa1, x, sizeof (*pa1));
+ memcpy (pa2, x, sizeof (*pa3));
+ memcpy (pa3, x, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy ((void *) &a, x, sizeof (&a));
+ memcpy ((char *) &a, x, sizeof (&a));
+ memcpy (&a, x, sizeof (&a) + 0);
+ memcpy (&a, x, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ memcpy (x, &a, sizeof a);
+ memcpy (x, &a, sizeof (a));
+ memcpy (x, &a, sizeof (struct A));
+ memcpy (x, &a, sizeof (const struct A));
+ memcpy (x, &a, sizeof (volatile struct A));
+ memcpy (x, &a, sizeof (volatile const struct A));
+ memcpy (x, &a, sizeof (TA));
+ memcpy (x, &a, sizeof (__typeof (*&a)));
+ memcpy (x, pa1, sizeof (*pa1));
+ memcpy (x, pa2, sizeof (*pa3));
+ memcpy (x, pa3, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy (x, (void *) &a, sizeof (&a));
+ memcpy (x, (char *) &a, sizeof (&a));
+ memcpy (x, &a, sizeof (&a) + 0);
+ memcpy (x, &a, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ memmove (&a, x, sizeof a);
+ memmove (&a, x, sizeof (a));
+ memmove (&a, x, sizeof (struct A));
+ memmove (&a, x, sizeof (const struct A));
+ memmove (&a, x, sizeof (volatile struct A));
+ memmove (&a, x, sizeof (volatile const struct A));
+ memmove (&a, x, sizeof (TA));
+ memmove (&a, x, sizeof (__typeof (*&a)));
+ memmove (pa1, x, sizeof (*pa1));
+ memmove (pa2, x, sizeof (*pa3));
+ memmove (pa3, x, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memmove ((void *) &a, x, sizeof (&a));
+ memmove ((char *) &a, x, sizeof (&a));
+ memmove (&a, x, sizeof (&a) + 0);
+ memmove (&a, x, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ memmove (x, &a, sizeof a);
+ memmove (x, &a, sizeof (a));
+ memmove (x, &a, sizeof (struct A));
+ memmove (x, &a, sizeof (const struct A));
+ memmove (x, &a, sizeof (volatile struct A));
+ memmove (x, &a, sizeof (volatile const struct A));
+ memmove (x, &a, sizeof (TA));
+ memmove (x, &a, sizeof (__typeof (*&a)));
+ memmove (x, pa1, sizeof (*pa1));
+ memmove (x, pa2, sizeof (*pa3));
+ memmove (x, pa3, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ memmove (x, (void *) &a, sizeof (&a));
+ memmove (x, (char *) &a, sizeof (&a));
+ memmove (x, &a, sizeof (&a) + 0);
+ memmove (x, &a, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ z += memcmp (&a, x, sizeof a);
+ z += memcmp (&a, x, sizeof (a));
+ z += memcmp (&a, x, sizeof (struct A));
+ z += memcmp (&a, x, sizeof (const struct A));
+ z += memcmp (&a, x, sizeof (volatile struct A));
+ z += memcmp (&a, x, sizeof (volatile const struct A));
+ z += memcmp (&a, x, sizeof (TA));
+ z += memcmp (&a, x, sizeof (__typeof (*&a)));
+ z += memcmp (pa1, x, sizeof (*pa1));
+ z += memcmp (pa2, x, sizeof (*pa3));
+ z += memcmp (pa3, x, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp ((void *) &a, x, sizeof (&a));
+ z += memcmp ((char *) &a, x, sizeof (&a));
+ z += memcmp (&a, x, sizeof (&a) + 0);
+ z += memcmp (&a, x, 0 + sizeof (&a));
+
+ // These are correct, no warning.
+ z += memcmp (x, &a, sizeof a);
+ z += memcmp (x, &a, sizeof (a));
+ z += memcmp (x, &a, sizeof (struct A));
+ z += memcmp (x, &a, sizeof (const struct A));
+ z += memcmp (x, &a, sizeof (volatile struct A));
+ z += memcmp (x, &a, sizeof (volatile const struct A));
+ z += memcmp (x, &a, sizeof (TA));
+ z += memcmp (x, &a, sizeof (__typeof (*&a)));
+ z += memcmp (x, pa1, sizeof (*pa1));
+ z += memcmp (x, pa2, sizeof (*pa3));
+ z += memcmp (x, pa3, sizeof (__typeof (*pa3)));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp (x, (void *) &a, sizeof (&a));
+ z += memcmp (x, (char *) &a, sizeof (&a));
+ z += memcmp (x, &a, sizeof (&a) + 0);
+ z += memcmp (x, &a, 0 + sizeof (&a));
+
+ return z;
+}
+
+template <int N>
+int
+f2 (void *x, int z)
+{
+ struct B b, *pb1 = &b;
+ TB *pb2 = &b;
+ PB pb3 = &b;
+ PTB pb4 = &b;
+ memset (&b, 0, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memset (pb1, 0, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pb2, 0, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pb3, 0, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pb4, 0, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memset (pb1, 0, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pb2, 0, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pb3, 0, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memset (pb4, 0, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memcpy (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memcpy (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memcpy (pb1, x, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memcpy (pb4, x, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memcpy (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memcpy (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memcpy (x, pb1, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memcpy (x, pb4, sizeof (__typeof (pb4))); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ memmove (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memmove (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ memmove (pb1, x, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ memmove (pb4, x, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ memmove (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memmove (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ memmove (x, pb1, sizeof (struct B *)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ memmove (x, pb4, sizeof (__typeof (pb4)));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (&b, x, sizeof (&b)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ z += memcmp (pb1, x, sizeof (pb1)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pb2, x, sizeof pb2); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pb3, x, sizeof (pb3)); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pb4, x, sizeof pb4); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+ z += memcmp (pb1, x, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb2, x, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (pb3, x, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the destination; expected \[^\n\r\]* or an explicit length" }
+
+ z += memcmp (x, &b, sizeof (&b)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ z += memcmp (x, pb1, sizeof (pb1)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pb2, sizeof pb2); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pb3, sizeof (pb3)); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pb4, sizeof pb4); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+ z += memcmp (x, pb1, sizeof (struct B *));// { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb2, sizeof (PTB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+ z += memcmp (x, pb3, sizeof (PB)); // { dg-warning "call is the same pointer type \[^\n\r\]* as the source; expected \[^\n\r\]* or an explicit length" }
+
+ // These are correct, no warning.
+ memset (&b, 0, sizeof b);
+ memset (&b, 0, sizeof (b));
+ memset (&b, 0, sizeof (struct B));
+ memset (&b, 0, sizeof (const struct B));
+ memset (&b, 0, sizeof (volatile struct B));
+ memset (&b, 0, sizeof (volatile const struct B));
+ memset (&b, 0, sizeof (TB));
+ memset (&b, 0, sizeof (__typeof (*&b)));
+ memset (pb1, 0, sizeof (*pb1));
+ memset (pb2, 0, sizeof (*pb3));
+ memset (pb3, 0, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memset ((void *) &b, 0, sizeof (&b));
+ memset ((char *) &b, 0, sizeof (&b));
+ memset (&b, 0, sizeof (&b) + 0);
+ memset (&b, 0, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ memcpy (&b, x, sizeof b);
+ memcpy (&b, x, sizeof (b));
+ memcpy (&b, x, sizeof (struct B));
+ memcpy (&b, x, sizeof (const struct B));
+ memcpy (&b, x, sizeof (volatile struct B));
+ memcpy (&b, x, sizeof (volatile const struct B));
+ memcpy (&b, x, sizeof (TB));
+ memcpy (&b, x, sizeof (__typeof (*&b)));
+ memcpy (pb1, x, sizeof (*pb1));
+ memcpy (pb2, x, sizeof (*pb3));
+ memcpy (pb3, x, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy ((void *) &b, x, sizeof (&b));
+ memcpy ((char *) &b, x, sizeof (&b));
+ memcpy (&b, x, sizeof (&b) + 0);
+ memcpy (&b, x, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ memcpy (x, &b, sizeof b);
+ memcpy (x, &b, sizeof (b));
+ memcpy (x, &b, sizeof (struct B));
+ memcpy (x, &b, sizeof (const struct B));
+ memcpy (x, &b, sizeof (volatile struct B));
+ memcpy (x, &b, sizeof (volatile const struct B));
+ memcpy (x, &b, sizeof (TB));
+ memcpy (x, &b, sizeof (__typeof (*&b)));
+ memcpy (x, pb1, sizeof (*pb1));
+ memcpy (x, pb2, sizeof (*pb3));
+ memcpy (x, pb3, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy (x, (void *) &b, sizeof (&b));
+ memcpy (x, (char *) &b, sizeof (&b));
+ memcpy (x, &b, sizeof (&b) + 0);
+ memcpy (x, &b, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ memmove (&b, x, sizeof b);
+ memmove (&b, x, sizeof (b));
+ memmove (&b, x, sizeof (struct B));
+ memmove (&b, x, sizeof (const struct B));
+ memmove (&b, x, sizeof (volatile struct B));
+ memmove (&b, x, sizeof (volatile const struct B));
+ memmove (&b, x, sizeof (TB));
+ memmove (&b, x, sizeof (__typeof (*&b)));
+ memmove (pb1, x, sizeof (*pb1));
+ memmove (pb2, x, sizeof (*pb3));
+ memmove (pb3, x, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memmove ((void *) &b, x, sizeof (&b));
+ memmove ((char *) &b, x, sizeof (&b));
+ memmove (&b, x, sizeof (&b) + 0);
+ memmove (&b, x, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ memmove (x, &b, sizeof b);
+ memmove (x, &b, sizeof (b));
+ memmove (x, &b, sizeof (struct B));
+ memmove (x, &b, sizeof (const struct B));
+ memmove (x, &b, sizeof (volatile struct B));
+ memmove (x, &b, sizeof (volatile const struct B));
+ memmove (x, &b, sizeof (TB));
+ memmove (x, &b, sizeof (__typeof (*&b)));
+ memmove (x, pb1, sizeof (*pb1));
+ memmove (x, pb2, sizeof (*pb3));
+ memmove (x, pb3, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ memmove (x, (void *) &b, sizeof (&b));
+ memmove (x, (char *) &b, sizeof (&b));
+ memmove (x, &b, sizeof (&b) + 0);
+ memmove (x, &b, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ z += memcmp (&b, x, sizeof b);
+ z += memcmp (&b, x, sizeof (b));
+ z += memcmp (&b, x, sizeof (struct B));
+ z += memcmp (&b, x, sizeof (const struct B));
+ z += memcmp (&b, x, sizeof (volatile struct B));
+ z += memcmp (&b, x, sizeof (volatile const struct B));
+ z += memcmp (&b, x, sizeof (TB));
+ z += memcmp (&b, x, sizeof (__typeof (*&b)));
+ z += memcmp (pb1, x, sizeof (*pb1));
+ z += memcmp (pb2, x, sizeof (*pb3));
+ z += memcmp (pb3, x, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp ((void *) &b, x, sizeof (&b));
+ z += memcmp ((char *) &b, x, sizeof (&b));
+ z += memcmp (&b, x, sizeof (&b) + 0);
+ z += memcmp (&b, x, 0 + sizeof (&b));
+
+ // These are correct, no warning.
+ z += memcmp (x, &b, sizeof b);
+ z += memcmp (x, &b, sizeof (b));
+ z += memcmp (x, &b, sizeof (struct B));
+ z += memcmp (x, &b, sizeof (const struct B));
+ z += memcmp (x, &b, sizeof (volatile struct B));
+ z += memcmp (x, &b, sizeof (volatile const struct B));
+ z += memcmp (x, &b, sizeof (TB));
+ z += memcmp (x, &b, sizeof (__typeof (*&b)));
+ z += memcmp (x, pb1, sizeof (*pb1));
+ z += memcmp (x, pb2, sizeof (*pb3));
+ z += memcmp (x, pb3, sizeof (__typeof (*pb3)));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp (x, (void *) &b, sizeof (&b));
+ z += memcmp (x, (char *) &b, sizeof (&b));
+ z += memcmp (x, &b, sizeof (&b) + 0);
+ z += memcmp (x, &b, 0 + sizeof (&b));
+
+ return z;
+}
+
+template <int N>
+int
+f3 (void *x, char *y, int z, X w)
+{
+ unsigned char *y1 = (unsigned char *) __builtin_alloca (z + 16);
+ char buf1[7];
+ signed char buf2[z + 32];
+ long buf3[17];
+ int *buf4[9];
+ signed char *y2 = buf2;
+ char c;
+ char *y3;
+ memset (y, 0, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memset (y1, 0, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memset (y2, 0, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memset (&c, 0, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memset (w, 0, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+
+ memcpy (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memcpy (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memcpy (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memcpy (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memcpy (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+
+ memcpy (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memcpy (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memcpy (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memcpy (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memcpy (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+
+ memmove (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memmove (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memmove (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ memmove (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ memmove (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+
+ memmove (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memmove (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memmove (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ memmove (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ memmove (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+
+ z += memcmp (y, x, sizeof (y)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += memcmp (y1, x, sizeof (y1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += memcmp (y2, x, sizeof (y2)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += memcmp (&c, x, sizeof (&c)); // { dg-warning "call is the same expression as the destination; did you mean to remove the addressof" }
+ z += memcmp (w, x, sizeof w); // { dg-warning "call is the same expression as the destination; did you mean to dereference it" }
+
+ z += memcmp (x, y, sizeof (y)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += memcmp (x, y1, sizeof (y1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += memcmp (x, y2, sizeof (y2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += memcmp (x, &c, sizeof (&c)); // { dg-warning "call is the same expression as the source; did you mean to remove the addressof" }
+ z += memcmp (x, w, sizeof w); // { dg-warning "call is the same expression as the source; did you mean to dereference it" }
+
+ // These are correct, no warning.
+ memset (y, 0, sizeof (*y));
+ memset (y1, 0, sizeof (*y2));
+ memset (buf1, 0, sizeof buf1);
+ memset (buf3, 0, sizeof (buf3));
+ memset (&buf3[0], 0, sizeof (buf3));
+ memset (&buf4[0], 0, sizeof (buf4));
+ memset (w, 0, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memset ((void *) y, 0, sizeof (y));
+ memset ((char *) y1, 0, sizeof (y2));
+ memset (y, 0, sizeof (y) + 0);
+ memset (y1, 0, 0 + sizeof (y2));
+ memset ((void *) &c, 0, sizeof (&c));
+ memset ((signed char *) &c, 0, sizeof (&c));
+ memset (&c, 0, sizeof (&c) + 0);
+ memset (&c, 0, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ memcpy (y, x, sizeof (*y));
+ memcpy (y1, x, sizeof (*y2));
+ memcpy (buf1, x, sizeof buf1);
+ memcpy (buf3, x, sizeof (buf3));
+ memcpy (&buf3[0], x, sizeof (buf3));
+ memcpy (&buf4[0], x, sizeof (buf4));
+ memcpy (&y3, y, sizeof (y3));
+ memcpy ((char *) &y3, y, sizeof (y3));
+ memcpy (w, x, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy ((void *) y, x, sizeof (y));
+ memcpy ((char *) y1, x, sizeof (y2));
+ memcpy (y, x, sizeof (y) + 0);
+ memcpy (y1, x, 0 + sizeof (y2));
+ memcpy ((void *) &c, x, sizeof (&c));
+ memcpy ((signed char *) &c, x, sizeof (&c));
+ memcpy (&c, x, sizeof (&c) + 0);
+ memcpy (&c, x, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ memcpy (x, y, sizeof (*y));
+ memcpy (x, y1, sizeof (*y2));
+ memcpy (x, buf1, sizeof buf1);
+ memcpy (x, buf3, sizeof (buf3));
+ memcpy (x, &buf3[0], sizeof (buf3));
+ memcpy (x, &buf4[0], sizeof (buf4));
+ memcpy (y, &y3, sizeof (y3));
+ memcpy (y, (char *) &y3, sizeof (y3));
+ memcpy (x, w, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memcpy (x, (void *) y, sizeof (y));
+ memcpy (x, (char *) y1, sizeof (y2));
+ memcpy (x, y, sizeof (y) + 0);
+ memcpy (x, y1, 0 + sizeof (y2));
+ memcpy (x, (void *) &c, sizeof (&c));
+ memcpy (x, (signed char *) &c, sizeof (&c));
+ memcpy (x, &c, sizeof (&c) + 0);
+ memcpy (x, &c, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ memmove (y, x, sizeof (*y));
+ memmove (y1, x, sizeof (*y2));
+ memmove (buf1, x, sizeof buf1);
+ memmove (buf3, x, sizeof (buf3));
+ memmove (&buf3[0], x, sizeof (buf3));
+ memmove (&buf4[0], x, sizeof (buf4));
+ memmove (&y3, y, sizeof (y3));
+ memmove ((char *) &y3, y, sizeof (y3));
+ memmove (w, x, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memmove ((void *) y, x, sizeof (y));
+ memmove ((char *) y1, x, sizeof (y2));
+ memmove (y, x, sizeof (y) + 0);
+ memmove (y1, x, 0 + sizeof (y2));
+ memmove ((void *) &c, x, sizeof (&c));
+ memmove ((signed char *) &c, x, sizeof (&c));
+ memmove (&c, x, sizeof (&c) + 0);
+ memmove (&c, x, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ memmove (x, y, sizeof (*y));
+ memmove (x, y1, sizeof (*y2));
+ memmove (x, buf1, sizeof buf1);
+ memmove (x, buf3, sizeof (buf3));
+ memmove (x, &buf3[0], sizeof (buf3));
+ memmove (x, &buf4[0], sizeof (buf4));
+ memmove (y, &y3, sizeof (y3));
+ memmove (y, (char *) &y3, sizeof (y3));
+ memmove (x, w, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ memmove (x, (void *) y, sizeof (y));
+ memmove (x, (char *) y1, sizeof (y2));
+ memmove (x, y, sizeof (y) + 0);
+ memmove (x, y1, 0 + sizeof (y2));
+ memmove (x, (void *) &c, sizeof (&c));
+ memmove (x, (signed char *) &c, sizeof (&c));
+ memmove (x, &c, sizeof (&c) + 0);
+ memmove (x, &c, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ z += memcmp (y, x, sizeof (*y));
+ z += memcmp (y1, x, sizeof (*y2));
+ z += memcmp (buf1, x, sizeof buf1);
+ z += memcmp (buf3, x, sizeof (buf3));
+ z += memcmp (&buf3[0], x, sizeof (buf3));
+ z += memcmp (&buf4[0], x, sizeof (buf4));
+ z += memcmp (&y3, y, sizeof (y3));
+ z += memcmp ((char *) &y3, y, sizeof (y3));
+ z += memcmp (w, x, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp ((void *) y, x, sizeof (y));
+ z += memcmp ((char *) y1, x, sizeof (y2));
+ z += memcmp (y, x, sizeof (y) + 0);
+ z += memcmp (y1, x, 0 + sizeof (y2));
+ z += memcmp ((void *) &c, x, sizeof (&c));
+ z += memcmp ((signed char *) &c, x, sizeof (&c));
+ z += memcmp (&c, x, sizeof (&c) + 0);
+ z += memcmp (&c, x, 0 + sizeof (&c));
+
+ // These are correct, no warning.
+ z += memcmp (x, y, sizeof (*y));
+ z += memcmp (x, y1, sizeof (*y2));
+ z += memcmp (x, buf1, sizeof buf1);
+ z += memcmp (x, buf3, sizeof (buf3));
+ z += memcmp (x, &buf3[0], sizeof (buf3));
+ z += memcmp (x, &buf4[0], sizeof (buf4));
+ z += memcmp (y, &y3, sizeof (y3));
+ z += memcmp (y, (char *) &y3, sizeof (y3));
+ z += memcmp (x, w, sizeof (X));
+ // These are probably broken, but obfuscated, no warning.
+ z += memcmp (x, (void *) y, sizeof (y));
+ z += memcmp (x, (char *) y1, sizeof (y2));
+ z += memcmp (x, y, sizeof (y) + 0);
+ z += memcmp (x, y1, 0 + sizeof (y2));
+ z += memcmp (x, (void *) &c, sizeof (&c));
+ z += memcmp (x, (signed char *) &c, sizeof (&c));
+ z += memcmp (x, &c, sizeof (&c) + 0);
+ z += memcmp (x, &c, 0 + sizeof (&c));
+
+ return z;
+}
+
+template <int N>
+int
+f4 (char *x, char **y, int z)
+{
+ const char *s1 = "foobarbaz";
+ const char *s2 = "abcde12345678";
+ strncpy (x, s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ strncat (x, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ y[0] = strndup (s1, sizeof (s1)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += strncmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s1)); // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length" }
+ z += strncasecmp (s1, s2, sizeof (s2)); // { dg-warning "call is the same expression as the source; did you mean to provide an explicit length" }
+
+ // These are correct, no warning.
+ const char s3[] = "foobarbaz";
+ const char s4[] = "abcde12345678";
+ strncpy (x, s3, sizeof (s3));
+ strncat (x, s4, sizeof (s4));
+ y[1] = strndup (s3, sizeof (s3));
+ z += strncmp (s3, s4, sizeof (s3));
+ z += strncmp (s3, s4, sizeof (s4));
+ z += strncasecmp (s3, s4, sizeof (s3));
+ z += strncasecmp (s3, s4, sizeof (s4));
+
+ return z;
+}
+
+int
+f (void *x, char *y, int z, X w, char **u)
+{
+ z += f1<0> (x, z);
+ z += f2<0> (x, z);
+ z += f3<0> (x, y, z, w);
+ z += f4<0> (y, u, z);
+ return z;
+}
+
+// { dg-prune-output "\[\n\r\]*will always overflow\[\n\r\]*" }
diff --git a/gcc/testsuite/g++.dg/torture/pr54735.C b/gcc/testsuite/g++.dg/torture/pr54735.C
new file mode 100644
index 000000000..0604ec517
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr54735.C
@@ -0,0 +1,179 @@
+// { dg-do compile }
+
+class Gmpfr
+{};
+class M : Gmpfr
+{
+public:
+ Gmpfr infconst;
+ M(int);
+};
+template<typename>struct A;
+template<typename, int, int, int = 0 ? : 0, int = 0, int = 0>class N;
+template<typename>class O;
+template<typename>struct B;
+struct C
+{
+ enum
+ { value };
+};
+class D
+{
+public:
+ enum
+ { ret };
+};
+struct F
+{
+ enum
+ { ret = 0 ? : 0 };
+};
+template<typename Derived>struct G
+{
+ typedef O<Derived>type;
+};
+struct H
+{
+ void operator * ();
+};
+struct I
+{
+ enum
+ { RequireInitialization = C::value ? : 0, ReadCost };
+};
+template<typename Derived>struct J
+{
+ enum
+ { ret = A<Derived>::InnerStrideAtCompileTime };
+};
+template<typename Derived>struct K
+{
+ enum
+ { ret = A<Derived>::OuterStrideAtCompileTime };
+};
+template<typename Derived>class P : H
+{
+public:
+ using H::operator *;
+ typedef typename A<Derived>::Scalar Scalar;
+ enum
+ { RowsAtCompileTime =
+ A<Derived>::RowsAtCompileTime, ColsAtCompileTime =
+ A<Derived>::ColsAtCompileTime, SizeAtCompileTime =
+ F::ret, MaxRowsAtCompileTime =
+ A<Derived>::MaxRowsAtCompileTime, MaxColsAtCompileTime =
+ A<Derived>::MaxColsAtCompileTime, MaxSizeAtCompileTime =
+ F::ret, Flags =
+ A<Derived>::Flags ? : 0 ? : 0, CoeffReadCost =
+ A<Derived>::CoeffReadCost, InnerStrideAtCompileTime =
+ J<Derived>::ret, OuterStrideAtCompileTime = K<Derived>::ret };
+ B<Derived> operator << (const Scalar&);
+};
+
+template<typename Derived>class O : public P<Derived>
+{};
+
+template<int _Cols>class L
+{
+public:
+
+ int cols()
+ {
+ return _Cols;
+ }
+};
+template<typename Derived>class Q : public G<Derived>::type
+{
+public:
+ typedef typename G<Derived>::type Base;
+ typedef typename A<Derived>::Index Index;
+ typedef typename A<Derived>::Scalar Scalar;
+ L<Base::ColsAtCompileTime> m_storage;
+ Index cols()
+ {
+ return m_storage.cols();
+ }
+
+ Scalar& coeffRef(Index,
+ Index);
+};
+
+template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
+ int _MaxCols>struct A<N<_Scalar, _Rows, _Cols, _Options, _MaxRows,
+ _MaxCols> >
+{
+ typedef _Scalar Scalar;
+ typedef int Index;
+ enum
+ { RowsAtCompileTime, ColsAtCompileTime =
+ _Cols, MaxRowsAtCompileTime, MaxColsAtCompileTime, Flags =
+ D::ret, CoeffReadCost =
+ I::ReadCost, InnerStrideAtCompileTime, OuterStrideAtCompileTime =
+ 0 ? : 0 };
+};
+template<typename _Scalar, int, int _Cols, int, int,
+ int>class N : public Q<N<_Scalar, 0, _Cols> >
+{
+public:
+ Q<N> Base;
+ template<typename T0, typename T1>N(const T0&,
+ const T1&);
+};
+void
+__assert_fail(int)
+throw() __attribute__((__noreturn__));
+template<typename XprType>struct B
+{
+ typedef typename XprType::Scalar Scalar;
+ typedef typename XprType::Index Index;
+ B(XprType & p1, const Scalar &) : m_xpr(p1), m_col(),
+ m_currentBlockRows(1)
+ {} B& operator, (const Scalar&)
+ {
+ Index a;
+
+ if (m_col == m_xpr.cols())
+ {
+ m_col = 0;
+ m_currentBlockRows = 1;
+ a && "Too " ? static_cast<void>(0) : __assert_fail(0);
+ }
+ m_col < m_xpr.cols()
+ && "Too " ? static_cast<void>(0) : __assert_fail(1);
+ m_currentBlockRows ? static_cast<void>(0) : __assert_fail(4);
+ m_xpr.coeffRef(0, m_col++) = 0;
+ return *this;
+ }
+ ~B()
+ {
+ 1 + m_currentBlockRows && m_col
+ && "Too " ? static_cast<void>(0) : __assert_fail(0);
+ }
+
+ XprType& m_xpr;
+ Index m_col;
+ Index m_currentBlockRows;
+};
+
+template<typename Derived>B<Derived>P<
+ Derived >::operator << (const Scalar&)
+{
+ return B<Derived>(*static_cast<Derived *>(this), 0);
+}
+
+template<class NT, int s>void
+ check_()
+{
+ N<NT, 0, s>m(0, 0);
+ m << 0, 0, 0, 0;
+}
+
+template<class NT>void check()
+{
+ check_<NT, 3>();
+}
+
+int main()
+{
+ check<M>();
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wnull-conversion-1.C b/gcc/testsuite/g++.dg/warn/Wnull-conversion-1.C
index 511f091f2..84a1d380b 100644
--- a/gcc/testsuite/g++.dg/warn/Wnull-conversion-1.C
+++ b/gcc/testsuite/g++.dg/warn/Wnull-conversion-1.C
@@ -9,7 +9,7 @@ void func2() {
int* t = false; // { dg-warning "converting 'false' to pointer" }
int* p;
p = false; // { dg-warning "converting 'false' to pointer" }
- int* r = sizeof(char) / 2;
+ int* r = sizeof(char) / 2; // { dg-error "invalid conversion from" "" { target c++11 } }
func1(false); // { dg-warning "converting 'false' to pointer" }
int i = NULL; // { dg-warning "converting to non-pointer" }
}
diff --git a/gcc/testsuite/g++.dg/warn/Wsign-compare-5.C b/gcc/testsuite/g++.dg/warn/Wsign-compare-5.C
new file mode 100644
index 000000000..641c49972
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wsign-compare-5.C
@@ -0,0 +1,20 @@
+// Test that -Wsign-compare doesn't warn about
+// equality/non-equality comparisons with sizeof.
+// { dg-do compile }
+// { dg-options "-Wsign-compare" }
+
+int
+foo (int x)
+{
+ if (x != sizeof (sizeof (x))) // { dg-bogus "comparison between signed and unsigned integer expressions" }
+ return 1;
+ return 0;
+}
+
+int
+bar (int x)
+{
+ if (x == sizeof (sizeof (x)) + 1) // { dg-bogus "comparison between signed and unsigned integer expressions" }
+ return 1;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wsizeof-pointer-memaccess-1.C b/gcc/testsuite/g++.dg/warn/Wsizeof-pointer-memaccess-1.C
new file mode 100644
index 000000000..e2ba8769b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wsizeof-pointer-memaccess-1.C
@@ -0,0 +1,13 @@
+// Test -Wsizeof-pointer-memaccess warnings.
+// { dg-do compile }
+// { dg-options "-Wall" }
+
+typedef __SIZE_TYPE__ size_t;
+extern "C" void *memset (void *, int, size_t);
+
+int
+foo (int x, char b[10])
+{
+ long a[memset (b, 0, sizeof (b)) ? x + 10 : x]; // { dg-warning "call is the same expression as the destination; did you mean to provide an explicit length?" }
+ return a[0];
+}
diff --git a/gcc/testsuite/gcc.dg/attr-alias-3.c b/gcc/testsuite/gcc.dg/attr-alias-3.c
index 02637b231..6ff1b475a 100644
--- a/gcc/testsuite/gcc.dg/attr-alias-3.c
+++ b/gcc/testsuite/gcc.dg/attr-alias-3.c
@@ -1,5 +1,5 @@
// { dg-do link }
-// { dg-xfail-if "" { "powerpc-ibm-aix*" } { "*" } { "" } }
+// { dg-skip-if "" { "powerpc-ibm-aix*" } { "*" } { "" } }
// { dg-require-alias "" }
// { dg-options "-O2 -fno-common" }
diff --git a/gcc/testsuite/gcc.dg/attr-alias-5.c b/gcc/testsuite/gcc.dg/attr-alias-5.c
index d22c286fc..56d9b302c 100644
--- a/gcc/testsuite/gcc.dg/attr-alias-5.c
+++ b/gcc/testsuite/gcc.dg/attr-alias-5.c
@@ -4,6 +4,7 @@
/* { dg-options "-std=gnu99" } */
/* { dg-require-alias "" } */
/* { dg-require-ascii-locale "" } */
+/* { dg-skip-if "" { powerpc*-*-aix* } { "*" } { "" } } */
void f0 (void) __attribute__((alias("\xa1"))); /* { dg-error "undefined symbol '\\\\241'" } */
void f1 (void) __attribute__((alias("\u00e9"))); /* { dg-error "undefined symbol '\\\\U000000e9'" } */
diff --git a/gcc/testsuite/gcc.dg/builtins-85.c b/gcc/testsuite/gcc.dg/builtins-85.c
new file mode 100644
index 000000000..0993fbc19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtins-85.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+extern void __chk_fail (void);
+extern int snprintf (char *, size_t, const char *, ...);
+extern inline __attribute__((gnu_inline, always_inline)) int snprintf (char *a, size_t b, const char *fmt, ...)
+{
+ if (__builtin_object_size (a, 0) != -1UL && __builtin_object_size (a, 0) < b)
+ __chk_fail ();
+ return __builtin_snprintf (a, b, fmt, __builtin_va_arg_pack ());
+}
+extern int snprintf (char *, size_t, const char *, ...) __asm ("mysnprintf");
+
+char buf[10];
+
+int
+main (void)
+{
+ snprintf (buf, 10, "%d%d\n", 10, 10);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "mysnprintf" } } */
+/* { dg-final { scan-assembler-not "__chk_fail" } } */
diff --git a/gcc/testsuite/gcc.dg/dump-ada-spec-1.c b/gcc/testsuite/gcc.dg/dump-ada-spec-1.c
new file mode 100644
index 000000000..eb249e798
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dump-ada-spec-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fdump-ada-spec" } */
+
+struct S
+{
+ int i;
+};
+
+/* { dg-final { scan-ada-spec "type S is record" } } */
+/* { dg-final { cleanup-ada-spec } } */
diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-1.c b/gcc/testsuite/gcc.dg/guality/pr54519-1.c
new file mode 100644
index 000000000..98afd45c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54519-1.c
@@ -0,0 +1,48 @@
+/* PR debug/54519 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+__attribute__((noinline, noclone)) void
+fn1 (int x)
+{
+ __asm volatile ("" : "+r" (x) : : "memory");
+}
+
+static int
+fn2 (int x, int y, int z)
+{
+ int a = 8;
+ if (x != z)
+ {
+ fn1 (x);
+ fn1 (x); /* { dg-final { gdb-test 20 "x" "36" } } */
+ if (x == 36) /* { dg-final { gdb-test 20 "y" "25" } } */
+ fn1 (x); /* { dg-final { gdb-test 20 "z" "6" } } */
+ fn1 (x); /* { dg-final { gdb-test 23 "x" "98" } } */
+ if (x == 98) /* { dg-final { gdb-test 23 "y" "117" } } */
+ fn1 (x); /* { dg-final { gdb-test 23 "z" "8" } } */
+ fn1 (x);
+ fn1 (x + a);
+ }
+ return y;
+}
+
+__attribute__((noinline, noclone)) int
+fn3 (int x, int y)
+{
+ return fn2 (x, y, 6);
+}
+
+__attribute__((noinline, noclone)) int
+fn4 (int x, int y)
+{
+ return fn2 (x, y, 8);
+}
+
+int
+main ()
+{
+ fn3 (36, 25);
+ fn4 (98, 117);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-2.c b/gcc/testsuite/gcc.dg/guality/pr54519-2.c
new file mode 100644
index 000000000..4ee3c9e2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54519-2.c
@@ -0,0 +1,45 @@
+/* PR debug/54519 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+__attribute__((noinline, noclone)) void
+fn1 (int x)
+{
+ __asm volatile ("" : "+r" (x) : : "memory");
+}
+
+static int
+fn2 (int x, int y)
+{
+ if (y)
+ {
+ fn1 (x); /* { dg-final { gdb-test 17 "x" "6" } } */
+ fn1 (x); /* { dg-final { gdb-test 17 "y" "25" } } */
+ fn1 (x);
+ fn1 (x);
+ y = -2 + x;
+ y = y * y * y + y;
+ fn1 (x + y); /* { dg-final { gdb-test 22 "y" "68" } } */
+ }
+ return x;
+}
+
+__attribute__((noinline, noclone)) int
+fn3 (int x, int y)
+{
+ return fn2 (x, y) + y;
+}
+
+__attribute__((noinline, noclone)) int
+fn4 (int x, int y)
+{
+ return fn2 (x, y) + y;
+}
+
+int
+main ()
+{
+ fn3 (6, 25);
+ fn4 (4, 117);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-3.c b/gcc/testsuite/gcc.dg/guality/pr54519-3.c
new file mode 100644
index 000000000..aa8369e15
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54519-3.c
@@ -0,0 +1,42 @@
+/* PR debug/54519 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+__attribute__((noinline, noclone)) void
+fn1 (int x)
+{
+ __asm volatile ("" : "+r" (x) : : "memory");
+}
+
+static int
+fn2 (int x, int y, int z)
+{
+ int a = 8;
+ if (x != z)
+ {
+ fn1 (x);
+ fn1 (x); /* { dg-final { gdb-test 20 "x" "36" } } */
+ if (x == 36) /* { dg-final { gdb-test 20 "y" "25" } } */
+ fn1 (x); /* { dg-final { gdb-test 20 "z" "6" } } */
+ fn1 (x); /* { dg-final { gdb-test 23 "x" "98" } } */
+ if (x == 98) /* { dg-final { gdb-test 23 "y" "117" } } */
+ fn1 (x); /* { dg-final { gdb-test 23 "z" "8" } } */
+ fn1 (x);
+ fn1 (x + a);
+ }
+ return y;
+}
+
+int (*p) (int, int, int) = fn2;
+
+int
+main ()
+{
+ __asm volatile ("" : : : "memory");
+ int (*q) (int, int, int) = p;
+ __asm volatile ("" : : : "memory");
+ q (36, 25, 6);
+ q (98, 117, 8);
+ q (0, 0, 0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-4.c b/gcc/testsuite/gcc.dg/guality/pr54519-4.c
new file mode 100644
index 000000000..d2765d148
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54519-4.c
@@ -0,0 +1,39 @@
+/* PR debug/54519 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+__attribute__((noinline, noclone)) void
+fn1 (int x)
+{
+ __asm volatile ("" : "+r" (x) : : "memory");
+}
+
+static int
+fn2 (int x, int y)
+{
+ if (y)
+ {
+ fn1 (x); /* { dg-final { gdb-test 17 "x" "6" } } */
+ fn1 (x); /* { dg-final { gdb-test 17 "y" "25" } } */
+ fn1 (x);
+ fn1 (x);
+ y = -2 + x;
+ y = y * y * y + y;
+ fn1 (x + y); /* { dg-final { gdb-test 22 "y" "68" } } */
+ }
+ return x;
+}
+
+int (*p) (int, int) = fn2;
+
+int
+main ()
+{
+ __asm volatile ("" : : : "memory");
+ int (*q) (int, int) = p;
+ __asm volatile ("" : : : "memory");
+ q (6, 25);
+ q (4, 117);
+ q (0, 0);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-5.c b/gcc/testsuite/gcc.dg/guality/pr54519-5.c
new file mode 100644
index 000000000..c64527a45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54519-5.c
@@ -0,0 +1,45 @@
+/* PR debug/54519 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+__attribute__((noinline, noclone)) void
+fn1 (int x)
+{
+ __asm volatile ("" : "+r" (x) : : "memory");
+}
+
+static int
+fn2 (int x, int y)
+{
+ if (y)
+ {
+ fn1 (x); /* { dg-final { gdb-test 17 "x" "6" } } */
+ fn1 (x); /* { dg-final { gdb-test 17 "y" "25" } } */
+ fn1 (x);
+ fn1 (x);
+ y = -2 + x;
+ y = y * y * y + y;
+ fn1 (x + y); /* { dg-final { gdb-test 22 "y" "68" } } */
+ }
+ return x;
+}
+
+__attribute__((noinline, noclone)) int
+fn3 (int x, int y)
+{
+ return fn2 (x, y);
+}
+
+__attribute__((noinline, noclone)) int
+fn4 (int x, int y)
+{
+ return fn2 (x, y);
+}
+
+int
+main ()
+{
+ fn3 (6, 25);
+ fn4 (4, 117);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr54519-6.c b/gcc/testsuite/gcc.dg/guality/pr54519-6.c
new file mode 100644
index 000000000..836ab1f66
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54519-6.c
@@ -0,0 +1,27 @@
+/* PR debug/54519 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+#include "../nop.h"
+
+static inline void
+f1 (int x, int y)
+{
+ asm volatile (NOP); /* { dg-final { gdb-test 11 "x" "2" } } */
+ asm volatile (NOP); /* { dg-final { gdb-test 11 "y" "0" } } */
+}
+
+static inline void
+f2 (int z)
+{
+ f1 (z, 0);
+ f1 (z, 1);
+}
+
+int
+main ()
+{
+ f2 (2);
+ f2 (3);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr54551.c b/gcc/testsuite/gcc.dg/guality/pr54551.c
new file mode 100644
index 000000000..4235f78ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/pr54551.c
@@ -0,0 +1,28 @@
+/* PR debug/54551 */
+/* { dg-do run } */
+/* { dg-options "-g" } */
+
+void __attribute__((__noinline__))
+bar (void)
+{
+ asm volatile ("");
+}
+
+int __attribute__((__noinline__))
+foo (int x, int y, int z)
+{
+ if (x != z)
+ {
+ int a = z + 1;
+ bar (); /* { dg-final { gdb-test 18 "a" "4" } } */
+ bar (); /* { dg-final { gdb-test 18 "z" "3" } } */
+ }
+ return y;
+}
+
+int
+main ()
+{
+ foo (1, 2, 3);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lower-subreg-1.c b/gcc/testsuite/gcc.dg/lower-subreg-1.c
index 8c7cc2c09..f5827e1db 100644
--- a/gcc/testsuite/gcc.dg/lower-subreg-1.c
+++ b/gcc/testsuite/gcc.dg/lower-subreg-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! { mips64 || { arm-*-* ia64-*-* spu-*-* tilegx-*-* } } } } } */
+/* { dg-do compile { target { ! { mips64 || { arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */
/* { dg-options "-O -fdump-rtl-subreg1" } */
/* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } { "*" } { "" } } */
/* { dg-require-effective-target ilp32 } */
diff --git a/gcc/testsuite/gcc.dg/lto/20120723_0.c b/gcc/testsuite/gcc.dg/lto/20120723_0.c
index ea08a0067..78cfdf77c 100644
--- a/gcc/testsuite/gcc.dg/lto/20120723_0.c
+++ b/gcc/testsuite/gcc.dg/lto/20120723_0.c
@@ -1,7 +1,9 @@
/* Make sure that by reference and by value aggregate jump functions do not get
- mixed up. */
+ mixed up.
+ ??? This testcase is invalid C and can only pass on specific platforms. */
/* { dg-lto-do run } */
-/* { dg-lto-options {{-O3 -fno-early-inlining -flto}} } */
+/* { dg-skip-if "" { { sparc*-*-* } && ilp32 } { "*" } { "" } } */
+/* { dg-lto-options { {-O3 -fno-early-inlining -flto}} } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/lto/resolutions_0.c b/gcc/testsuite/gcc.dg/lto/resolutions_0.c
new file mode 100644
index 000000000..9e59cb069
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/resolutions_0.c
@@ -0,0 +1,10 @@
+/* { dg-require-linker-plugin "" } */
+/* { dg-extra-ld-options "-fuse-linker-plugin -O1" } */
+
+link_error()
+{
+}
+main()
+{
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr54087.c b/gcc/testsuite/gcc.dg/pr54087.c
new file mode 100644
index 000000000..abb0af3d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr54087.c
@@ -0,0 +1,18 @@
+/* PR54087. Verify __atomic_sub (val) uses __atomic_add (-val) if there is no
+ atomic_aub. */
+/* { dg-require-effective-target sync_int_long } */
+/* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-final { scan-assembler-times "xadd" 2 } } */
+
+
+int a;
+
+int f1(int p)
+{
+ return __atomic_sub_fetch(&a, p, __ATOMIC_SEQ_CST) == 0;
+}
+
+int f2(int p)
+{
+ return __atomic_fetch_sub(&a, p, __ATOMIC_SEQ_CST) - p == 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr54782.c b/gcc/testsuite/gcc.dg/pr54782.c
new file mode 100644
index 000000000..2a3075449
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr54782.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ffast-math -ftree-parallelize-loops=2 -g" } */
+
+struct S
+{
+ int n;
+ float *a;
+};
+
+int
+foo (struct S *s)
+{
+ float sum = 0;
+ int i;
+ for (i = 0; i < s->n; i++)
+ sum += s->a[i];
+ return sum;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr51106-2.c b/gcc/testsuite/gcc.dg/torture/pr51106-2.c
index 80328a92e..bab0987ff 100644
--- a/gcc/testsuite/gcc.dg/torture/pr51106-2.c
+++ b/gcc/testsuite/gcc.dg/torture/pr51106-2.c
@@ -1,7 +1,7 @@
/* PR target/51106 */
/* { dg-do "compile" } */
/* { dg-skip-if "RTL error" { "*-*-*" } { "-fno-fat-lto-objects" } { "" } } */
-/* { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
int
bar (int x)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
index 91a3f56a6..be3a49dfa 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fwrapv -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fwrapv -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fwrapv -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fwrapv -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
index 69eb6303f..7af5fd072 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c
index 33788134e..50dea9cb3 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11b.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c
index 269a85fd1..f3ada9944 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11c.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=3 -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c
index d74ebaf27..ad6f4b5af 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c
index b2796c1b7..c96ee001e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c
index 954e24c92..f14bf837a 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c
index abe07cae7..d90520eff 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c
index 0a862ab89..ffc5e265d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c
@@ -1,6 +1,6 @@
/* { dg-do run { target vect_cmdline_needed } } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats" } */
-/* { dg-options "-O2 -ftree-vectorize -ftree-vectorizer-verbose=4 -fdump-tree-vect-stats -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
+/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details -mno-sse" { target { i?86-*-* x86_64-*-* } } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp85.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp85.c
new file mode 100644
index 000000000..ad2b38d02
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp85.c
@@ -0,0 +1,40 @@
+/* PR tree-optimization/54810 */
+/* { dg-do link } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+extern void link_error (void);
+
+#define T(n, ntype, wtype) \
+void \
+f##n (wtype s) \
+{ \
+ if ((ntype) s == 0) \
+ return; \
+ if (s == 0) \
+ link_error (); \
+}
+
+T(1, unsigned char, unsigned char)
+T(2, unsigned char, unsigned short)
+T(3, unsigned char, unsigned int)
+T(4, unsigned char, unsigned long int)
+T(5, unsigned char, unsigned long long int)
+T(6, unsigned short int, unsigned short int)
+T(7, unsigned short int, unsigned int)
+T(8, unsigned short int, unsigned long int)
+T(9, unsigned short int, unsigned long long int)
+T(10, unsigned int, unsigned int)
+T(11, unsigned int, unsigned long int)
+T(12, unsigned int, unsigned long long int)
+T(13, unsigned long int, unsigned long int)
+T(14, unsigned long int, unsigned long long int)
+T(15, unsigned long long int, unsigned long long int)
+
+int
+main ()
+{
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "link_error" "vrp1"} } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/ucnid-10.c b/gcc/testsuite/gcc.dg/ucnid-10.c
index 37b18d7e0..83425d3cf 100644
--- a/gcc/testsuite/gcc.dg/ucnid-10.c
+++ b/gcc/testsuite/gcc.dg/ucnid-10.c
@@ -3,7 +3,7 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -fextended-identifiers" } */
/* { dg-require-ascii-locale "" } */
-/* { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
#pragma pack(push)
#pragma pack(pop, \u00f3) /* { dg-warning "pop, \\\\U000000f3.*push, \\\\U000000f3" } */
diff --git a/gcc/testsuite/gcc.dg/ucnid-13.c b/gcc/testsuite/gcc.dg/ucnid-13.c
index 24309d125..0b94247ba 100644
--- a/gcc/testsuite/gcc.dg/ucnid-13.c
+++ b/gcc/testsuite/gcc.dg/ucnid-13.c
@@ -3,7 +3,7 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -fextended-identifiers -Wpacked" } */
/* { dg-require-ascii-locale "" } */
-/* { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
int a __attribute__((\u00c0)); /* { dg-warning "'\\\\U000000c0' attribute directive ignored" } */
diff --git a/gcc/testsuite/gcc.dg/ucnid-7.c b/gcc/testsuite/gcc.dg/ucnid-7.c
index da5aa0ddb..3f73e35d4 100644
--- a/gcc/testsuite/gcc.dg/ucnid-7.c
+++ b/gcc/testsuite/gcc.dg/ucnid-7.c
@@ -3,7 +3,7 @@
/* { dg-do compile } */
/* { dg-options "-std=c99 -fextended-identifiers" } */
/* { dg-require-ascii-locale "" } */
-/* { dg-xfail-if "" { "powerpc-ibm-aix*" } { "*" } { "" } } */
+/* { dg-skip-if "" { "powerpc-ibm-aix*" } { "*" } { "" } } */
void *p = &\u00e9; /* { dg-error "'\\\\U000000e9' undeclared" } */
void *q = &\u1e00; /* { dg-error "'\\\\U00001e00' undeclared" } */
diff --git a/gcc/testsuite/gcc.dg/ucnid-8.c b/gcc/testsuite/gcc.dg/ucnid-8.c
index 0e48a7f6d..df1f35053 100644
--- a/gcc/testsuite/gcc.dg/ucnid-8.c
+++ b/gcc/testsuite/gcc.dg/ucnid-8.c
@@ -3,7 +3,7 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99 -fextended-identifiers -Wvla" } */
/* { dg-require-ascii-locale "" } */
-/* { dg-xfail-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc-ibm-aix* } { "*" } { "" } } */
int a __attribute__((__mode__(\u00e9))); /* { dg-error "unknown machine mode '\\\\U000000e9'" } */
struct s1 { int \u00e9 : 0; }; /* { dg-error "zero width for bit-field '\\\\U000000e9'" } */
diff --git a/gcc/testsuite/gcc.dg/vmx/3b-13.c b/gcc/testsuite/gcc.dg/vmx/3b-13.c
index 146f737ae..42c3ca4fa 100644
--- a/gcc/testsuite/gcc.dg/vmx/3b-13.c
+++ b/gcc/testsuite/gcc.dg/vmx/3b-13.c
@@ -3,7 +3,7 @@
vector signed int
f(vector float a, vector signed int b)
{
- return vec_splat(vec_cts(vec_ctf(vec_ctu(a, 31),0),9),30);
+ return vec_splat(vec_cts(vec_ctf(vec_ctu(a, 31),0),9),2);
}
static void test()
diff --git a/gcc/testsuite/gcc.target/i386/pr54457.c b/gcc/testsuite/gcc.target/i386/pr54457.c
new file mode 100644
index 000000000..d27f899fd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr54457.c
@@ -0,0 +1,11 @@
+/* { dg-do compile { target { ! { ia32 } } } } */
+/* { dg-options "-O2 -mx32 -maddress-mode=short" } */
+
+extern char array[40];
+
+char foo (long long position)
+{
+ return array[position + 1];
+}
+
+/* { dg-final { scan-assembler-not "add\[lq\]?\[^\n\]*1" } } */
diff --git a/gcc/testsuite/gcc.target/i386/vect-double-1.c b/gcc/testsuite/gcc.target/i386/vect-double-1.c
index 0b691bcbb..d96d6399c 100644
--- a/gcc/testsuite/gcc.target/i386/vect-double-1.c
+++ b/gcc/testsuite/gcc.target/i386/vect-double-1.c
@@ -32,5 +32,5 @@ sse2_test (void)
}
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "Vectorized loops: 1" 1 "vect" } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.target/i386/vect-rebuild.c b/gcc/testsuite/gcc.target/i386/vect-rebuild.c
new file mode 100644
index 000000000..570967f6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/vect-rebuild.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O -mavx -fno-tree-forwprop" } */
+
+typedef double v2df __attribute__ ((__vector_size__ (16)));
+typedef double v4df __attribute__ ((__vector_size__ (32)));
+
+v2df f1 (v2df x)
+{
+ v2df xx = { x[0], x[1] };
+ return xx;
+}
+
+v4df f2 (v4df x)
+{
+ v4df xx = { x[0], x[1], x[2], x[3] };
+ return xx;
+}
+
+v2df g (v2df x)
+{
+ v2df xx = { x[1], x[0] };
+ return xx;
+}
+
+v2df h (v4df x)
+{
+ v2df xx = { x[2], x[3] };
+ return xx;
+}
+
+/* { dg-final { scan-assembler-not "unpck" } } */
+/* { dg-final { scan-assembler-times "\tv?permilpd\[ \t\]" 1 } } */
+/* { dg-final { scan-assembler-times "\tv?extractf128\[ \t\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/mips/madd-9.c b/gcc/testsuite/gcc.target/mips/madd-9.c
index 6d545495c..28681a910 100644
--- a/gcc/testsuite/gcc.target/mips/madd-9.c
+++ b/gcc/testsuite/gcc.target/mips/madd-9.c
@@ -1,7 +1,13 @@
/* { dg-do compile } */
-/* { dg-options "isa_rev>=1 -mgp32" } */
-/* { dg-skip-if "code quality test" { *-*-* } { "-O0" } { "" } } */
+/* { dg-options "isa_rev>=1 -mgp32 -mtune=4kc" } */
+/* References to X within the loop need to have a higher frequency than
+ references to X outside the loop, otherwise there is no reason
+ to prefer multiply/accumulator registers over GPRs. */
+/* { dg-skip-if "requires register frequencies" { *-*-* } { "-O0" "-Os" } { "" } } */
/* { dg-final { scan-assembler-not "\tmul\t" } } */
+/* { dg-final { scan-assembler-not "\tmthi" } } */
+/* { dg-final { scan-assembler-not "\tmtlo" } } */
+/* { dg-final { scan-assembler "\tmult\t" } } */
/* { dg-final { scan-assembler "\tmadd\t" } } */
NOMIPS16 long long
diff --git a/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-1.c b/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-1.c
new file mode 100644
index 000000000..d26f99840
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-1.c
@@ -0,0 +1,22 @@
+/* { dg-options "-mdspr2 -mgp32 -mtune=74kc" } */
+/* References to RESULT within the loop need to have a higher frequency than
+ references to RESULT outside the loop, otherwise there is no reason
+ to prefer multiply/accumulator registers over GPRs. */
+/* { dg-skip-if "requires register frequencies" { *-*-* } { "-O0" "-Os" } { "" } } */
+
+/* Check that the zero-initialization of the accumulator feeding into
+ the madd is done by means of a mult instruction instead of mthi/mtlo. */
+
+NOMIPS16 long long f (int n, int *v, int m)
+{
+ long long result = 0;
+ int i;
+
+ for (i = 0; i < n; i++)
+ result = __builtin_mips_madd (result, v[i], m);
+ return result;
+}
+
+/* { dg-final { scan-assembler "\tmult\t\\\$ac.,\\\$0,\\\$0" } } */
+/* { dg-final { scan-assembler-not "mthi\t" } } */
+/* { dg-final { scan-assembler-not "mtlo\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c b/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c
new file mode 100644
index 000000000..8d06a8039
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/mips32-dsp-accinit-2.c
@@ -0,0 +1,22 @@
+/* { dg-options "-mdspr2 -mgp32 -mtune=4kp" } */
+/* References to RESULT within the loop need to have a higher frequency than
+ references to RESULT outside the loop, otherwise there is no reason
+ to prefer multiply/accumulator registers over GPRs. */
+/* { dg-skip-if "requires register frequencies" { *-*-* } { "-O0" "-Os" } { "" } } */
+
+/* Check that the zero-initialization of the accumulator feeding into
+ the madd is done by means of a mult instruction instead of mthi/mtlo. */
+
+NOMIPS16 long long f (int n, int *v, int m)
+{
+ long long result = 0;
+ int i;
+
+ for (i = 0; i < n; i++)
+ result = __builtin_mips_madd (result, v[i], m);
+ return result;
+}
+
+/* { dg-final { scan-assembler-not "mult\t\[^\n\]*\\\$0" } } */
+/* { dg-final { scan-assembler "\tmthi\t" } } */
+/* { dg-final { scan-assembler "\tmtlo\t" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr46728-1.c b/gcc/testsuite/gcc.target/powerpc/pr46728-1.c
index 16336243a..9c15987df 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr46728-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr46728-1.c
@@ -27,5 +27,5 @@ main (int argc, char *argv[])
}
-/* { dg-final { scan-assembler-times "fsqrt" 2 { target powerpc*-*-* } } } */
+/* { dg-final { scan-assembler-times "fsqrt|xssqrtdp" 2 { target powerpc*-*-* } } } */
/* { dg-final { scan-assembler-not "pow" { target powerpc*-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr46728-2.c b/gcc/testsuite/gcc.target/powerpc/pr46728-2.c
index abf92491f..b89617dad 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr46728-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr46728-2.c
@@ -27,5 +27,5 @@ main (int argc, char *argv[])
}
-/* { dg-final { scan-assembler-times "fsqrt" 4 { target powerpc*-*-* } } } */
+/* { dg-final { scan-assembler-times "fsqrt|xssqrtdp" 4 { target powerpc*-*-* } } } */
/* { dg-final { scan-assembler-not "pow" { target powerpc*-*-* } } } */
diff --git a/gcc/testsuite/gcc.target/sh/pr51244-12.c b/gcc/testsuite/gcc.target/sh/pr51244-12.c
new file mode 100644
index 000000000..ca8e2d4b3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr51244-12.c
@@ -0,0 +1,68 @@
+/* Check that the negc instruction is generated as expected for the cases
+ below. If we see a movrt or #-1 negc sequence it means that the pattern
+ which handles the inverted case does not work properly. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*" } { "" } } */
+/* { dg-final { scan-assembler-times "negc" 10 } } */
+/* { dg-final { scan-assembler-not "movrt|#-1|add|sub" } } */
+
+int
+test00 (int a, int b, int* x)
+{
+ return (a == b) ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test00_inv (int a, int b)
+{
+ return (a != b) ? 0x80000000 : 0x7FFFFFFF;
+}
+
+int
+test01 (int a, int b)
+{
+ return (a >= b) ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test01_inv (int a, int b)
+{
+ return (a < b) ? 0x80000000 : 0x7FFFFFFF;
+}
+
+int
+test02 (int a, int b)
+{
+ return (a > b) ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test02_inv (int a, int b)
+{
+ return (a <= b) ? 0x80000000 : 0x7FFFFFFF;
+}
+
+int
+test03 (int a, int b)
+{
+ return ((a & b) == 0) ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test03_inv (int a, int b)
+{
+ return ((a & b) != 0) ? 0x80000000 : 0x7FFFFFFF;
+}
+
+int
+test04 (int a)
+{
+ return ((a & 0x55) == 0) ? 0x7FFFFFFF : 0x80000000;
+}
+
+int
+test04_inv (int a)
+{
+ return ((a & 0x55) != 0) ? 0x80000000 : 0x7FFFFFFF;
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr54760-1.c b/gcc/testsuite/gcc.target/sh/pr54760-1.c
new file mode 100644
index 000000000..9108a3fde
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr54760-1.c
@@ -0,0 +1,20 @@
+/* Check that the __builtin_thread_pointer and __builtin_set_thread_pointer
+ built-in functions result in gbr store / load instructions. */
+/* { dg-do compile { target "sh*-*-*" } } */
+/* { dg-options "-O1" } */
+/* { dg-skip-if "" { "sh*-*-*" } { "-m5*"} { "" } } */
+/* { dg-final { scan-assembler-times "ldc" 1 } } */
+/* { dg-final { scan-assembler-times "stc" 1 } } */
+/* { dg-final { scan-assembler-times "gbr" 2 } } */
+
+void*
+test00 (void)
+{
+ return __builtin_thread_pointer ();
+}
+
+void
+test01 (void* p)
+{
+ __builtin_set_thread_pointer (p);
+}
diff --git a/gcc/testsuite/gfortran.dg/class_53.f90 b/gcc/testsuite/gfortran.dg/class_53.f90
new file mode 100644
index 000000000..0a8c96208
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/class_53.f90
@@ -0,0 +1,18 @@
+! { dg-do compile }
+!
+! PR 54778: [OOP] an ICE on invalid OO code
+!
+! Contributed by Sylwester Arabas <slayoo@staszic.waw.pl>
+
+implicit none
+
+type :: arr_t
+ real :: at
+end type
+
+type(arr_t) :: this
+class(arr_t) :: elem ! { dg-error "must be dummy, allocatable or pointer" }
+
+elem = this ! { dg-error "Variable must not be polymorphic in intrinsic assignment" }
+
+end
diff --git a/gcc/testsuite/gfortran.dg/generic_25.f90 b/gcc/testsuite/gfortran.dg/generic_25.f90
new file mode 100644
index 000000000..39b7e23eb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/generic_25.f90
@@ -0,0 +1,30 @@
+! { dg-do run }
+!
+! PR 45521: [F08] GENERIC resolution with ALLOCATABLE/POINTER and PROCEDURE
+!
+! Contributed by <wangmianzhi1@linuxmail.org>
+
+ interface test
+ procedure testAlloc
+ procedure testPtr
+ end interface
+
+ integer, allocatable :: a1
+ integer, pointer :: a2
+
+ if (.not.test(a1)) call abort()
+ if (test(a2)) call abort()
+
+contains
+
+ logical function testAlloc(obj)
+ integer, allocatable :: obj
+ testAlloc = .true.
+ end function
+
+ logical function testPtr(obj)
+ integer, pointer :: obj
+ testPtr = .false.
+ end function
+
+end
diff --git a/gcc/testsuite/gfortran.dg/generic_26.f90 b/gcc/testsuite/gfortran.dg/generic_26.f90
new file mode 100644
index 000000000..a1deef19f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/generic_26.f90
@@ -0,0 +1,29 @@
+! { dg-do compile }
+! { dg-options "-std=f2003" }
+!
+! PR 45521: [F08] GENERIC resolution with ALLOCATABLE/POINTER and PROCEDURE
+!
+! Contributed by <wangmianzhi1@linuxmail.org>
+
+module a
+
+ interface test
+ procedure testAlloc
+ procedure testPtr ! { dg-error "Ambiguous interfaces" }
+ end interface
+
+contains
+
+ logical function testAlloc(obj)
+ integer, allocatable :: obj
+ testAlloc = .true.
+ end function
+
+ logical function testPtr(obj)
+ integer, pointer :: obj
+ testPtr = .false.
+ end function
+
+end
+
+! { dg-final { cleanup-modules "a" } }
diff --git a/gcc/testsuite/gfortran.dg/generic_27.f90 b/gcc/testsuite/gfortran.dg/generic_27.f90
new file mode 100644
index 000000000..f4f4f5ab9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/generic_27.f90
@@ -0,0 +1,34 @@
+! { dg-do run }
+!
+! PR 45521: [F08] GENERIC resolution with ALLOCATABLE/POINTER and PROCEDURE
+!
+! Contributed by Janus Weil <janus@gcc.gnu.org>
+
+module m
+ implicit none
+ interface testIF
+ module procedure test1
+ module procedure test2
+ end interface
+contains
+ real function test1 (obj)
+ real :: obj
+ test1 = obj
+ end function
+ real function test2 (pr)
+ procedure(real) :: pr
+ test2 = pr(0.)
+ end function
+end module
+
+program test
+ use m
+ implicit none
+ intrinsic :: cos
+
+ if (testIF(2.0)/=2.0) call abort()
+ if (testIF(cos)/=1.0) call abort()
+
+end program
+
+! { dg-final { cleanup-modules "m" } }
diff --git a/gcc/testsuite/gfortran.dg/typebound_operator_17.f90 b/gcc/testsuite/gfortran.dg/typebound_operator_17.f90
new file mode 100644
index 000000000..4e58a7fa2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_operator_17.f90
@@ -0,0 +1,43 @@
+! { dg-do compile }
+!
+! PR 54832: [4.8 Regression] [OOP] Type-bound operator not picked up with RESULT variable
+!
+! Contributed by Damian Rouson <rouson@sandia.gov>
+
+ type, abstract :: integrand
+ contains
+ procedure(t_interface), deferred :: t
+ procedure(assign_interface), deferred :: assign
+ procedure(times_interface), deferred :: times
+ generic :: operator(*) => times
+ generic :: assignment(=) => assign
+ end type
+
+ abstract interface
+ function t_interface(this) result(dState_dt)
+ import :: integrand
+ class(integrand) ,intent(in) :: this
+ class(integrand) ,allocatable :: dState_dt
+ end function
+ function times_interface(lhs,rhs)
+ import :: integrand
+ class(integrand) ,intent(in) :: lhs
+ class(integrand) ,allocatable :: times_interface
+ real, intent(in) :: rhs
+ end function
+ subroutine assign_interface(lhs,rhs)
+ import :: integrand
+ class(integrand) ,intent(in) :: rhs
+ class(integrand) ,intent(inout) :: lhs
+ end subroutine
+ end interface
+
+contains
+
+ subroutine integrate(model,dt)
+ class(integrand) :: model
+ real dt
+ model = model%t()*dt
+ end subroutine
+
+end
diff --git a/gcc/testsuite/gfortran.dg/vect/vect.exp b/gcc/testsuite/gfortran.dg/vect/vect.exp
index f00b25773..caacc0419 100644
--- a/gcc/testsuite/gfortran.dg/vect/vect.exp
+++ b/gcc/testsuite/gfortran.dg/vect/vect.exp
@@ -26,7 +26,7 @@ set DEFAULT_VECTCFLAGS ""
# These flags are used for all targets.
lappend DEFAULT_VECTCFLAGS "-O2" "-ftree-vectorize" "-fno-vect-cost-model" \
- "-ftree-vectorizer-verbose=4" "-fdump-tree-vect-stats"
+ "-fdump-tree-vect-details"
# If the target system supports vector instructions, the default action
# for a test is 'run', otherwise it's 'compile'. Save current default.
diff --git a/gcc/testsuite/lib/gcc-dg.exp b/gcc/testsuite/lib/gcc-dg.exp
index 2cc49f7e6..b3f8d3bb1 100644
--- a/gcc/testsuite/lib/gcc-dg.exp
+++ b/gcc/testsuite/lib/gcc-dg.exp
@@ -503,6 +503,19 @@ proc cleanup-stack-usage { } {
}
}
+# Remove an Ada spec file for the current test.
+proc cleanup-ada-spec { } {
+ set testcase [testname-for-summary]
+ remove-build-file "[get_ada_spec_filename $testcase]"
+
+ # Clean up files for additional source files.
+ if [info exists additional_sources] {
+ foreach srcfile $additional_sources {
+ remove-build-file "[get_ada_spec_filename $srcfile]"
+ }
+ }
+}
+
# Remove all dump files with the provided suffix.
proc cleanup-dump { suffix } {
set testcase [testname-for-summary]
diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp
index c513857cd..598948e81 100644
--- a/gcc/testsuite/lib/scanasm.exp
+++ b/gcc/testsuite/lib/scanasm.exp
@@ -184,6 +184,38 @@ proc scan-stack-usage-not { args } {
dg-scan "scan-file-not" 0 $testcase $output_file $args
}
+# Return the filename of the Ada spec corresponding to the argument.
+
+proc get_ada_spec_filename { testcase } {
+ # The name might include a list of options; extract the file name.
+ set filename [lindex $testcase 0]
+ set tailname [file tail $filename]
+ set extension [string trimleft [file extension $tailname] {.}]
+ set rootname [regsub -all {\-} [file rootname $tailname] {_}]
+
+ return [string tolower "${rootname}_${extension}.ads"]
+}
+
+# Look for a pattern in the .ads file produced by the compiler. See
+# dg-scan for details.
+
+proc scan-ada-spec { args } {
+ set testcase [testname-for-summary]
+ set output_file "[get_ada_spec_filename $testcase]"
+
+ dg-scan "scan-file" 1 $testcase $output_file $args
+}
+
+# Check that a pattern is not present in the .ads file produced by the
+# compiler. See dg-scan for details.
+
+proc scan-ada-spec-not { args } {
+ set testcase [testname-for-summary]
+ set output_file "[get_ada_spec_filename $testcase]"
+
+ dg-scan "scan-file-not" 0 $testcase $output_file $args
+}
+
# Call pass if pattern is present given number of times, otherwise fail.
proc scan-assembler-times { args } {
if { [llength $args] < 2 } {
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 2aa3e4000..2c9329f76 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1815,6 +1815,9 @@ finalize (bool no_backend)
if (mem_report)
dump_memory_report (true);
+ if (profile_report)
+ dump_profile_report ();
+
/* Language-specific end of compilation actions. */
lang_hooks.finish ();
}
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 307fb64ad..9a41e0753 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -49,6 +49,7 @@ extern void emit_debug_global_declarations (tree *, int);
extern void write_global_declarations (void);
extern void dump_memory_report (bool);
+extern void dump_profile_report (void);
extern void target_reinit (void);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 774e74f2a..af277b79e 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -4000,6 +4000,80 @@ verify_gimple_assign_single (gimple stmt)
return res;
case CONSTRUCTOR:
+ if (TREE_CODE (rhs1_type) == VECTOR_TYPE)
+ {
+ unsigned int i;
+ tree elt_i, elt_v, elt_t = NULL_TREE;
+
+ if (CONSTRUCTOR_NELTS (rhs1) == 0)
+ return res;
+ /* For vector CONSTRUCTORs we require that either it is empty
+ CONSTRUCTOR, or it is a CONSTRUCTOR of smaller vector elements
+ (then the element count must be correct to cover the whole
+ outer vector and index must be NULL on all elements, or it is
+ a CONSTRUCTOR of scalar elements, where we as an exception allow
+ smaller number of elements (assuming zero filling) and
+ consecutive indexes as compared to NULL indexes (such
+ CONSTRUCTORs can appear in the IL from FEs). */
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (rhs1), i, elt_i, elt_v)
+ {
+ if (elt_t == NULL_TREE)
+ {
+ elt_t = TREE_TYPE (elt_v);
+ if (TREE_CODE (elt_t) == VECTOR_TYPE)
+ {
+ tree elt_t = TREE_TYPE (elt_v);
+ if (!useless_type_conversion_p (TREE_TYPE (rhs1_type),
+ TREE_TYPE (elt_t)))
+ {
+ error ("incorrect type of vector CONSTRUCTOR"
+ " elements");
+ debug_generic_stmt (rhs1);
+ return true;
+ }
+ else if (CONSTRUCTOR_NELTS (rhs1)
+ * TYPE_VECTOR_SUBPARTS (elt_t)
+ != TYPE_VECTOR_SUBPARTS (rhs1_type))
+ {
+ error ("incorrect number of vector CONSTRUCTOR"
+ " elements");
+ debug_generic_stmt (rhs1);
+ return true;
+ }
+ }
+ else if (!useless_type_conversion_p (TREE_TYPE (rhs1_type),
+ elt_t))
+ {
+ error ("incorrect type of vector CONSTRUCTOR elements");
+ debug_generic_stmt (rhs1);
+ return true;
+ }
+ else if (CONSTRUCTOR_NELTS (rhs1)
+ > TYPE_VECTOR_SUBPARTS (rhs1_type))
+ {
+ error ("incorrect number of vector CONSTRUCTOR elements");
+ debug_generic_stmt (rhs1);
+ return true;
+ }
+ }
+ else if (!useless_type_conversion_p (elt_t, TREE_TYPE (elt_v)))
+ {
+ error ("incorrect type of vector CONSTRUCTOR elements");
+ debug_generic_stmt (rhs1);
+ return true;
+ }
+ if (elt_i != NULL_TREE
+ && (TREE_CODE (elt_t) == VECTOR_TYPE
+ || TREE_CODE (elt_i) != INTEGER_CST
+ || compare_tree_int (elt_i, i) != 0))
+ {
+ error ("vector CONSTRUCTOR with non-NULL element index");
+ debug_generic_stmt (rhs1);
+ return true;
+ }
+ }
+ }
+ return res;
case OBJ_TYPE_REF:
case ASSERT_EXPR:
case WITH_SIZE_EXPR:
@@ -6248,6 +6322,7 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
use_operand_p use;
tree op = PHI_RESULT (phi);
ssa_op_iter oi;
+ unsigned i;
if (virtual_operand_p (op))
{
@@ -6266,6 +6341,23 @@ move_block_to_fn (struct function *dest_cfun, basic_block bb,
SET_USE (use, replace_ssa_name (op, d->vars_map, dest_cfun->decl));
}
+ for (i = 0; i < EDGE_COUNT (bb->preds); i++)
+ {
+ location_t locus = gimple_phi_arg_location (phi, i);
+ tree block = LOCATION_BLOCK (locus);
+
+ if (locus == UNKNOWN_LOCATION)
+ continue;
+ if (d->orig_block == NULL_TREE || block == d->orig_block)
+ {
+ if (d->new_block == NULL_TREE)
+ locus = LOCATION_LOCUS (locus);
+ else
+ locus = COMBINE_LOCATION_DATA (line_table, locus, d->new_block);
+ gimple_phi_arg_set_location (phi, i, locus);
+ }
+ }
+
gsi_next (&si);
}
diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c
index 5a1fa3a0d..a1511ea7e 100644
--- a/gcc/tree-dump.c
+++ b/gcc/tree-dump.c
@@ -26,17 +26,10 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h"
#include "splay-tree.h"
#include "filenames.h"
-#include "diagnostic-core.h"
-#include "toplev.h"
#include "tree-dump.h"
#include "langhooks.h"
#include "tree-iterator.h"
-/* If non-NULL, return one past-the-end of the matching SUBPART of
- the WHOLE string. */
-#define skip_leading_substring(whole, part) \
- (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
-
static unsigned int queue (dump_info_p, const_tree, int);
static void dump_index (dump_info_p, unsigned int);
static void dequeue_and_dump (dump_info_p);
@@ -162,6 +155,22 @@ dump_maybe_newline (dump_info_p di)
}
}
+/* Dump FUNCTION_DECL FN as tree dump PHASE. */
+
+void
+dump_function (int phase, tree fn)
+{
+ FILE *stream;
+ int flags;
+
+ stream = dump_begin (phase, &flags);
+ if (stream)
+ {
+ dump_function_to_file (fn, stream, flags);
+ dump_end (phase, stream);
+ }
+}
+
/* Dump pointer PTR using FIELD to identify it. */
void
@@ -766,362 +775,3 @@ dump_node (const_tree t, int flags, FILE *stream)
}
splay_tree_delete (di.nodes);
}
-
-
-/* Table of tree dump switches. This must be consistent with the
- tree_dump_index enumeration in tree-pass.h. */
-static struct dump_file_info dump_files[TDI_end] =
-{
- {NULL, NULL, NULL, 0, 0, 0},
- {".cgraph", "ipa-cgraph", NULL, TDF_IPA, 0, 0},
- {".tu", "translation-unit", NULL, TDF_TREE, 0, 1},
- {".class", "class-hierarchy", NULL, TDF_TREE, 0, 2},
- {".original", "tree-original", NULL, TDF_TREE, 0, 3},
- {".gimple", "tree-gimple", NULL, TDF_TREE, 0, 4},
- {".nested", "tree-nested", NULL, TDF_TREE, 0, 5},
- {".vcg", "tree-vcg", NULL, TDF_TREE, 0, 6},
- {".ads", "ada-spec", NULL, 0, 0, 7},
-#define FIRST_AUTO_NUMBERED_DUMP 8
-
- {NULL, "tree-all", NULL, TDF_TREE, 0, 0},
- {NULL, "rtl-all", NULL, TDF_RTL, 0, 0},
- {NULL, "ipa-all", NULL, TDF_IPA, 0, 0},
-};
-
-/* Dynamically registered tree dump files and switches. */
-static struct dump_file_info *extra_dump_files;
-static size_t extra_dump_files_in_use;
-static size_t extra_dump_files_alloced;
-
-/* Define a name->number mapping for a dump flag value. */
-struct dump_option_value_info
-{
- const char *const name; /* the name of the value */
- const int value; /* the value of the name */
-};
-
-/* Table of dump options. This must be consistent with the TDF_* flags
- in tree.h */
-static const struct dump_option_value_info dump_options[] =
-{
- {"address", TDF_ADDRESS},
- {"asmname", TDF_ASMNAME},
- {"slim", TDF_SLIM},
- {"raw", TDF_RAW},
- {"graph", TDF_GRAPH},
- {"details", TDF_DETAILS},
- {"cselib", TDF_CSELIB},
- {"stats", TDF_STATS},
- {"blocks", TDF_BLOCKS},
- {"vops", TDF_VOPS},
- {"lineno", TDF_LINENO},
- {"uid", TDF_UID},
- {"stmtaddr", TDF_STMTADDR},
- {"memsyms", TDF_MEMSYMS},
- {"verbose", TDF_VERBOSE},
- {"eh", TDF_EH},
- {"alias", TDF_ALIAS},
- {"nouid", TDF_NOUID},
- {"enumerate_locals", TDF_ENUMERATE_LOCALS},
- {"scev", TDF_SCEV},
- {"all", ~(TDF_RAW | TDF_SLIM | TDF_LINENO | TDF_TREE | TDF_RTL | TDF_IPA
- | TDF_STMTADDR | TDF_GRAPH | TDF_DIAGNOSTIC | TDF_VERBOSE
- | TDF_RHS_ONLY | TDF_NOUID | TDF_ENUMERATE_LOCALS | TDF_SCEV)},
- {NULL, 0}
-};
-
-unsigned int
-dump_register (const char *suffix, const char *swtch, const char *glob,
- int flags)
-{
- static int next_dump = FIRST_AUTO_NUMBERED_DUMP;
- int num = next_dump++;
-
- size_t count = extra_dump_files_in_use++;
-
- if (count >= extra_dump_files_alloced)
- {
- if (extra_dump_files_alloced == 0)
- extra_dump_files_alloced = 32;
- else
- extra_dump_files_alloced *= 2;
- extra_dump_files = XRESIZEVEC (struct dump_file_info,
- extra_dump_files,
- extra_dump_files_alloced);
- }
-
- memset (&extra_dump_files[count], 0, sizeof (struct dump_file_info));
- extra_dump_files[count].suffix = suffix;
- extra_dump_files[count].swtch = swtch;
- extra_dump_files[count].glob = glob;
- extra_dump_files[count].flags = flags;
- extra_dump_files[count].num = num;
-
- return count + TDI_end;
-}
-
-
-/* Return the dump_file_info for the given phase. */
-
-struct dump_file_info *
-get_dump_file_info (int phase)
-{
- if (phase < TDI_end)
- return &dump_files[phase];
- else if ((size_t) (phase - TDI_end) >= extra_dump_files_in_use)
- return NULL;
- else
- return extra_dump_files + (phase - TDI_end);
-}
-
-
-/* Return the name of the dump file for the given phase.
- If the dump is not enabled, returns NULL. */
-
-char *
-get_dump_file_name (int phase)
-{
- char dump_id[10];
- struct dump_file_info *dfi;
-
- if (phase == TDI_none)
- return NULL;
-
- dfi = get_dump_file_info (phase);
- if (dfi->state == 0)
- return NULL;
-
- if (dfi->num < 0)
- dump_id[0] = '\0';
- else
- {
- char suffix;
- if (dfi->flags & TDF_TREE)
- suffix = 't';
- else if (dfi->flags & TDF_IPA)
- suffix = 'i';
- else
- suffix = 'r';
-
- if (snprintf (dump_id, sizeof (dump_id), ".%03d%c", dfi->num, suffix) < 0)
- dump_id[0] = '\0';
- }
-
- return concat (dump_base_name, dump_id, dfi->suffix, NULL);
-}
-
-/* Begin a tree dump for PHASE. Stores any user supplied flag in
- *FLAG_PTR and returns a stream to write to. If the dump is not
- enabled, returns NULL.
- Multiple calls will reopen and append to the dump file. */
-
-FILE *
-dump_begin (int phase, int *flag_ptr)
-{
- char *name;
- struct dump_file_info *dfi;
- FILE *stream;
-
- if (phase == TDI_none || !dump_enabled_p (phase))
- return NULL;
-
- name = get_dump_file_name (phase);
- dfi = get_dump_file_info (phase);
- stream = fopen (name, dfi->state < 0 ? "w" : "a");
- if (!stream)
- error ("could not open dump file %qs: %m", name);
- else
- dfi->state = 1;
- free (name);
-
- if (flag_ptr)
- *flag_ptr = dfi->flags;
-
- return stream;
-}
-
-/* Returns nonzero if tree dump PHASE is enabled. If PHASE is
- TDI_tree_all, return nonzero if any dump is enabled. */
-
-int
-dump_enabled_p (int phase)
-{
- if (phase == TDI_tree_all)
- {
- size_t i;
- for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
- if (dump_files[i].state)
- return 1;
- for (i = 0; i < extra_dump_files_in_use; i++)
- if (extra_dump_files[i].state)
- return 1;
- return 0;
- }
- else
- {
- struct dump_file_info *dfi = get_dump_file_info (phase);
- return dfi->state;
- }
-}
-
-/* Returns nonzero if tree dump PHASE has been initialized. */
-
-int
-dump_initialized_p (int phase)
-{
- struct dump_file_info *dfi = get_dump_file_info (phase);
- return dfi->state > 0;
-}
-
-/* Returns the switch name of PHASE. */
-
-const char *
-dump_flag_name (int phase)
-{
- struct dump_file_info *dfi = get_dump_file_info (phase);
- return dfi->swtch;
-}
-
-/* Finish a tree dump for PHASE. STREAM is the stream created by
- dump_begin. */
-
-void
-dump_end (int phase ATTRIBUTE_UNUSED, FILE *stream)
-{
- fclose (stream);
-}
-
-/* Enable all tree dumps. Return number of enabled tree dumps. */
-
-static int
-dump_enable_all (int flags)
-{
- int ir_dump_type = (flags & (TDF_TREE | TDF_RTL | TDF_IPA));
- int n = 0;
- size_t i;
-
- for (i = TDI_none + 1; i < (size_t) TDI_end; i++)
- if ((dump_files[i].flags & ir_dump_type))
- {
- dump_files[i].state = -1;
- dump_files[i].flags |= flags;
- n++;
- }
-
- for (i = 0; i < extra_dump_files_in_use; i++)
- if ((extra_dump_files[i].flags & ir_dump_type))
- {
- extra_dump_files[i].state = -1;
- extra_dump_files[i].flags |= flags;
- n++;
- }
-
- return n;
-}
-
-/* Parse ARG as a dump switch. Return nonzero if it is, and store the
- relevant details in the dump_files array. */
-
-static int
-dump_switch_p_1 (const char *arg, struct dump_file_info *dfi, bool doglob)
-{
- const char *option_value;
- const char *ptr;
- int flags;
-
- if (doglob && !dfi->glob)
- return 0;
-
- option_value = skip_leading_substring (arg, doglob ? dfi->glob : dfi->swtch);
- if (!option_value)
- return 0;
-
- if (*option_value && *option_value != '-')
- return 0;
-
- ptr = option_value;
- flags = 0;
-
- while (*ptr)
- {
- const struct dump_option_value_info *option_ptr;
- const char *end_ptr;
- unsigned length;
-
- while (*ptr == '-')
- ptr++;
- end_ptr = strchr (ptr, '-');
- if (!end_ptr)
- end_ptr = ptr + strlen (ptr);
- length = end_ptr - ptr;
-
- for (option_ptr = dump_options; option_ptr->name; option_ptr++)
- if (strlen (option_ptr->name) == length
- && !memcmp (option_ptr->name, ptr, length))
- {
- flags |= option_ptr->value;
- goto found;
- }
- warning (0, "ignoring unknown option %q.*s in %<-fdump-%s%>",
- length, ptr, dfi->swtch);
- found:;
- ptr = end_ptr;
- }
-
- dfi->state = -1;
- dfi->flags |= flags;
-
- /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the
- known dumps. */
- if (dfi->suffix == NULL)
- dump_enable_all (dfi->flags);
-
- return 1;
-}
-
-int
-dump_switch_p (const char *arg)
-{
- size_t i;
- int any = 0;
-
- for (i = TDI_none + 1; i != TDI_end; i++)
- any |= dump_switch_p_1 (arg, &dump_files[i], false);
-
- /* Don't glob if we got a hit already */
- if (!any)
- for (i = TDI_none + 1; i != TDI_end; i++)
- any |= dump_switch_p_1 (arg, &dump_files[i], true);
-
- for (i = 0; i < extra_dump_files_in_use; i++)
- any |= dump_switch_p_1 (arg, &extra_dump_files[i], false);
-
- if (!any)
- for (i = 0; i < extra_dump_files_in_use; i++)
- any |= dump_switch_p_1 (arg, &extra_dump_files[i], true);
-
-
- return any;
-}
-
-/* Dump FUNCTION_DECL FN as tree dump PHASE. */
-
-void
-dump_function (int phase, tree fn)
-{
- FILE *stream;
- int flags;
-
- stream = dump_begin (phase, &flags);
- if (stream)
- {
- dump_function_to_file (fn, stream, flags);
- dump_end (phase, stream);
- }
-}
-
-bool
-enable_rtl_dump_file (void)
-{
- return dump_enable_all (TDF_RTL | TDF_DETAILS | TDF_BLOCKS) > 0;
-}
diff --git a/gcc/tree-dump.h b/gcc/tree-dump.h
index 50faf4b84..67ea6e5f7 100644
--- a/gcc/tree-dump.h
+++ b/gcc/tree-dump.h
@@ -89,12 +89,9 @@ extern void dump_string_field (dump_info_p, const char *, const char *);
extern void queue_and_dump_index (dump_info_p, const char *, const_tree, int);
extern void queue_and_dump_type (dump_info_p, const_tree);
extern void dump_function (int, tree);
-extern void dump_function_to_file (tree, FILE *, int);
-extern void debug_function (tree, int);
extern int dump_flag (dump_info_p, int, const_tree);
-extern unsigned int dump_register (const char *, const char *, const char *,
- int);
-
+/* In tree-cfg.c */
+extern void dump_function_to_file (tree, FILE *, int);
#endif /* ! GCC_TREE_DUMP_H */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index a585c0b88..2c8071e8c 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -2374,6 +2374,31 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
gimple_debug_source_bind_set_var (stmt, t);
walk_tree (gimple_debug_source_bind_get_value_ptr (stmt),
remap_gimple_op_r, &wi, NULL);
+ /* When inlining and source bind refers to one of the optimized
+ away parameters, change the source bind into normal debug bind
+ referring to the corresponding DEBUG_EXPR_DECL that should have
+ been bound before the call stmt. */
+ t = gimple_debug_source_bind_get_value (stmt);
+ if (t != NULL_TREE
+ && TREE_CODE (t) == PARM_DECL
+ && id->gimple_call)
+ {
+ VEC(tree, gc) **debug_args = decl_debug_args_lookup (id->src_fn);
+ unsigned int i;
+ if (debug_args != NULL)
+ {
+ for (i = 0; i < VEC_length (tree, *debug_args); i += 2)
+ if (VEC_index (tree, *debug_args, i) == DECL_ORIGIN (t)
+ && TREE_CODE (VEC_index (tree, *debug_args, i + 1))
+ == DEBUG_EXPR_DECL)
+ {
+ t = VEC_index (tree, *debug_args, i + 1);
+ stmt->gsbase.subcode = GIMPLE_DEBUG_BIND;
+ gimple_debug_bind_set_value (stmt, t);
+ break;
+ }
+ }
+ }
}
processing_debug_stmt = 0;
@@ -3814,6 +3839,12 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
goto egress;
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn))
+ /* For extern inline functions that get redefined we always
+ silently ignored always_inline flag. Better behaviour would
+ be to be able to keep both bodies and use extern inline body
+ for inlining, but we can't do that because frontends overwrite
+ the body. */
+ && !cg_edge->callee->local.redefined_extern_inline
/* Avoid warnings during early inline pass. */
&& cgraph_global_info_ready
/* PR 20090218-1_0.c. Body can be provided by another module. */
@@ -3921,7 +3952,29 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
initialize_inlined_parameters (id, stmt, fn, bb);
if (DECL_INITIAL (fn))
- prepend_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id));
+ {
+ tree *var;
+
+ prepend_lexical_block (id->block, remap_blocks (DECL_INITIAL (fn), id));
+ gcc_checking_assert (BLOCK_SUBBLOCKS (id->block)
+ && (BLOCK_CHAIN (BLOCK_SUBBLOCKS (id->block))
+ == NULL_TREE));
+ /* Move vars for PARM_DECLs from DECL_INITIAL block to id->block,
+ otherwise for DWARF DW_TAG_formal_parameter will not be children of
+ DW_TAG_inlined_subroutine, but of a DW_TAG_lexical_block
+ under it. The parameters can be then evaluated in the debugger,
+ but don't show in backtraces. */
+ for (var = &BLOCK_VARS (BLOCK_SUBBLOCKS (id->block)); *var; )
+ if (TREE_CODE (DECL_ORIGIN (*var)) == PARM_DECL)
+ {
+ tree v = *var;
+ *var = TREE_CHAIN (v);
+ TREE_CHAIN (v) = BLOCK_VARS (id->block);
+ BLOCK_VARS (id->block) = v;
+ }
+ else
+ var = &TREE_CHAIN (*var);
+ }
/* Return statements in the function body will be replaced by jumps
to the RET_LABEL. */
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 0b9980361..b4d868889 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -235,6 +235,7 @@ get_frame_type (struct nesting_info *info)
info->frame_type = type;
info->frame_decl = create_tmp_var_for (info, type, "FRAME");
+ DECL_NONLOCAL_FRAME (info->frame_decl) = 1;
/* ??? Always make it addressable for now, since it is meant to
be pointed to by the static chain pointer. This pessimizes
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 41ddf57d6..a3b981ec0 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -1944,7 +1944,6 @@ gather_scalar_reductions (loop_p loop, htab_t reduction_list)
gimple_stmt_iterator gsi;
loop_vec_info simple_loop_info;
- vect_dump = NULL;
simple_loop_info = vect_analyze_loop_form (loop);
for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
diff --git a/gcc/tree-ssa-address.c b/gcc/tree-ssa-address.c
index caa51be6a..c5b8ff105 100644
--- a/gcc/tree-ssa-address.c
+++ b/gcc/tree-ssa-address.c
@@ -821,16 +821,6 @@ get_address_description (tree op, struct mem_address *addr)
addr->offset = TMR_OFFSET (op);
}
-/* Copies the additional information attached to target_mem_ref FROM to TO. */
-
-void
-copy_mem_ref_info (tree to, tree from)
-{
- /* And the info about the original reference. */
- TREE_SIDE_EFFECTS (to) = TREE_SIDE_EFFECTS (from);
- TREE_THIS_VOLATILE (to) = TREE_THIS_VOLATILE (from);
-}
-
/* Copies the reference information from OLD_REF to NEW_REF, where
NEW_REF should be either a MEM_REF or a TARGET_MEM_REF. */
@@ -901,7 +891,7 @@ maybe_fold_tmr (tree ref)
{
struct mem_address addr;
bool changed = false;
- tree ret, off;
+ tree new_ref, off;
get_address_description (ref, &addr);
@@ -962,10 +952,11 @@ maybe_fold_tmr (tree ref)
ended up folding it, always create a new TARGET_MEM_REF regardless
if it is valid in this for on the target - the propagation result
wouldn't be anyway. */
- ret = create_mem_ref_raw (TREE_TYPE (ref),
- TREE_TYPE (addr.offset), &addr, false);
- copy_mem_ref_info (ret, ref);
- return ret;
+ new_ref = create_mem_ref_raw (TREE_TYPE (ref),
+ TREE_TYPE (addr.offset), &addr, false);
+ TREE_SIDE_EFFECTS (new_ref) = TREE_SIDE_EFFECTS (ref);
+ TREE_THIS_VOLATILE (new_ref) = TREE_THIS_VOLATILE (ref);
+ return new_ref;
}
/* Dump PARTS to FILE. */
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index b0e951a22..eb1af4e9e 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -571,7 +571,7 @@ forward_propagate_into_cond (gimple_stmt_iterator *gsi_p)
if (TREE_CODE_CLASS (code) == tcc_comparison)
tmp = fold_build2_loc (gimple_location (def_stmt),
code,
- boolean_type_node,
+ TREE_TYPE (cond),
gimple_assign_rhs1 (def_stmt),
gimple_assign_rhs2 (def_stmt));
else if ((code == BIT_NOT_EXPR
diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c
index 7bf89d19f..b63dc7e81 100644
--- a/gcc/tree-ssa-live.c
+++ b/gcc/tree-ssa-live.c
@@ -621,6 +621,11 @@ clear_unused_block_pointer_1 (tree *tp, int *, void *)
if (EXPR_P (*tp) && TREE_BLOCK (*tp)
&& !TREE_USED (TREE_BLOCK (*tp)))
TREE_SET_BLOCK (*tp, NULL);
+ if (TREE_CODE (*tp) == VAR_DECL && DECL_DEBUG_EXPR_IS_FROM (*tp))
+ {
+ tree debug_expr = DECL_DEBUG_EXPR (*tp);
+ walk_tree (&debug_expr, clear_unused_block_pointer_1, NULL, NULL);
+ }
return NULL_TREE;
}
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index e76e64398..ac5353905 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -638,29 +638,22 @@ outermost_indep_loop (struct loop *outer, struct loop *loop, mem_ref_p ref)
static tree *
simple_mem_ref_in_stmt (gimple stmt, bool *is_store)
{
- tree *lhs;
- enum tree_code code;
+ tree *lhs, *rhs;
- /* Recognize MEM = (SSA_NAME | invariant) and SSA_NAME = MEM patterns. */
- if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ /* Recognize SSA_NAME = MEM and MEM = (SSA_NAME | invariant) patterns. */
+ if (!gimple_assign_single_p (stmt))
return NULL;
- code = gimple_assign_rhs_code (stmt);
-
lhs = gimple_assign_lhs_ptr (stmt);
+ rhs = gimple_assign_rhs1_ptr (stmt);
- if (TREE_CODE (*lhs) == SSA_NAME)
+ if (TREE_CODE (*lhs) == SSA_NAME && gimple_vuse (stmt))
{
- if (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS
- || !is_gimple_addressable (gimple_assign_rhs1 (stmt)))
- return NULL;
-
*is_store = false;
- return gimple_assign_rhs1_ptr (stmt);
+ return rhs;
}
- else if (code == SSA_NAME
- || (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS
- && is_gimple_min_invariant (gimple_assign_rhs1 (stmt))))
+ else if (gimple_vdef (stmt)
+ && (TREE_CODE (*rhs) == SSA_NAME || is_gimple_min_invariant (*rhs)))
{
*is_store = true;
return lhs;
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 86c33d318..8dbbed236 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -4820,6 +4820,13 @@ do_pre (void)
free_scc_vn ();
+ /* Tail merging invalidates the virtual SSA web, together with
+ cfg-cleanup opportunities exposed by PRE this will wreck the
+ SSA updating machinery. So make sure to run update-ssa
+ manually, before eventually scheduling cfg-cleanup as part of
+ the todo. */
+ update_ssa (TODO_update_ssa_only_virtuals);
+
return todo;
}
@@ -4845,8 +4852,7 @@ struct gimple_opt_pass pass_pre =
0, /* properties_provided */
0, /* properties_destroyed */
TODO_rebuild_alias, /* todo_flags_start */
- TODO_update_ssa_only_virtuals | TODO_ggc_collect
- | TODO_verify_ssa /* todo_flags_finish */
+ TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
}
};
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 9e62ebe2e..832328d32 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1,5 +1,5 @@
/* SCC value numbering for trees
- Copyright (C) 2006, 2007, 2008, 2009, 2010
+ Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
Free Software Foundation, Inc.
Contributed by Daniel Berlin <dan@dberlin.org>
@@ -1639,8 +1639,12 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_)
if (i < CONSTRUCTOR_NELTS (ctor))
{
constructor_elt *elt = CONSTRUCTOR_ELT (ctor, i);
- if (compare_tree_int (elt->index, i) == 0)
- val = elt->value;
+ if (TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
+ {
+ if (TREE_CODE (TREE_TYPE (elt->value))
+ != VECTOR_TYPE)
+ val = elt->value;
+ }
}
}
if (val)
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index f9bee51b0..fc6984583 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -216,6 +216,9 @@ unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
expr->decl_common.off_align = bp_unpack_value (bp, 8);
}
+ if (TREE_CODE (expr) == VAR_DECL)
+ DECL_NONLOCAL_FRAME (expr) = (unsigned) bp_unpack_value (bp, 1);
+
if (TREE_CODE (expr) == RESULT_DECL
|| TREE_CODE (expr) == PARM_DECL
|| TREE_CODE (expr) == VAR_DECL)
@@ -789,22 +792,22 @@ static void
lto_input_ts_block_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
- /* Do not stream BLOCK_SOURCE_LOCATION. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
- dwarf2out.c. */
BLOCK_VARS (expr) = streamer_read_chain (ib, data_in);
- /* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
- dwarf2out.c. */
-
BLOCK_SUPERCONTEXT (expr) = stream_read_tree (ib, data_in);
- /* Do not stream BLOCK_ABSTRACT_ORIGIN. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
+ /* Stream BLOCK_ABSTRACT_ORIGIN and BLOCK_SOURCE_LOCATION for
+ the limited cases we can handle - those that represent inlined
+ function scopes. For the rest them on the floor instead of ICEing in
dwarf2out.c. */
- BLOCK_FRAGMENT_ORIGIN (expr) = stream_read_tree (ib, data_in);
- BLOCK_FRAGMENT_CHAIN (expr) = stream_read_tree (ib, data_in);
+ BLOCK_ABSTRACT_ORIGIN (expr) = stream_read_tree (ib, data_in);
+ BLOCK_SOURCE_LOCATION (expr) = lto_input_location (ib, data_in);
+ /* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information
+ for early inlined BLOCKs so drop it on the floor instead of ICEing in
+ dwarf2out.c. */
+
+ /* BLOCK_FRAGMENT_ORIGIN and BLOCK_FRAGMENT_CHAIN is not live at LTO
+ streaming time. */
/* We re-compute BLOCK_SUBBLOCKS of our parent here instead
of streaming it. For non-BLOCK BLOCK_SUPERCONTEXTs we still
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index 54059a87d..4fccd7720 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -181,6 +181,9 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_value (bp, expr->decl_common.off_align, 8);
}
+ if (TREE_CODE (expr) == VAR_DECL)
+ bp_pack_value (bp, DECL_NONLOCAL_FRAME (expr), 1);
+
if (TREE_CODE (expr) == RESULT_DECL
|| TREE_CODE (expr) == PARM_DECL
|| TREE_CODE (expr) == VAR_DECL)
@@ -682,21 +685,32 @@ write_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
static void
write_ts_block_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
{
- /* Do not stream BLOCK_SOURCE_LOCATION. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
- dwarf2out.c. */
streamer_write_chain (ob, BLOCK_VARS (expr), ref_p);
+ stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
+
+ /* Stream BLOCK_ABSTRACT_ORIGIN and BLOCK_SOURCE_LOCATION for
+ the limited cases we can handle - those that represent inlined
+ function scopes. For the rest them on the floor instead of ICEing in
+ dwarf2out.c. */
+ if (inlined_function_outer_scope_p (expr))
+ {
+ tree ultimate_origin = block_ultimate_origin (expr);
+ stream_write_tree (ob, ultimate_origin, ref_p);
+ lto_output_location (ob, BLOCK_SOURCE_LOCATION (expr));
+ }
+ else
+ {
+ stream_write_tree (ob, NULL_TREE, ref_p);
+ lto_output_location (ob, UNKNOWN_LOCATION);
+ }
/* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
+ for early inlined BLOCKs so drop it on the floor instead of ICEing in
dwarf2out.c. */
- stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
- /* Do not stream BLOCK_ABSTRACT_ORIGIN. We cannot handle debug information
- for early inlining so drop it on the floor instead of ICEing in
- dwarf2out.c. */
- stream_write_tree (ob, BLOCK_FRAGMENT_ORIGIN (expr), ref_p);
- stream_write_tree (ob, BLOCK_FRAGMENT_CHAIN (expr), ref_p);
+ /* BLOCK_FRAGMENT_ORIGIN and BLOCK_FRAGMENT_CHAIN is not live at LTO
+ streaming time. */
+
/* Do not output BLOCK_SUBBLOCKS. Instead on streaming-in this
list is re-constructed from BLOCK_SUPERCONTEXT. */
}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 09704694d..dc6e1e72b 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "dumpfile.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
@@ -59,23 +60,26 @@ vect_lanes_optab_supported_p (const char *name, convert_optab optab,
if (array_mode == BLKmode)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no array mode for %s[" HOST_WIDE_INT_PRINT_DEC "]",
- GET_MODE_NAME (mode), count);
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no array mode for %s[" HOST_WIDE_INT_PRINT_DEC "]",
+ GET_MODE_NAME (mode), count);
return false;
}
if (convert_optab_handler (optab, array_mode, mode) == CODE_FOR_nothing)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "cannot use %s<%s><%s>",
- name, GET_MODE_NAME (array_mode), GET_MODE_NAME (mode));
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "cannot use %s<%s><%s>", name,
+ GET_MODE_NAME (array_mode), GET_MODE_NAME (mode));
return false;
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "can use %s<%s><%s>",
- name, GET_MODE_NAME (array_mode), GET_MODE_NAME (mode));
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "can use %s<%s><%s>", name, GET_MODE_NAME (array_mode),
+ GET_MODE_NAME (mode));
return true;
}
@@ -435,12 +439,13 @@ vect_check_interleaving (struct data_reference *dra,
if (diff_mod_size == 0)
{
vect_update_interleaving_chain (drb, dra);
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Detected interleaving ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Detected interleaving ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
}
return true;
}
@@ -457,12 +462,13 @@ vect_check_interleaving (struct data_reference *dra,
if (diff_mod_size == 0)
{
vect_update_interleaving_chain (dra, drb);
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Detected interleaving ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Detected interleaving ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
}
return true;
}
@@ -518,26 +524,29 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
if ((unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS) == 0)
return false;
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "mark for run-time aliasing test between ");
- print_generic_expr (vect_dump, DR_REF (DDR_A (ddr)), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (DDR_B (ddr)), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "mark for run-time aliasing test between ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_A (ddr)));
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_B (ddr)));
}
if (optimize_loop_nest_for_size_p (loop))
{
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "versioning not supported when optimizing for size.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "versioning not supported when optimizing for size.");
return false;
}
/* FORNOW: We don't support versioning with outer-loop vectorization. */
if (loop->inner)
{
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "versioning not yet supported for outer-loops.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "versioning not yet supported for outer-loops.");
return false;
}
@@ -546,9 +555,10 @@ vect_mark_for_runtime_alias_test (ddr_p ddr, loop_vec_info loop_vinfo)
if (TREE_CODE (DR_STEP (DDR_A (ddr))) != INTEGER_CST
|| TREE_CODE (DR_STEP (DDR_B (ddr))) != INTEGER_CST)
{
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "versioning not yet supported for non-constant "
- "step");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "versioning not yet supported for non-constant "
+ "step");
return false;
}
@@ -601,13 +611,16 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (loop_vinfo)
{
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "versioning for alias required: "
- "can't determine dependence between ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "versioning for alias required: "
+ "can't determine dependence between ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ DR_REF (dra));
+ dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ DR_REF (drb));
}
/* Add to list of ddrs that need to be tested at run-time. */
@@ -624,12 +637,13 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (DR_IS_READ (dra) && DR_IS_READ (drb))
return false;
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "can't determine dependence between ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "can't determine dependence between ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
+ dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
}
/* We do not vectorize basic blocks with write-write dependencies. */
@@ -652,31 +666,34 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
if (dra != drb && vect_check_interleaving (dra, drb))
return false;
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "determined dependence between ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "determined dependence between ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
}
/* Do not vectorize basic blcoks with write-write dependences. */
if (DR_IS_WRITE (dra) && DR_IS_WRITE (drb))
return true;
- /* Check if this dependence is allowed in basic block vectorization. */
+ /* Check if this dependence is allowed in basic block vectorization. */
return vect_drs_dependent_in_basic_block (dra, drb);
}
/* Loop-based vectorization and known data dependence. */
if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "versioning for alias required: bad dist vector for ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "versioning for alias required: "
+ "bad dist vector for ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dra));
+ dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (drb));
}
/* Add to list of ddrs that need to be tested at run-time. */
return !vect_mark_for_runtime_alias_test (ddr, loop_vinfo);
@@ -687,17 +704,19 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
{
int dist = dist_v[loop_depth];
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "dependence distance = %d.", dist);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "dependence distance = %d.", dist);
if (dist == 0)
{
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "dependence distance == 0 between ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "dependence distance == 0 between ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
}
/* For interleaving, mark that there is a read-write dependency if
@@ -718,8 +737,9 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
/* If DDR_REVERSED_P the order of the data-refs in DDR was
reversed (to make distance vector positive), and the actual
distance is negative. */
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "dependence distance negative.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "dependence distance negative.");
continue;
}
@@ -729,27 +749,30 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
/* The dependence distance requires reduction of the maximal
vectorization factor. */
*max_vf = abs (dist);
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "adjusting maximal vectorization factor to %i",
- *max_vf);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "adjusting maximal vectorization factor to %i",
+ *max_vf);
}
if (abs (dist) >= *max_vf)
{
/* Dependence distance does not create dependence, as far as
vectorization is concerned, in this case. */
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "dependence distance >= VF.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "dependence distance >= VF.");
continue;
}
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized, possible dependence "
- "between data-refs ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized, possible dependence "
+ "between data-refs ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
}
return true;
@@ -772,9 +795,9 @@ vect_analyze_data_ref_dependences (loop_vec_info loop_vinfo,
VEC (ddr_p, heap) *ddrs = NULL;
struct data_dependence_relation *ddr;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_analyze_dependences ===");
-
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_analyze_dependences ===");
if (loop_vinfo)
ddrs = LOOP_VINFO_DDRS (loop_vinfo);
else
@@ -814,8 +837,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
tree misalign;
tree aligned_to, alignment;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_compute_data_ref_alignment:");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_compute_data_ref_alignment:");
if (loop_vinfo)
loop = LOOP_VINFO_LOOP (loop_vinfo);
@@ -846,16 +870,18 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
if (dr_step % GET_MODE_SIZE (TYPE_MODE (vectype)) == 0)
{
- if (vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "inner step divides the vector-size.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "inner step divides the vector-size.");
misalign = STMT_VINFO_DR_INIT (stmt_info);
aligned_to = STMT_VINFO_DR_ALIGNED_TO (stmt_info);
base_addr = STMT_VINFO_DR_BASE_ADDRESS (stmt_info);
}
else
{
- if (vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "inner step doesn't divide the vector-size.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "inner step doesn't divide the vector-size.");
misalign = NULL_TREE;
}
}
@@ -872,8 +898,9 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
if (dr_step % GET_MODE_SIZE (TYPE_MODE (vectype)) != 0)
{
- if (vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "SLP: step doesn't divide the vector-size.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "SLP: step doesn't divide the vector-size.");
misalign = NULL_TREE;
}
}
@@ -884,10 +911,11 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
if ((aligned_to && tree_int_cst_compare (aligned_to, alignment) < 0)
|| !misalign)
{
- if (vect_print_dump_info (REPORT_ALIGNMENT))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Unknown alignment for access: ");
- print_generic_expr (vect_dump, base, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Unknown alignment for access: ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, base);
}
return true;
}
@@ -913,10 +941,11 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
if (!vect_can_force_dr_alignment_p (base, TYPE_ALIGN (vectype))
|| (TREE_STATIC (base) && flag_section_anchors))
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "can't force alignment of ref: ");
- print_generic_expr (vect_dump, ref, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "can't force alignment of ref: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
}
return true;
}
@@ -924,10 +953,10 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
/* Force the alignment of the decl.
NOTE: This is the only change to the code we make during
the analysis phase, before deciding to vectorize the loop. */
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "force alignment of ");
- print_generic_expr (vect_dump, ref, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "force alignment of ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
}
DECL_ALIGN (base) = TYPE_ALIGN (vectype);
@@ -958,17 +987,19 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
if (!host_integerp (misalign, 1))
{
/* Negative or overflowed misalignment value. */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unexpected misalign value");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unexpected misalign value");
return false;
}
SET_DR_MISALIGNMENT (dr, TREE_INT_CST_LOW (misalign));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr));
- print_generic_expr (vect_dump, ref, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "misalign = %d bytes of ref ", DR_MISALIGNMENT (dr));
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, ref);
}
return true;
@@ -1064,8 +1095,8 @@ vect_update_misalignment_for_peel (struct data_reference *dr,
return;
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Setting misalignment to -1.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "Setting misalignment to -1.");
SET_DR_MISALIGNMENT (dr, -1);
}
@@ -1111,22 +1142,25 @@ vect_verify_datarefs_alignment (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
supportable_dr_alignment = vect_supportable_dr_alignment (dr, false);
if (!supportable_dr_alignment)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
if (DR_IS_READ (dr))
- fprintf (vect_dump,
- "not vectorized: unsupported unaligned load.");
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported unaligned load.");
else
- fprintf (vect_dump,
- "not vectorized: unsupported unaligned store.");
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported unaligned "
+ "store.");
- print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ DR_REF (dr));
}
return false;
}
if (supportable_dr_alignment != dr_aligned
- && vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "Vectorizing an unaligned access.");
+ && dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Vectorizing an unaligned access.");
}
return true;
}
@@ -1181,15 +1215,18 @@ vector_alignment_reachable_p (struct data_reference *dr)
{
HOST_WIDE_INT elmsize =
int_cst_value (TYPE_SIZE_UNIT (TREE_TYPE (vectype)));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "data size =" HOST_WIDE_INT_PRINT_DEC, elmsize);
- fprintf (vect_dump, ". misalignment = %d. ", DR_MISALIGNMENT (dr));
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "data size =" HOST_WIDE_INT_PRINT_DEC, elmsize);
+ dump_printf (MSG_NOTE,
+ ". misalignment = %d. ", DR_MISALIGNMENT (dr));
}
if (DR_MISALIGNMENT (dr) % elmsize)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "data size does not divide the misalignment.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "data size does not divide the misalignment.\n");
return false;
}
}
@@ -1198,8 +1235,9 @@ vector_alignment_reachable_p (struct data_reference *dr)
{
tree type = TREE_TYPE (DR_REF (dr));
bool is_packed = not_size_aligned (DR_REF (dr));
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Unknown misalignment, is_packed = %d",is_packed);
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Unknown misalignment, is_packed = %d",is_packed);
if (targetm.vectorize.vector_alignment_reachable (type, is_packed))
return true;
else
@@ -1231,9 +1269,10 @@ vect_get_data_access_cost (struct data_reference *dr,
else
vect_get_store_cost (dr, ncopies, inside_cost, body_cost_vec);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_get_data_access_cost: inside_cost = %d, "
- "outside_cost = %d.", *inside_cost, *outside_cost);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_get_data_access_cost: inside_cost = %d, "
+ "outside_cost = %d.", *inside_cost, *outside_cost);
}
@@ -1528,8 +1567,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
unsigned int nelements, mis, same_align_drs_max = 0;
stmt_vector_for_cost body_cost_vec = NULL;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_enhance_data_refs_alignment ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_enhance_data_refs_alignment ===");
/* While cost model enhancements are expected in the future, the high level
view of the code at this time is as follows:
@@ -1582,8 +1622,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
and so we can't generate the new base for the pointer. */
if (STMT_VINFO_STRIDE_LOAD_P (stmt_info))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "strided load prevents peeling");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "strided load prevents peeling");
do_peeling = false;
break;
}
@@ -1697,9 +1738,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
{
if (!aligned_access_p (dr))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vector alignment may not be reachable");
-
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "vector alignment may not be reachable");
break;
}
}
@@ -1838,8 +1879,9 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
if (STMT_VINFO_GROUPED_ACCESS (stmt_info))
npeel /= GROUP_SIZE (stmt_info);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Try peeling by %d", npeel);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Try peeling by %d", npeel);
}
/* Ensure that all data refs can be vectorized after the peel. */
@@ -1909,12 +1951,13 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
else
LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo) = DR_MISALIGNMENT (dr0);
SET_DR_MISALIGNMENT (dr0, 0);
- if (vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "Alignment of access forced using peeling.");
-
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Peeling for alignment will be applied.");
-
+ if (dump_kind_p (MSG_NOTE))
+ {
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Alignment of access forced using peeling.");
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Peeling for alignment will be applied.");
+ }
/* We've delayed passing the inside-loop peeling costs to the
target cost model until we were sure peeling would happen.
Do so now. */
@@ -2034,12 +2077,14 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
dr = STMT_VINFO_DATA_REF (stmt_info);
SET_DR_MISALIGNMENT (dr, 0);
- if (vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "Alignment of access forced using versioning.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Alignment of access forced using versioning.");
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Versioning for alignment will be applied.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Versioning for alignment will be applied.");
/* Peeling and versioning can't be done together at this time. */
gcc_assert (! (do_peeling && do_versioning));
@@ -2103,8 +2148,9 @@ vect_find_same_alignment_drs (struct data_dependence_relation *ddr,
{
int dist = dist_v[loop_depth];
- if (vect_print_dump_info (REPORT_DR_DETAILS))
- fprintf (vect_dump, "dependence distance = %d.", dist);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "dependence distance = %d.", dist);
/* Same loop iteration. */
if (dist == 0
@@ -2113,14 +2159,15 @@ vect_find_same_alignment_drs (struct data_dependence_relation *ddr,
/* Two references with distance zero have the same alignment. */
VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_a), drb);
VEC_safe_push (dr_p, heap, STMT_VINFO_SAME_ALIGN_REFS (stmtinfo_b), dra);
- if (vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "accesses have the same alignment.");
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "dependence distance modulo vf == 0 between ");
- print_generic_expr (vect_dump, DR_REF (dra), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (drb), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "accesses have the same alignment.");
+ dump_printf (MSG_NOTE,
+ "dependence distance modulo vf == 0 between ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dra));
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (drb));
}
}
}
@@ -2136,8 +2183,9 @@ bool
vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo,
bb_vec_info bb_vinfo)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_analyze_data_refs_alignment ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_analyze_data_refs_alignment ===");
/* Mark groups of data references with same alignment using
data dependence information. */
@@ -2153,9 +2201,10 @@ vect_analyze_data_refs_alignment (loop_vec_info loop_vinfo,
if (!vect_compute_data_refs_alignment (loop_vinfo, bb_vinfo))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump,
- "not vectorized: can't calculate alignment for data ref.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: can't calculate alignment "
+ "for data ref.");
return false;
}
@@ -2205,24 +2254,27 @@ vect_analyze_group_access (struct data_reference *dr)
{
GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = stmt;
GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize;
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Detected single element interleaving ");
- print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
- fprintf (vect_dump, " step ");
- print_generic_expr (vect_dump, step, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Detected single element interleaving ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (dr));
+ dump_printf (MSG_NOTE, " step ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, step);
}
if (loop_vinfo)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Data access with gaps requires scalar "
- "epilogue loop");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Data access with gaps requires scalar "
+ "epilogue loop");
if (loop->inner)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Peeling for outer loop is not"
- " supported");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Peeling for outer loop is not"
+ " supported");
return false;
}
@@ -2232,10 +2284,11 @@ vect_analyze_group_access (struct data_reference *dr)
return true;
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not consecutive access ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not consecutive access ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
if (bb_vinfo)
@@ -2244,7 +2297,7 @@ vect_analyze_group_access (struct data_reference *dr)
STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr))) = false;
return true;
}
-
+
return false;
}
@@ -2271,8 +2324,9 @@ vect_analyze_group_access (struct data_reference *dr)
{
if (DR_IS_WRITE (data_ref))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Two store stmts share the same dr.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Two store stmts share the same dr.");
return false;
}
@@ -2281,9 +2335,9 @@ vect_analyze_group_access (struct data_reference *dr)
if (GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (next))
|| GROUP_READ_WRITE_DEPENDENCE (vinfo_for_stmt (prev)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump,
- "READ_WRITE dependence in interleaving.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "READ_WRITE dependence in interleaving.");
return false;
}
@@ -2301,8 +2355,9 @@ vect_analyze_group_access (struct data_reference *dr)
next_step = DR_STEP (STMT_VINFO_DATA_REF (vinfo_for_stmt (next)));
if (tree_int_cst_compare (step, next_step))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "not consecutive access in interleaving");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not consecutive access in interleaving");
return false;
}
@@ -2317,8 +2372,9 @@ vect_analyze_group_access (struct data_reference *dr)
slp_impossible = true;
if (DR_IS_WRITE (data_ref))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "interleaved store with gaps");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "interleaved store with gaps");
return false;
}
@@ -2345,10 +2401,11 @@ vect_analyze_group_access (struct data_reference *dr)
greater than STEP. */
if (dr_step && dr_step < count_in_bytes + gaps * type_size)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "interleaving size is greater than step for ");
- print_generic_expr (vect_dump, DR_REF (dr), TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "interleaving size is greater than step for ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, DR_REF (dr));
}
return false;
}
@@ -2367,8 +2424,9 @@ vect_analyze_group_access (struct data_reference *dr)
}
else
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "interleaved store with gaps");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "interleaved store with gaps");
return false;
}
}
@@ -2376,13 +2434,14 @@ vect_analyze_group_access (struct data_reference *dr)
/* Check that STEP is a multiple of type size. */
if (dr_step && (dr_step % type_size) != 0)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "step is not a multiple of type size: step ");
- print_generic_expr (vect_dump, step, TDF_SLIM);
- fprintf (vect_dump, " size ");
- print_generic_expr (vect_dump, TYPE_SIZE_UNIT (scalar_type),
- TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "step is not a multiple of type size: step ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, step);
+ dump_printf (MSG_MISSED_OPTIMIZATION, " size ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ TYPE_SIZE_UNIT (scalar_type));
}
return false;
}
@@ -2391,8 +2450,9 @@ vect_analyze_group_access (struct data_reference *dr)
groupsize = count;
GROUP_SIZE (vinfo_for_stmt (stmt)) = groupsize;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Detected interleaving of size %d", (int)groupsize);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Detected interleaving of size %d", (int)groupsize);
/* SLP: create an SLP data structure for every interleaving group of
stores for further analysis in vect_analyse_slp. */
@@ -2409,13 +2469,15 @@ vect_analyze_group_access (struct data_reference *dr)
/* There is a gap in the end of the group. */
if (groupsize - last_accessed_element > 0 && loop_vinfo)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Data access with gaps requires scalar "
- "epilogue loop");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Data access with gaps requires scalar "
+ "epilogue loop");
if (loop->inner)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Peeling for outer loop is not supported");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Peeling for outer loop is not supported");
return false;
}
@@ -2446,8 +2508,9 @@ vect_analyze_data_ref_access (struct data_reference *dr)
if (loop_vinfo && !step)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad data-ref access in loop");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad data-ref access in loop");
return false;
}
@@ -2468,8 +2531,9 @@ vect_analyze_data_ref_access (struct data_reference *dr)
step = STMT_VINFO_DR_STEP (stmt_info);
if (integer_zerop (step))
{
- if (vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "zero step in outer loop.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "zero step in outer loop.");
if (DR_IS_READ (dr))
return true;
else
@@ -2493,8 +2557,9 @@ vect_analyze_data_ref_access (struct data_reference *dr)
if (loop && nested_in_vect_loop_p (loop, stmt))
{
- if (vect_print_dump_info (REPORT_ALIGNMENT))
- fprintf (vect_dump, "grouped access in outer loop.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "grouped access in outer loop.");
return false;
}
@@ -2523,8 +2588,9 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
VEC (data_reference_p, heap) *datarefs;
struct data_reference *dr;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_analyze_data_ref_accesses ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_analyze_data_ref_accesses ===");
if (loop_vinfo)
datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
@@ -2535,8 +2601,9 @@ vect_analyze_data_ref_accesses (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
if (STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (DR_STMT (dr)))
&& !vect_analyze_data_ref_access (dr))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: complicated access pattern.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: complicated access pattern.");
if (bb_vinfo)
{
@@ -2564,8 +2631,9 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo);
unsigned i, j;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_prune_runtime_alias_test_list ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_prune_runtime_alias_test_list ===");
for (i = 0; i < VEC_length (ddr_p, ddrs); )
{
@@ -2581,16 +2649,17 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
if (vect_vfa_range_equal (ddr_i, ddr_j))
{
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "found equal ranges ");
- print_generic_expr (vect_dump, DR_REF (DDR_A (ddr_i)), TDF_SLIM);
- fprintf (vect_dump, ", ");
- print_generic_expr (vect_dump, DR_REF (DDR_B (ddr_i)), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (DDR_A (ddr_j)), TDF_SLIM);
- fprintf (vect_dump, ", ");
- print_generic_expr (vect_dump, DR_REF (DDR_B (ddr_j)), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "found equal ranges ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_A (ddr_i)));
+ dump_printf (MSG_NOTE, ", ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_B (ddr_i)));
+ dump_printf (MSG_NOTE, " and ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_A (ddr_j)));
+ dump_printf (MSG_NOTE, ", ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, DR_REF (DDR_B (ddr_j)));
}
found = true;
break;
@@ -2608,11 +2677,11 @@ vect_prune_runtime_alias_test_list (loop_vec_info loop_vinfo)
if (VEC_length (ddr_p, ddrs) >
(unsigned) PARAM_VALUE (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS))
{
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "disable versioning for alias - max number of generated "
- "checks exceeded.");
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "disable versioning for alias - max number of "
+ "generated checks exceeded.");
}
VEC_truncate (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo), 0);
@@ -2895,8 +2964,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
tree scalar_type;
bool res, stop_bb_analysis = false;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_analyze_data_refs ===\n");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_analyze_data_refs ===\n");
if (loop_vinfo)
{
@@ -2909,9 +2979,10 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (!res)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: loop contains function calls"
- " or data references that cannot be analyzed");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: loop contains function calls"
+ " or data references that cannot be analyzed");
return false;
}
@@ -2940,9 +3011,11 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (!compute_all_dependences (BB_VINFO_DATAREFS (bb_vinfo),
&BB_VINFO_DDRS (bb_vinfo), NULL, true))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: basic block contains function"
- " calls or data references that cannot be analyzed");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: basic block contains function"
+ " calls or data references that cannot be"
+ " analyzed");
return false;
}
@@ -2962,9 +3035,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (!dr || !DR_REF (dr))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: unhandled data-ref ");
-
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unhandled data-ref ");
return false;
}
@@ -3008,11 +3081,12 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (!gather)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: data ref analysis "
- "failed ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: data ref analysis "
+ "failed ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
if (bb_vinfo)
@@ -3028,9 +3102,10 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (TREE_CODE (DR_BASE_ADDRESS (dr)) == INTEGER_CST)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: base addr of dr is a "
- "constant");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: base addr of dr is a "
+ "constant");
if (bb_vinfo)
{
@@ -3046,10 +3121,11 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (TREE_THIS_VOLATILE (DR_REF (dr)))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: volatile type ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: volatile type ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
if (bb_vinfo)
@@ -3064,11 +3140,12 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (stmt_can_throw_internal (stmt))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: statement can throw an "
- "exception ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: statement can throw an "
+ "exception ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
if (bb_vinfo)
@@ -3086,11 +3163,12 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (TREE_CODE (DR_REF (dr)) == COMPONENT_REF
&& DECL_BIT_FIELD (TREE_OPERAND (DR_REF (dr), 1)))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: statement is bitfield "
- "access ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: statement is bitfield "
+ "access ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
if (bb_vinfo)
@@ -3111,10 +3189,11 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (is_gimple_call (stmt))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: dr in a call ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: dr in a call ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
if (bb_vinfo)
@@ -3153,10 +3232,11 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
tree inner_base = build_fold_indirect_ref
(fold_build_pointer_plus (base, init));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "analyze in outer-loop: ");
- print_generic_expr (vect_dump, inner_base, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "analyze in outer-loop: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, inner_base);
}
outer_base = get_inner_reference (inner_base, &pbitsize, &pbitpos,
@@ -3165,8 +3245,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (pbitpos % BITS_PER_UNIT != 0)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "failed: bit offset alignment.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "failed: bit offset alignment.\n");
return false;
}
@@ -3174,8 +3255,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (!simple_iv (loop, loop_containing_stmt (stmt), outer_base,
&base_iv, false))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "failed: evolution of base is not affine.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "failed: evolution of base is not affine.\n");
return false;
}
@@ -3196,8 +3278,9 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
else if (!simple_iv (loop, loop_containing_stmt (stmt), poffset,
&offset_iv, false))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "evolution of offset is not affine.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "evolution of offset is not affine.\n");
return false;
}
@@ -3220,28 +3303,36 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
STMT_VINFO_DR_ALIGNED_TO (stmt_info) =
size_int (highest_pow2_factor (offset_iv.base));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "\touter base_address: ");
- print_generic_expr (vect_dump, STMT_VINFO_DR_BASE_ADDRESS (stmt_info), TDF_SLIM);
- fprintf (vect_dump, "\n\touter offset from base address: ");
- print_generic_expr (vect_dump, STMT_VINFO_DR_OFFSET (stmt_info), TDF_SLIM);
- fprintf (vect_dump, "\n\touter constant offset from base address: ");
- print_generic_expr (vect_dump, STMT_VINFO_DR_INIT (stmt_info), TDF_SLIM);
- fprintf (vect_dump, "\n\touter step: ");
- print_generic_expr (vect_dump, STMT_VINFO_DR_STEP (stmt_info), TDF_SLIM);
- fprintf (vect_dump, "\n\touter aligned to: ");
- print_generic_expr (vect_dump, STMT_VINFO_DR_ALIGNED_TO (stmt_info), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "\touter base_address: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ STMT_VINFO_DR_BASE_ADDRESS (stmt_info));
+ dump_printf (MSG_NOTE, "\n\touter offset from base address: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ STMT_VINFO_DR_OFFSET (stmt_info));
+ dump_printf (MSG_NOTE,
+ "\n\touter constant offset from base address: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ STMT_VINFO_DR_INIT (stmt_info));
+ dump_printf (MSG_NOTE, "\n\touter step: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ STMT_VINFO_DR_STEP (stmt_info));
+ dump_printf (MSG_NOTE, "\n\touter aligned to: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ STMT_VINFO_DR_ALIGNED_TO (stmt_info));
}
}
if (STMT_VINFO_DATA_REF (stmt_info))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: more than one data ref in stmt: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: more than one data ref "
+ "in stmt: ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
if (bb_vinfo)
@@ -3264,13 +3355,14 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
get_vectype_for_scalar_type (scalar_type);
if (!STMT_VINFO_VECTYPE (stmt_info))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: no vectype for stmt: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
- fprintf (vect_dump, " scalar_type: ");
- print_generic_expr (vect_dump, scalar_type, TDF_DETAILS);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: no vectype for stmt: ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+ dump_printf (MSG_MISSED_OPTIMIZATION, " scalar_type: ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_DETAILS,
+ scalar_type);
}
if (bb_vinfo)
@@ -3314,11 +3406,12 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
{
STMT_VINFO_DATA_REF (stmt_info) = NULL;
free_data_ref (dr);
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: not suitable for gather load ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: not suitable for gather "
+ "load ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
}
@@ -3366,12 +3459,12 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
if (bad)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: data dependence conflict"
- " prevents gather load");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: data dependence conflict"
+ " prevents gather load");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
}
@@ -3387,11 +3480,12 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
= vect_check_strided_load (stmt, loop_vinfo, NULL, NULL);
if (!strided_load)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: not suitable for strided load ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: not suitable for strided "
+ "load ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
}
@@ -3574,10 +3668,10 @@ vect_create_addr_base_for_vector_ref (gimple stmt,
mark_ptr_info_alignment_unknown (SSA_NAME_PTR_INFO (vec_stmt));
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "created ");
- print_generic_expr (vect_dump, vec_stmt, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "created ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, vec_stmt);
}
return vec_stmt;
@@ -3696,20 +3790,21 @@ vect_create_data_ref_ptr (gimple stmt, tree aggr_type, struct loop *at_loop,
in LOOP. */
base_name = build_fold_indirect_ref (unshare_expr (DR_BASE_ADDRESS (dr)));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
tree data_ref_base = base_name;
- fprintf (vect_dump, "create %s-pointer variable to type: ",
- tree_code_name[(int) TREE_CODE (aggr_type)]);
- print_generic_expr (vect_dump, aggr_type, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "create %s-pointer variable to type: ",
+ tree_code_name[(int) TREE_CODE (aggr_type)]);
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, aggr_type);
if (TREE_CODE (data_ref_base) == VAR_DECL
|| TREE_CODE (data_ref_base) == ARRAY_REF)
- fprintf (vect_dump, " vectorizing an array ref: ");
+ dump_printf (MSG_NOTE, " vectorizing an array ref: ");
else if (TREE_CODE (data_ref_base) == COMPONENT_REF)
- fprintf (vect_dump, " vectorizing a record based array ref: ");
+ dump_printf (MSG_NOTE, " vectorizing a record based array ref: ");
else if (TREE_CODE (data_ref_base) == SSA_NAME)
- fprintf (vect_dump, " vectorizing a pointer ref: ");
- print_generic_expr (vect_dump, base_name, TDF_SLIM);
+ dump_printf (MSG_NOTE, " vectorizing a pointer ref: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, base_name);
}
/* (1) Create the new aggregate-pointer variable. */
@@ -4025,9 +4120,10 @@ vect_grouped_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
/* vect_permute_store_chain requires the group size to be a power of two. */
if (exact_log2 (count) == -1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "the size of the group of accesses"
- " is not a power of 2");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "the size of the group of accesses"
+ " is not a power of 2");
return false;
}
@@ -4050,8 +4146,9 @@ vect_grouped_store_supported (tree vectype, unsigned HOST_WIDE_INT count)
}
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "interleave op not supported by target.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf (MSG_MISSED_OPTIMIZATION,
+ "interleave op not supported by target.");
return false;
}
@@ -4467,9 +4564,10 @@ vect_grouped_load_supported (tree vectype, unsigned HOST_WIDE_INT count)
/* vect_permute_load_chain requires the group size to be a power of two. */
if (exact_log2 (count) == -1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "the size of the group of accesses"
- " is not a power of 2");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "the size of the group of accesses"
+ " is not a power of 2");
return false;
}
@@ -4490,8 +4588,9 @@ vect_grouped_load_supported (tree vectype, unsigned HOST_WIDE_INT count)
}
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "extract even/odd not supported by target");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "extract even/odd not supported by target");
return false;
}
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index f48095344..a91dd910b 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "dumpfile.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
@@ -791,14 +792,13 @@ slpeel_make_loop_iterate_ntimes (struct loop *loop, tree niters)
free_stmt_vec_info (orig_cond);
loop_loc = find_loop_location (loop);
- if (dump_file && (dump_flags & TDF_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- if (loop_loc != UNKNOWN_LOC)
- fprintf (dump_file, "\nloop at %s:%d: ",
- LOC_FILE (loop_loc), LOC_LINE (loop_loc));
- print_gimple_stmt (dump_file, cond_stmt, 0, TDF_SLIM);
+ if (LOCATION_LOCUS (loop_loc) != UNKNOWN_LOC)
+ dump_printf (MSG_NOTE, "\nloop at %s:%d: ", LOC_FILE (loop_loc),
+ LOC_LINE (loop_loc));
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, cond_stmt, 0);
}
-
loop->nb_iterations = niters;
}
@@ -1246,13 +1246,8 @@ slpeel_tree_peel_loop_to_edge (struct loop *loop,
if (!(new_loop = slpeel_tree_duplicate_loop_to_edge_cfg (loop, e)))
{
loop_loc = find_loop_location (loop);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- if (loop_loc != UNKNOWN_LOC)
- fprintf (dump_file, "\n%s:%d: note: ",
- LOC_FILE (loop_loc), LOC_LINE (loop_loc));
- fprintf (dump_file, "tree_duplicate_loop_to_edge_cfg failed.\n");
- }
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, loop_loc,
+ "tree_duplicate_loop_to_edge_cfg failed.\n");
return NULL;
}
@@ -1688,19 +1683,18 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
/* Analyze phi functions of the loop header. */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_can_advance_ivs_p:");
-
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "vect_can_advance_ivs_p:");
for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
tree access_fn = NULL;
tree evolution_part;
phi = gsi_stmt (gsi);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Analyze phi: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "Analyze phi: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
}
/* Skip virtual phi's. The data dependences that are associated with
@@ -1708,8 +1702,9 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
if (virtual_operand_p (PHI_RESULT (phi)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "virtual phi. skip.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "virtual phi. skip.");
continue;
}
@@ -1717,8 +1712,9 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
if (STMT_VINFO_DEF_TYPE (vinfo_for_stmt (phi)) == vect_reduction_def)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "reduc phi. skip.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "reduc phi. skip.");
continue;
}
@@ -1729,23 +1725,25 @@ vect_can_advance_ivs_p (loop_vec_info loop_vinfo)
if (!access_fn)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "No Access function.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "No Access function.");
return false;
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Access function of PHI: ");
- print_generic_expr (vect_dump, access_fn, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Access function of PHI: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, access_fn);
}
evolution_part = evolution_part_in_loop_num (access_fn, loop->num);
if (evolution_part == NULL_TREE)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "No evolution.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf (MSG_MISSED_OPTIMIZATION, "No evolution.");
return false;
}
@@ -1829,17 +1827,19 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
phi = gsi_stmt (gsi);
phi1 = gsi_stmt (gsi1);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "vect_update_ivs_after_vectorizer: phi: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_update_ivs_after_vectorizer: phi: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
}
/* Skip virtual phi's. */
if (virtual_operand_p (PHI_RESULT (phi)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "virtual phi. skip.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "virtual phi. skip.");
continue;
}
@@ -1847,8 +1847,9 @@ vect_update_ivs_after_vectorizer (loop_vec_info loop_vinfo, tree niters,
stmt_info = vinfo_for_stmt (phi);
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_reduction_def)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "reduc phi. skip.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "reduc phi. skip.");
continue;
}
@@ -1909,8 +1910,9 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
tree cond_expr = NULL_TREE;
gimple_seq cond_expr_stmt_list = NULL;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_do_peeling_for_loop_bound ===");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "=== vect_do_peeling_for_loop_bound ===");
initialize_original_copy_tables ();
@@ -1956,9 +1958,9 @@ vect_do_peeling_for_loop_bound (loop_vec_info loop_vinfo, tree *ratio,
if (check_profitability)
max_iter = MAX (max_iter, (int) th);
record_niter_bound (new_loop, double_int::from_shwi (max_iter), false, true);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Setting upper bound of nb iterations for epilogue "
- "loop to %d\n", max_iter);
+ dump_printf (MSG_OPTIMIZED_LOCATIONS,
+ "Setting upper bound of nb iterations for epilogue "
+ "loop to %d\n", max_iter);
/* After peeling we have to reset scalar evolution analyzer. */
scev_reset ();
@@ -2020,8 +2022,9 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters, int
{
int npeel = LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "known peeling = %d.", npeel);
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "known peeling = %d.", npeel);
iters = build_int_cst (niters_type, npeel);
*bound = LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo);
@@ -2073,10 +2076,11 @@ vect_gen_niters_for_prolog_loop (loop_vec_info loop_vinfo, tree loop_niters, int
if (TREE_CODE (loop_niters) != INTEGER_CST)
iters = fold_build2 (MIN_EXPR, niters_type, iters, loop_niters);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
{
- fprintf (vect_dump, "niters for prolog loop: ");
- print_generic_expr (vect_dump, iters, TDF_SLIM);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "niters for prolog loop: ");
+ dump_generic_expr (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, iters);
}
var = create_tmp_var (niters_type, "prolog_loop_niters");
@@ -2129,9 +2133,10 @@ vect_update_inits_of_drs (loop_vec_info loop_vinfo, tree niters)
unsigned int i;
VEC (data_reference_p, heap) *datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
struct data_reference *dr;
-
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_update_inits_of_dr ===");
+
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "=== vect_update_inits_of_dr ===");
FOR_EACH_VEC_ELT (data_reference_p, datarefs, i, dr)
vect_update_init_of_dr (dr, niters);
@@ -2158,8 +2163,9 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo,
int max_iter;
int bound = 0;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_do_peeling_for_alignment ===");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "=== vect_do_peeling_for_alignment ===");
initialize_original_copy_tables ();
@@ -2184,9 +2190,9 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo,
if (check_profitability)
max_iter = MAX (max_iter, (int) th);
record_niter_bound (new_loop, double_int::from_shwi (max_iter), false, true);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Setting upper bound of nb iterations for prologue "
- "loop to %d\n", max_iter);
+ dump_printf (MSG_OPTIMIZED_LOCATIONS,
+ "Setting upper bound of nb iterations for prologue "
+ "loop to %d\n", max_iter);
/* Update number of times loop executes. */
n_iters = LOOP_VINFO_NITERS (loop_vinfo);
@@ -2469,13 +2475,13 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
segment_length_a = vect_vfa_segment_size (dr_a, length_factor);
segment_length_b = vect_vfa_segment_size (dr_b, length_factor);
- if (vect_print_dump_info (REPORT_DR_DETAILS))
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
{
- fprintf (vect_dump,
- "create runtime check for data references ");
- print_generic_expr (vect_dump, DR_REF (dr_a), TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, DR_REF (dr_b), TDF_SLIM);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "create runtime check for data references ");
+ dump_generic_expr (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, DR_REF (dr_a));
+ dump_printf (MSG_OPTIMIZED_LOCATIONS, " and ");
+ dump_generic_expr (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, DR_REF (dr_b));
}
seg_a_min = addr_base_a;
@@ -2500,9 +2506,10 @@ vect_create_cond_for_alias_checks (loop_vec_info loop_vinfo,
*cond_expr = part_cond_expr;
}
- if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
- fprintf (vect_dump, "created %u versioning for alias checks.\n",
- VEC_length (ddr_p, may_alias_ddrs));
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "created %u versioning for alias checks.\n",
+ VEC_length (ddr_p, may_alias_ddrs));
}
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 728bc0f09..58edfcbe4 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "dumpfile.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
@@ -139,6 +140,8 @@ along with GCC; see the file COPYING3. If not see
http://gcc.gnu.org/projects/tree-ssa/vectorization.html
*/
+static void vect_estimate_min_profitable_iters (loop_vec_info, int *, int *);
+
/* Function vect_determine_vectorization_factor
Determine the vectorization factor (VF). VF is the number of data elements
@@ -184,8 +187,9 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
gimple_stmt_iterator pattern_def_si = gsi_none ();
bool analyze_pattern_stmt = false;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_determine_vectorization_factor ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_determine_vectorization_factor ===");
for (i = 0; i < nbbs; i++)
{
@@ -195,10 +199,10 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
{
phi = gsi_stmt (si);
stmt_info = vinfo_for_stmt (phi);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> examining phi: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "==> examining phi: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
}
gcc_assert (stmt_info);
@@ -208,34 +212,37 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
gcc_assert (!STMT_VINFO_VECTYPE (stmt_info));
scalar_type = TREE_TYPE (PHI_RESULT (phi));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "get vectype for scalar type: ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "get vectype for scalar type: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type);
}
vectype = get_vectype_for_scalar_type (scalar_type);
if (!vectype)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: unsupported data-type ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported "
+ "data-type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ scalar_type);
}
return false;
}
STMT_VINFO_VECTYPE (stmt_info) = vectype;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "vectype: ");
- print_generic_expr (vect_dump, vectype, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "vectype: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, vectype);
}
nunits = TYPE_VECTOR_SUBPARTS (vectype);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "nunits = %d", nunits);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "nunits = %d", nunits);
if (!vectorization_factor
|| (nunits > vectorization_factor))
@@ -254,10 +261,11 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
stmt_info = vinfo_for_stmt (stmt);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> examining statement: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "==> examining statement: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
gcc_assert (stmt_info);
@@ -273,16 +281,17 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
{
stmt = pattern_stmt;
stmt_info = vinfo_for_stmt (pattern_stmt);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> examining pattern statement: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "==> examining pattern statement: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
}
else
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "skip.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "skip.");
gsi_next (&si);
continue;
}
@@ -321,12 +330,12 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
if (!gsi_end_p (pattern_def_si))
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump,
- "==> examining pattern def stmt: ");
- print_gimple_stmt (vect_dump, pattern_def_stmt, 0,
- TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "==> examining pattern def stmt: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM,
+ pattern_def_stmt, 0);
}
stmt = pattern_def_stmt;
@@ -344,20 +353,23 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
if (gimple_get_lhs (stmt) == NULL_TREE)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: irregular stmt.");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: irregular stmt.");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt,
+ 0);
}
return false;
}
if (VECTOR_MODE_P (TYPE_MODE (gimple_expr_type (stmt))))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: vector stmt in loop:");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: vector stmt in loop:");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
}
@@ -377,19 +389,22 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
{
gcc_assert (!STMT_VINFO_DATA_REF (stmt_info));
scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "get vectype for scalar type: ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "get vectype for scalar type: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type);
}
vectype = get_vectype_for_scalar_type (scalar_type);
if (!vectype)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: unsupported data-type ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported "
+ "data-type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ scalar_type);
}
return false;
}
@@ -402,19 +417,21 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
support one vector size per loop). */
scalar_type = vect_get_smallest_scalar_type (stmt, &dummy,
&dummy);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "get vectype for scalar type: ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "get vectype for scalar type: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type);
}
vf_vectype = get_vectype_for_scalar_type (scalar_type);
if (!vf_vectype)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: unsupported data-type ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported data-type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ scalar_type);
}
return false;
}
@@ -422,28 +439,29 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
if ((GET_MODE_SIZE (TYPE_MODE (vectype))
!= GET_MODE_SIZE (TYPE_MODE (vf_vectype))))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: different sized vector "
- "types in statement, ");
- print_generic_expr (vect_dump, vectype, TDF_SLIM);
- fprintf (vect_dump, " and ");
- print_generic_expr (vect_dump, vf_vectype, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: different sized vector "
+ "types in statement, ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ vectype);
+ dump_printf (MSG_MISSED_OPTIMIZATION, " and ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ vf_vectype);
}
return false;
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "vectype: ");
- print_generic_expr (vect_dump, vf_vectype, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "vectype: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, vf_vectype);
}
nunits = TYPE_VECTOR_SUBPARTS (vf_vectype);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "nunits = %d", nunits);
-
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "nunits = %d", nunits);
if (!vectorization_factor
|| (nunits > vectorization_factor))
vectorization_factor = nunits;
@@ -457,12 +475,14 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
}
/* TODO: Analyze cost. Decide if worth while to vectorize. */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vectorization factor = %d", vectorization_factor);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "vectorization factor = %d",
+ vectorization_factor);
if (vectorization_factor <= 1)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: unsupported data-type");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported data-type");
return false;
}
LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
@@ -497,12 +517,12 @@ vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init,
step_expr = evolution_part;
init_expr = unshare_expr (initial_condition_in_loop_num (access_fn, loop_nb));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "step: ");
- print_generic_expr (vect_dump, step_expr, TDF_SLIM);
- fprintf (vect_dump, ", init: ");
- print_generic_expr (vect_dump, init_expr, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "step: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, step_expr);
+ dump_printf (MSG_NOTE, ", init: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, init_expr);
}
*init = init_expr;
@@ -510,8 +530,9 @@ vect_is_simple_iv_evolution (unsigned loop_nb, tree access_fn, tree * init,
if (TREE_CODE (step_expr) != INTEGER_CST)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "step unknown.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "step unknown.");
return false;
}
@@ -534,8 +555,9 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
gimple_stmt_iterator gsi;
bool double_reduc;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_analyze_scalar_cycles ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_analyze_scalar_cycles ===");
/* First - identify all inductions. Reduction detection assumes that all the
inductions have been identified, therefore, this order must not be
@@ -547,10 +569,10 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
tree def = PHI_RESULT (phi);
stmt_vec_info stmt_vinfo = vinfo_for_stmt (phi);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Analyze phi: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "Analyze phi: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
}
/* Skip virtual phi's. The data dependences that are associated with
@@ -565,10 +587,11 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
if (access_fn)
{
STRIP_NOPS (access_fn);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Access function of PHI: ");
- print_generic_expr (vect_dump, access_fn, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Access function of PHI: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, access_fn);
}
STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo)
= evolution_part_in_loop_num (access_fn, loop->num);
@@ -583,8 +606,8 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
gcc_assert (STMT_VINFO_LOOP_PHI_EVOLUTION_PART (stmt_vinfo) != NULL_TREE);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Detected induction.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "Detected induction.");
STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_induction_def;
}
@@ -598,10 +621,10 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
gimple reduc_stmt;
bool nested_cycle;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Analyze phi: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "Analyze phi: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
}
gcc_assert (!virtual_operand_p (def)
@@ -614,8 +637,9 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
{
if (double_reduc)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Detected double reduction.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Detected double reduction.");
STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_double_reduction_def;
STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
@@ -625,8 +649,9 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
{
if (nested_cycle)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Detected vectorizable nested cycle.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Detected vectorizable nested cycle.");
STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_nested_cycle;
STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
@@ -634,8 +659,9 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
}
else
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Detected reduction.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Detected reduction.");
STMT_VINFO_DEF_TYPE (stmt_vinfo) = vect_reduction_def;
STMT_VINFO_DEF_TYPE (vinfo_for_stmt (reduc_stmt)) =
@@ -649,8 +675,9 @@ vect_analyze_scalar_cycles_1 (loop_vec_info loop_vinfo, struct loop *loop)
}
}
else
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Unknown def-use cycle pattern.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Unknown def-use cycle pattern.");
}
VEC_free (gimple, heap, worklist);
@@ -710,9 +737,9 @@ vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
{
tree niters;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== get_loop_niters ===");
-
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== get_loop_niters ===");
niters = number_of_exit_cond_executions (loop);
if (niters != NULL_TREE
@@ -720,10 +747,10 @@ vect_get_loop_niters (struct loop *loop, tree *number_of_iterations)
{
*number_of_iterations = niters;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> get_loop_niters:" );
- print_generic_expr (vect_dump, *number_of_iterations, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "==> get_loop_niters:");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, *number_of_iterations);
}
}
@@ -968,16 +995,18 @@ vect_analyze_loop_1 (struct loop *loop)
{
loop_vec_info loop_vinfo;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "===== analyze_loop_nest_1 =====");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "===== analyze_loop_nest_1 =====");
/* Check the CFG characteristics of the loop (nesting, entry/exit, etc. */
loop_vinfo = vect_analyze_loop_form (loop);
if (!loop_vinfo)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad inner-loop form.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad inner-loop form.");
return NULL;
}
@@ -1001,8 +1030,9 @@ vect_analyze_loop_form (struct loop *loop)
tree number_of_iterations = NULL;
loop_vec_info inner_loop_vinfo = NULL;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_analyze_loop_form ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_analyze_loop_form ===");
/* Different restrictions apply when we are considering an inner-most loop,
vs. an outer (nested) loop.
@@ -1024,15 +1054,17 @@ vect_analyze_loop_form (struct loop *loop)
if (loop->num_nodes != 2)
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: control flow in loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: control flow in loop.");
return NULL;
}
if (empty_block_p (loop->header))
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: empty loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: empty loop.");
return NULL;
}
}
@@ -1060,8 +1092,9 @@ vect_analyze_loop_form (struct loop *loop)
if ((loop->inner)->inner || (loop->inner)->next)
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: multiple nested loops.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: multiple nested loops.");
return NULL;
}
@@ -1069,25 +1102,27 @@ vect_analyze_loop_form (struct loop *loop)
inner_loop_vinfo = vect_analyze_loop_1 (loop->inner);
if (!inner_loop_vinfo)
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: Bad inner loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: Bad inner loop.");
return NULL;
}
if (!expr_invariant_in_loop_p (loop,
LOOP_VINFO_NITERS (inner_loop_vinfo)))
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump,
- "not vectorized: inner-loop count not invariant.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: inner-loop count not invariant.");
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
}
if (loop->num_nodes != 5)
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: control flow in loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: control flow in loop.");
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
}
@@ -1101,25 +1136,29 @@ vect_analyze_loop_form (struct loop *loop)
|| !single_exit (innerloop)
|| single_exit (innerloop)->dest != EDGE_PRED (loop->latch, 0)->src)
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: unsupported outerloop form.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported outerloop form.");
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Considering outer-loop vectorization.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Considering outer-loop vectorization.");
}
if (!single_exit (loop)
|| EDGE_COUNT (loop->header->preds) != 2)
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
if (!single_exit (loop))
- fprintf (vect_dump, "not vectorized: multiple exits.");
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: multiple exits.");
else if (EDGE_COUNT (loop->header->preds) != 2)
- fprintf (vect_dump, "not vectorized: too many incoming edges.");
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: too many incoming edges.");
}
if (inner_loop_vinfo)
destroy_loop_vec_info (inner_loop_vinfo, true);
@@ -1133,8 +1172,9 @@ vect_analyze_loop_form (struct loop *loop)
if (!empty_block_p (loop->latch)
|| !gimple_seq_empty_p (phi_nodes (loop->latch)))
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: unexpected loop form.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unexpected loop form.");
if (inner_loop_vinfo)
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
@@ -1147,13 +1187,14 @@ vect_analyze_loop_form (struct loop *loop)
if (!(e->flags & EDGE_ABNORMAL))
{
split_loop_exit_edge (e);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "split exit edge.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf (MSG_NOTE, "split exit edge.");
}
else
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: abnormal loop exit edge.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: abnormal loop exit edge.");
if (inner_loop_vinfo)
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
@@ -1163,8 +1204,9 @@ vect_analyze_loop_form (struct loop *loop)
loop_cond = vect_get_loop_niters (loop, &number_of_iterations);
if (!loop_cond)
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "not vectorized: complicated exit condition.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: complicated exit condition.");
if (inner_loop_vinfo)
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
@@ -1172,9 +1214,10 @@ vect_analyze_loop_form (struct loop *loop)
if (!number_of_iterations)
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump,
- "not vectorized: number of iterations cannot be computed.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: number of iterations cannot be "
+ "computed.");
if (inner_loop_vinfo)
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
@@ -1182,8 +1225,9 @@ vect_analyze_loop_form (struct loop *loop)
if (chrec_contains_undetermined (number_of_iterations))
{
- if (vect_print_dump_info (REPORT_BAD_FORM_LOOPS))
- fprintf (vect_dump, "Infinite number of iterations.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Infinite number of iterations.");
if (inner_loop_vinfo)
destroy_loop_vec_info (inner_loop_vinfo, true);
return NULL;
@@ -1191,16 +1235,18 @@ vect_analyze_loop_form (struct loop *loop)
if (!NITERS_KNOWN_P (number_of_iterations))
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Symbolic number of iterations is ");
- print_generic_expr (vect_dump, number_of_iterations, TDF_DETAILS);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Symbolic number of iterations is ");
+ dump_generic_expr (MSG_NOTE, TDF_DETAILS, number_of_iterations);
}
}
else if (TREE_INT_CST_LOW (number_of_iterations) == 0)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: number of iterations = 0.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: number of iterations = 0.");
if (inner_loop_vinfo)
destroy_loop_vec_info (inner_loop_vinfo, false);
return NULL;
@@ -1243,9 +1289,12 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
unsigned int th;
bool only_slp_in_loop = true, ok;
HOST_WIDE_INT max_niter;
+ HOST_WIDE_INT estimated_niter;
+ int min_profitable_estimate;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_analyze_loop_operations ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_analyze_loop_operations ===");
gcc_assert (LOOP_VINFO_VECT_FACTOR (loop_vinfo));
vectorization_factor = LOOP_VINFO_VECT_FACTOR (loop_vinfo);
@@ -1279,9 +1328,10 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo));
LOOP_VINFO_VECT_FACTOR (loop_vinfo) = vectorization_factor;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Updating vectorization factor to %d ",
- vectorization_factor);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Updating vectorization factor to %d ",
+ vectorization_factor);
}
for (i = 0; i < nbbs; i++)
@@ -1294,10 +1344,10 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
ok = true;
stmt_info = vinfo_for_stmt (phi);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "examining phi: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "examining phi: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
}
/* Inner-loop loop-closed exit phi in outer-loop vectorization
@@ -1313,9 +1363,10 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
&& STMT_VINFO_DEF_TYPE (stmt_info)
!= vect_double_reduction_def)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump,
- "Unsupported loop-closed phi in outer-loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Unsupported loop-closed phi in "
+ "outer-loop.");
return false;
}
@@ -1354,8 +1405,9 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
if (STMT_VINFO_LIVE_P (stmt_info))
{
/* FORNOW: not yet supported. */
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: value used after loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: value used after loop.");
return false;
}
@@ -1363,8 +1415,9 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
&& STMT_VINFO_DEF_TYPE (stmt_info) != vect_induction_def)
{
/* A scalar-dependence cycle that we don't support. */
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: scalar dependence cycle.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: scalar dependence cycle.");
return false;
}
@@ -1377,11 +1430,12 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
if (!ok)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "not vectorized: relevant phi not supported: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: relevant phi not "
+ "supported: ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, phi, 0);
}
return false;
}
@@ -1402,31 +1456,35 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
touching this loop. */
if (!need_to_vectorize)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump,
- "All the computation can be taken out of the loop.");
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump,
- "not vectorized: redundant loop. no profit to vectorize.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "All the computation can be taken out of the loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: redundant loop. no profit to "
+ "vectorize.");
return false;
}
if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
- && vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump,
- "vectorization_factor = %d, niters = " HOST_WIDE_INT_PRINT_DEC,
- vectorization_factor, LOOP_VINFO_INT_NITERS (loop_vinfo));
+ && dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vectorization_factor = %d, niters = "
+ HOST_WIDE_INT_PRINT_DEC, vectorization_factor,
+ LOOP_VINFO_INT_NITERS (loop_vinfo));
if ((LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& (LOOP_VINFO_INT_NITERS (loop_vinfo) < vectorization_factor))
|| ((max_niter = max_stmt_executions_int (loop)) != -1
&& (unsigned HOST_WIDE_INT) max_niter < vectorization_factor))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: iteration count too small.");
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump,"not vectorized: iteration count smaller than "
- "vectorization factor.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: iteration count too small.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: iteration count smaller than "
+ "vectorization factor.");
return false;
}
@@ -1436,22 +1494,26 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
vector stmts depends on VF. */
vect_update_slp_costs_according_to_vf (loop_vinfo);
- min_profitable_iters = vect_estimate_min_profitable_iters (loop_vinfo);
+ vect_estimate_min_profitable_iters (loop_vinfo, &min_profitable_iters,
+ &min_profitable_estimate);
LOOP_VINFO_COST_MODEL_MIN_ITERS (loop_vinfo) = min_profitable_iters;
if (min_profitable_iters < 0)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: vectorization not profitable.");
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "not vectorized: vector version will never be "
- "profitable.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: vectorization not profitable.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: vector version will never be "
+ "profitable.");
return false;
}
min_scalar_loop_bound = ((PARAM_VALUE (PARAM_MIN_VECT_LOOP_BOUND)
* vectorization_factor) - 1);
+
/* Use the cost model only if it is more conservative than user specified
threshold. */
@@ -1464,13 +1526,31 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
if (LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo)
&& LOOP_VINFO_INT_NITERS (loop_vinfo) <= th)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: vectorization not "
- "profitable.");
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "not vectorized: iteration count smaller than "
- "user specified loop bound parameter or minimum "
- "profitable iterations (whichever is more conservative).");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: vectorization not profitable.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "not vectorized: iteration count smaller than user "
+ "specified loop bound parameter or minimum profitable "
+ "iterations (whichever is more conservative).");
+ return false;
+ }
+
+ if ((estimated_niter = estimated_stmt_executions_int (loop)) != -1
+ && ((unsigned HOST_WIDE_INT) estimated_niter
+ <= MAX (th, (unsigned)min_profitable_estimate)))
+ {
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: estimated iteration count too "
+ "small.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "not vectorized: estimated iteration count smaller "
+ "than specified loop bound parameter or minimum "
+ "profitable iterations (whichever is more "
+ "conservative).");
return false;
}
@@ -1478,20 +1558,20 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
|| LOOP_VINFO_INT_NITERS (loop_vinfo) % vectorization_factor != 0
|| LOOP_PEELING_FOR_ALIGNMENT (loop_vinfo))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "epilog loop required.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "epilog loop required.");
if (!vect_can_advance_ivs_p (loop_vinfo))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump,
- "not vectorized: can't create epilog loop 1.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: can't create epilog loop 1.");
return false;
}
if (!slpeel_can_duplicate_loop_p (loop, single_exit (loop)))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump,
- "not vectorized: can't create epilog loop 2.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: can't create epilog loop 2.");
return false;
}
}
@@ -1522,8 +1602,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
ok = vect_analyze_data_refs (loop_vinfo, NULL, &min_vf);
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad data references.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad data references.");
return false;
}
@@ -1539,8 +1620,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
ok = vect_mark_stmts_to_be_vectorized (loop_vinfo);
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unexpected pattern.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unexpected pattern.");
return false;
}
@@ -1553,22 +1635,25 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
if (!ok
|| max_vf < min_vf)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad data dependence.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad data dependence.");
return false;
}
ok = vect_determine_vectorization_factor (loop_vinfo);
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "can't determine vectorization factor.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "can't determine vectorization factor.");
return false;
}
if (max_vf < LOOP_VINFO_VECT_FACTOR (loop_vinfo))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad data dependence.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad data dependence.");
return false;
}
@@ -1578,8 +1663,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
ok = vect_analyze_data_refs_alignment (loop_vinfo, NULL);
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad data alignment.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad data alignment.");
return false;
}
@@ -1589,8 +1675,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
ok = vect_analyze_data_ref_accesses (loop_vinfo, NULL);
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad data access.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad data access.");
return false;
}
@@ -1600,9 +1687,10 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
ok = vect_prune_runtime_alias_test_list (loop_vinfo);
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "too long list of versioning for alias "
- "run-time tests.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "too long list of versioning for alias "
+ "run-time tests.");
return false;
}
@@ -1612,8 +1700,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
ok = vect_enhance_data_refs_alignment (loop_vinfo);
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad data alignment.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad data alignment.");
return false;
}
@@ -1636,8 +1725,9 @@ vect_analyze_loop_2 (loop_vec_info loop_vinfo)
ok = vect_analyze_loop_operations (loop_vinfo, slp);
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad operation or unsupported loop bound.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad operation or unsupported loop bound.");
return false;
}
@@ -1659,15 +1749,17 @@ vect_analyze_loop (struct loop *loop)
current_vector_size = 0;
vector_sizes = targetm.vectorize.autovectorize_vector_sizes ();
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "===== analyze_loop_nest =====");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "===== analyze_loop_nest =====");
if (loop_outer (loop)
&& loop_vec_info_for_loop (loop_outer (loop))
&& LOOP_VINFO_VECTORIZABLE_P (loop_vec_info_for_loop (loop_outer (loop))))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "outer-loop already vectorized.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "outer-loop already vectorized.");
return NULL;
}
@@ -1677,8 +1769,9 @@ vect_analyze_loop (struct loop *loop)
loop_vinfo = vect_analyze_loop_form (loop);
if (!loop_vinfo)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bad loop form.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bad loop form.");
return NULL;
}
@@ -1698,9 +1791,10 @@ vect_analyze_loop (struct loop *loop)
/* Try the next biggest vector size. */
current_vector_size = 1 << floor_log2 (vector_sizes);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "***** Re-trying analysis with "
- "vector size %d\n", current_vector_size);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "***** Re-trying analysis with "
+ "vector size %d\n", current_vector_size);
}
}
@@ -1754,10 +1848,10 @@ reduction_code_for_scalar_code (enum tree_code code,
STMT is printed with a message MSG. */
static void
-report_vect_op (gimple stmt, const char *msg)
+report_vect_op (int msg_type, gimple stmt, const char *msg)
{
- fprintf (vect_dump, "%s", msg);
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (msg_type, vect_location, "%s", msg);
+ dump_gimple_stmt (msg_type, TDF_SLIM, stmt, 0);
}
@@ -1929,10 +2023,10 @@ vect_is_slp_reduction (loop_vec_info loop_info, gimple phi, gimple first_stmt)
== vect_internal_def
&& !is_loop_header_bb_p (gimple_bb (def_stmt)))))
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "swapping oprnds: ");
- print_gimple_stmt (vect_dump, next_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "swapping oprnds: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, next_stmt, 0);
}
swap_tree_operands (next_stmt,
@@ -2031,8 +2125,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "intermediate value used outside loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "intermediate value used outside loop.");
return NULL;
}
@@ -2042,18 +2137,20 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
nloop_uses++;
if (nloop_uses > 1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "reduction used in loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "reduction used in loop.");
return NULL;
}
}
if (TREE_CODE (loop_arg) != SSA_NAME)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "reduction: not ssa_name: ");
- print_generic_expr (vect_dump, loop_arg, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "reduction: not ssa_name: ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, loop_arg);
}
return NULL;
}
@@ -2061,15 +2158,16 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
def_stmt = SSA_NAME_DEF_STMT (loop_arg);
if (!def_stmt)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "reduction: no def_stmt.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "reduction: no def_stmt.");
return NULL;
}
if (!is_gimple_assign (def_stmt) && gimple_code (def_stmt) != GIMPLE_PHI)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- print_gimple_stmt (vect_dump, def_stmt, 0, TDF_SLIM);
+ if (dump_kind_p (MSG_NOTE))
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, def_stmt, 0);
return NULL;
}
@@ -2096,8 +2194,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
nloop_uses++;
if (nloop_uses > 1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "reduction used in loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "reduction used in loop.");
return NULL;
}
}
@@ -2111,8 +2210,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
if (gimple_phi_num_args (def_stmt) != 1
|| TREE_CODE (op1) != SSA_NAME)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unsupported phi node definition.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported phi node definition.");
return NULL;
}
@@ -2123,8 +2223,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
&& flow_bb_inside_loop_p (loop->inner, gimple_bb (def1))
&& is_gimple_assign (def1))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "detected double reduction: ");
+ if (dump_kind_p (MSG_NOTE))
+ report_vect_op (MSG_NOTE, def_stmt,
+ "detected double reduction: ");
*double_reduc = true;
return def_stmt;
@@ -2149,8 +2250,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
if (check_reduction
&& (!commutative_tree_code (code) || !associative_tree_code (code)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: not commutative/associative: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
+ "reduction: not commutative/associative: ");
return NULL;
}
@@ -2158,8 +2260,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
{
if (code != COND_EXPR)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: not binary operation: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
+ "reduction: not binary operation: ");
return NULL;
}
@@ -2176,8 +2279,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
if (TREE_CODE (op1) != SSA_NAME && TREE_CODE (op2) != SSA_NAME)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: uses not ssa_names: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
+ "reduction: uses not ssa_names: ");
return NULL;
}
@@ -2189,8 +2293,9 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
if (TREE_CODE (op1) != SSA_NAME && TREE_CODE (op2) != SSA_NAME)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: uses not ssa_names: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
+ "reduction: uses not ssa_names: ");
return NULL;
}
@@ -2206,24 +2311,29 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
|| (op4 && TREE_CODE (op4) == SSA_NAME
&& !types_compatible_p (type, TREE_TYPE (op4))))
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "reduction: multiple types: operation type: ");
- print_generic_expr (vect_dump, type, TDF_SLIM);
- fprintf (vect_dump, ", operands types: ");
- print_generic_expr (vect_dump, TREE_TYPE (op1), TDF_SLIM);
- fprintf (vect_dump, ",");
- print_generic_expr (vect_dump, TREE_TYPE (op2), TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "reduction: multiple types: operation type: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, type);
+ dump_printf (MSG_NOTE, ", operands types: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ TREE_TYPE (op1));
+ dump_printf (MSG_NOTE, ",");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ TREE_TYPE (op2));
if (op3)
{
- fprintf (vect_dump, ",");
- print_generic_expr (vect_dump, TREE_TYPE (op3), TDF_SLIM);
+ dump_printf (MSG_NOTE, ",");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ TREE_TYPE (op3));
}
if (op4)
{
- fprintf (vect_dump, ",");
- print_generic_expr (vect_dump, TREE_TYPE (op4), TDF_SLIM);
+ dump_printf (MSG_NOTE, ",");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM,
+ TREE_TYPE (op4));
}
}
@@ -2243,23 +2353,25 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
&& check_reduction)
{
/* Changing the order of operations changes the semantics. */
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: unsafe fp math optimization: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
+ "reduction: unsafe fp math optimization: ");
return NULL;
}
else if (INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_TRAPS (type)
&& check_reduction)
{
/* Changing the order of operations changes the semantics. */
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: unsafe int math optimization: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
+ "reduction: unsafe int math optimization: ");
return NULL;
}
else if (SAT_FIXED_POINT_TYPE_P (type) && check_reduction)
{
/* Changing the order of operations changes the semantics. */
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt,
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
"reduction: unsafe fixed-point math optimization: ");
return NULL;
}
@@ -2295,8 +2407,8 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
if (code != COND_EXPR
&& ((!def1 || gimple_nop_p (def1)) && (!def2 || gimple_nop_p (def2))))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: no defs for operands: ");
+ if (dump_kind_p (MSG_NOTE))
+ report_vect_op (MSG_NOTE, def_stmt, "reduction: no defs for operands: ");
return NULL;
}
@@ -2317,8 +2429,8 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
== vect_internal_def
&& !is_loop_header_bb_p (gimple_bb (def1)))))))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "detected reduction: ");
+ if (dump_kind_p (MSG_NOTE))
+ report_vect_op (MSG_NOTE, def_stmt, "detected reduction: ");
return def_stmt;
}
@@ -2340,8 +2452,8 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
/* Swap operands (just for simplicity - so that the rest of the code
can assume that the reduction variable is always the last (second)
argument). */
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt,
+ if (dump_kind_p (MSG_NOTE))
+ report_vect_op (MSG_NOTE, def_stmt,
"detected reduction: need to swap operands: ");
swap_tree_operands (def_stmt, gimple_assign_rhs1_ptr (def_stmt),
@@ -2352,8 +2464,8 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
}
else
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "detected reduction: ");
+ if (dump_kind_p (MSG_NOTE))
+ report_vect_op (MSG_NOTE, def_stmt, "detected reduction: ");
}
return def_stmt;
@@ -2362,14 +2474,16 @@ vect_is_simple_reduction_1 (loop_vec_info loop_info, gimple phi,
/* Try to find SLP reduction chain. */
if (check_reduction && vect_is_slp_reduction (loop_info, phi, def_stmt))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: detected reduction chain: ");
+ if (dump_kind_p (MSG_NOTE))
+ report_vect_op (MSG_NOTE, def_stmt,
+ "reduction: detected reduction chain: ");
return def_stmt;
}
- if (vect_print_dump_info (REPORT_DETAILS))
- report_vect_op (def_stmt, "reduction: unknown pattern: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ report_vect_op (MSG_MISSED_OPTIMIZATION, def_stmt,
+ "reduction: unknown pattern: ");
return NULL;
}
@@ -2475,10 +2589,10 @@ vect_get_known_peeling_cost (loop_vec_info loop_vinfo, int peel_iters_prologue,
if (!LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
{
*peel_iters_epilogue = vf/2;
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "cost model: "
- "epilogue peel iters set to vf/2 because "
- "loop iterations are unknown .");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "cost model: epilogue peel iters set to vf/2 "
+ "because loop iterations are unknown .");
/* If peeled iterations are known but number of scalar loop
iterations are unknown, count a taken branch per peeled loop. */
@@ -2512,15 +2626,15 @@ vect_get_known_peeling_cost (loop_vec_info loop_vinfo, int peel_iters_prologue,
Return the number of iterations required for the vector version of the
loop to be profitable relative to the cost of the scalar version of the
- loop.
-
- TODO: Take profile info into account before making vectorization
- decisions, if available. */
+ loop. */
-int
-vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
+static void
+vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo,
+ int *ret_min_profitable_niters,
+ int *ret_min_profitable_estimate)
{
int min_profitable_iters;
+ int min_profitable_estimate;
int peel_iters_prologue;
int peel_iters_epilogue;
unsigned vec_inside_cost = 0;
@@ -2536,9 +2650,10 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
/* Cost model disabled. */
if (!flag_vect_cost_model)
{
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "cost model disabled.");
- return 0;
+ dump_printf_loc (MSG_NOTE, vect_location, "cost model disabled.");
+ *ret_min_profitable_niters = 0;
+ *ret_min_profitable_estimate = 0;
+ return;
}
/* Requires loop versioning tests to handle misalignment. */
@@ -2549,9 +2664,9 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo));
(void) add_stmt_cost (target_cost_data, len, vector_stmt, NULL, 0,
vect_prologue);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "cost model: Adding cost of checks for loop "
- "versioning to treat misalignment.\n");
+ dump_printf (MSG_NOTE,
+ "cost model: Adding cost of checks for loop "
+ "versioning to treat misalignment.\n");
}
/* Requires loop versioning with alias checks. */
@@ -2561,9 +2676,9 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
unsigned len = VEC_length (ddr_p, LOOP_VINFO_MAY_ALIAS_DDRS (loop_vinfo));
(void) add_stmt_cost (target_cost_data, len, vector_stmt, NULL, 0,
vect_prologue);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "cost model: Adding cost of checks for loop "
- "versioning aliasing.\n");
+ dump_printf (MSG_NOTE,
+ "cost model: Adding cost of checks for loop "
+ "versioning aliasing.\n");
}
if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo)
@@ -2593,17 +2708,15 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
if (npeel < 0)
{
peel_iters_prologue = vf/2;
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "cost model: "
- "prologue peel iters set to vf/2.");
+ dump_printf (MSG_NOTE, "cost model: "
+ "prologue peel iters set to vf/2.");
/* If peeling for alignment is unknown, loop bound of main loop becomes
unknown. */
peel_iters_epilogue = vf/2;
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "cost model: "
- "epilogue peel iters set to vf/2 because "
- "peeling for alignment is unknown .");
+ dump_printf (MSG_NOTE, "cost model: "
+ "epilogue peel iters set to vf/2 because "
+ "peeling for alignment is unknown.");
/* If peeled iterations are unknown, count a taken branch and a not taken
branch per peeled loop. Even if scalar loop iterations are known,
@@ -2769,32 +2882,39 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
/* vector version will never be profitable. */
else
{
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "cost model: the vector iteration cost = %d "
- "divided by the scalar iteration cost = %d "
- "is greater or equal to the vectorization factor = %d.",
- vec_inside_cost, scalar_single_iter_cost, vf);
- return -1;
- }
-
- if (vect_print_dump_info (REPORT_COST))
- {
- fprintf (vect_dump, "Cost model analysis: \n");
- fprintf (vect_dump, " Vector inside of loop cost: %d\n",
- vec_inside_cost);
- fprintf (vect_dump, " Vector prologue cost: %d\n",
- vec_prologue_cost);
- fprintf (vect_dump, " Vector epilogue cost: %d\n",
- vec_epilogue_cost);
- fprintf (vect_dump, " Scalar iteration cost: %d\n",
- scalar_single_iter_cost);
- fprintf (vect_dump, " Scalar outside cost: %d\n", scalar_outside_cost);
- fprintf (vect_dump, " prologue iterations: %d\n",
- peel_iters_prologue);
- fprintf (vect_dump, " epilogue iterations: %d\n",
- peel_iters_epilogue);
- fprintf (vect_dump, " Calculated minimum iters for profitability: %d\n",
- min_profitable_iters);
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "cost model: the vector iteration cost = %d "
+ "divided by the scalar iteration cost = %d "
+ "is greater or equal to the vectorization factor = %d.",
+ vec_inside_cost, scalar_single_iter_cost, vf);
+ *ret_min_profitable_niters = -1;
+ *ret_min_profitable_estimate = -1;
+ return;
+ }
+
+ if (dump_kind_p (MSG_NOTE))
+ {
+ dump_printf_loc (MSG_NOTE, vect_location, "Cost model analysis: \n");
+ dump_printf (MSG_NOTE, " Vector inside of loop cost: %d\n",
+ vec_inside_cost);
+ dump_printf (MSG_NOTE, " Vector prologue cost: %d\n",
+ vec_prologue_cost);
+ dump_printf (MSG_NOTE, " Vector epilogue cost: %d\n",
+ vec_epilogue_cost);
+ dump_printf (MSG_NOTE, " Scalar iteration cost: %d\n",
+ scalar_single_iter_cost);
+ dump_printf (MSG_NOTE, " Scalar outside cost: %d\n",
+ scalar_outside_cost);
+ dump_printf (MSG_NOTE, " Vector outside cost: %d\n",
+ vec_outside_cost);
+ dump_printf (MSG_NOTE, " prologue iterations: %d\n",
+ peel_iters_prologue);
+ dump_printf (MSG_NOTE, " epilogue iterations: %d\n",
+ peel_iters_epilogue);
+ dump_printf (MSG_NOTE,
+ " Calculated minimum iters for profitability: %d\n",
+ min_profitable_iters);
}
min_profitable_iters =
@@ -2805,11 +2925,37 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo)
then skip the vectorized loop. */
min_profitable_iters--;
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, " Profitability threshold = %d\n",
- min_profitable_iters);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ " Runtime profitability threshold = %d\n", min_profitable_iters);
+
+ *ret_min_profitable_niters = min_profitable_iters;
+
+ /* Calculate number of iterations required to make the vector version
+ profitable, relative to the loop bodies only.
+
+ Non-vectorized variant is SIC * niters and it must win over vector
+ variant on the expected loop trip count. The following condition must hold true:
+ SIC * niters > VIC * ((niters-PL_ITERS-EP_ITERS)/VF) + VOC + SOC */
+
+ if (vec_outside_cost <= 0)
+ min_profitable_estimate = 1;
+ else
+ {
+ min_profitable_estimate = ((vec_outside_cost + scalar_outside_cost) * vf
+ - vec_inside_cost * peel_iters_prologue
+ - vec_inside_cost * peel_iters_epilogue)
+ / ((scalar_single_iter_cost * vf)
+ - vec_inside_cost);
+ }
+ min_profitable_estimate --;
+ min_profitable_estimate = MAX (min_profitable_estimate, min_profitable_iters);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ " Static estimate profitability threshold = %d\n",
+ min_profitable_iters);
- return min_profitable_iters;
+ *ret_min_profitable_estimate = min_profitable_estimate;
}
@@ -2864,10 +3010,12 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
if (!vectype)
{
- if (vect_print_dump_info (REPORT_COST))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "unsupported data-type ");
- print_generic_expr (vect_dump, TREE_TYPE (reduction_op), TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported data-type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ TREE_TYPE (reduction_op));
}
return false;
}
@@ -2933,10 +3081,11 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
}
}
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_reduction_cost: inside_cost = %d, "
- "prologue_cost = %d, epilogue_cost = %d .", inside_cost,
- prologue_cost, epilogue_cost);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf (MSG_NOTE,
+ "vect_model_reduction_cost: inside_cost = %d, "
+ "prologue_cost = %d, epilogue_cost = %d .", inside_cost,
+ prologue_cost, epilogue_cost);
return true;
}
@@ -2961,9 +3110,10 @@ vect_model_induction_cost (stmt_vec_info stmt_info, int ncopies)
prologue_cost = add_stmt_cost (target_cost_data, 2, scalar_to_vec,
stmt_info, 0, vect_prologue);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_induction_cost: inside_cost = %d, "
- "prologue_cost = %d .", inside_cost, prologue_cost);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_induction_cost: inside_cost = %d, "
+ "prologue_cost = %d .", inside_cost, prologue_cost);
}
@@ -3089,10 +3239,11 @@ get_initial_def_for_induction (gimple iv_phi)
new_bb = gsi_insert_on_edge_immediate (pe, init_stmt);
gcc_assert (!new_bb);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "created new init_stmt: ");
- print_gimple_stmt (vect_dump, init_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "created new init_stmt: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, init_stmt, 0);
}
CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, new_name);
}
@@ -3231,21 +3382,24 @@ get_initial_def_for_induction (gimple iv_phi)
&& !STMT_VINFO_LIVE_P (stmt_vinfo));
STMT_VINFO_VEC_STMT (stmt_vinfo) = new_stmt;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "vector of inductions after inner-loop:");
- print_gimple_stmt (vect_dump, new_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vector of inductions after inner-loop:");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, new_stmt, 0);
}
}
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "transform induction: created def-use cycle: ");
- print_gimple_stmt (vect_dump, induction_phi, 0, TDF_SLIM);
- fprintf (vect_dump, "\n");
- print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (vec_def), 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "transform induction: created def-use cycle: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, induction_phi, 0);
+ dump_printf (MSG_NOTE, "\n");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM,
+ SSA_NAME_DEF_STMT (vec_def), 0);
}
STMT_VINFO_VEC_STMT (phi_info) = induction_phi;
@@ -3646,14 +3800,13 @@ vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt,
add_phi_arg (phi, def, loop_latch_edge (loop), UNKNOWN_LOCATION);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "transform reduction: created def-use"
- " cycle: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
- fprintf (vect_dump, "\n");
- print_gimple_stmt (vect_dump, SSA_NAME_DEF_STMT (def), 0,
- TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "transform reduction: created def-use cycle: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
+ dump_printf (MSG_NOTE, "\n");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, SSA_NAME_DEF_STMT (def), 0);
}
phi = STMT_VINFO_RELATED_STMT (vinfo_for_stmt (phi));
@@ -3848,8 +4001,9 @@ vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt,
/*** Case 1: Create:
v_out2 = reduc_expr <v_out1> */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Reduce using direct vector reduction.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Reduce using direct vector reduction.");
vec_dest = vect_create_destination_var (scalar_dest, vectype);
tmp = build1 (reduc_code, vectype, new_phi_result);
@@ -3898,8 +4052,9 @@ vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt,
Create: va = vop <va, va'>
} */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Reduce using vector shifts");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Reduce using vector shifts");
vec_dest = vect_create_destination_var (scalar_dest, vectype);
new_temp = new_phi_result;
@@ -3938,8 +4093,9 @@ vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt,
Create: s = op <s, s'> // For non SLP cases
} */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Reduce using scalar code. ");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Reduce using scalar code. ");
vec_size_in_bits = tree_low_cst (TYPE_SIZE (vectype), 1);
FOR_EACH_VEC_ELT (gimple, new_phis, i, new_phi)
@@ -4028,8 +4184,9 @@ vect_create_epilog_for_reduction (VEC (tree, heap) *vect_defs, gimple stmt,
{
tree rhs;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "extract scalar result");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "extract scalar result");
if (BYTES_BIG_ENDIAN)
bitpos = size_binop (MULT_EXPR,
@@ -4266,11 +4423,11 @@ vect_finalize_reduction:
UNKNOWN_LOCATION);
add_phi_arg (vect_phi, PHI_RESULT (inner_phi),
loop_latch_edge (outer_loop), UNKNOWN_LOCATION);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "created double reduction phi "
- "node: ");
- print_gimple_stmt (vect_dump, vect_phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "created double reduction phi node: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, vect_phi, 0);
}
vect_phi_res = PHI_RESULT (vect_phi);
@@ -4616,8 +4773,9 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
{
if (!vectorizable_condition (stmt, gsi, NULL, ops[reduc_index], 0, NULL))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unsupported condition in reduction");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported condition in reduction");
return false;
}
@@ -4630,24 +4788,25 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
optab = optab_for_tree_code (code, vectype_in, optab_default);
if (!optab)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no optab.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no optab.");
return false;
}
if (optab_handler (optab, vec_mode) == CODE_FOR_nothing)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "op not supported by target.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf (MSG_NOTE, "op not supported by target.");
if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
|| LOOP_VINFO_VECT_FACTOR (loop_vinfo)
< vect_min_worthwhile_factor (code))
return false;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "proceeding using word mode.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf (MSG_NOTE, "proceeding using word mode.");
}
/* Worthwhile without SIMD support? */
@@ -4655,8 +4814,9 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
&& LOOP_VINFO_VECT_FACTOR (loop_vinfo)
< vect_min_worthwhile_factor (code))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "not worthwhile without SIMD support.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not worthwhile without SIMD support.");
return false;
}
@@ -4735,8 +4895,9 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
optab_default);
if (!reduc_optab)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no optab for reduction.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no optab for reduction.");
epilog_reduc_code = ERROR_MARK;
}
@@ -4744,8 +4905,9 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
if (reduc_optab
&& optab_handler (reduc_optab, vec_mode) == CODE_FOR_nothing)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "reduc op not supported by target.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "reduc op not supported by target.");
epilog_reduc_code = ERROR_MARK;
}
@@ -4754,8 +4916,9 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
{
if (!nested_cycle || double_reduc)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no reduc code for scalar code.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no reduc code for scalar code.");
return false;
}
@@ -4763,8 +4926,9 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
if (double_reduc && ncopies > 1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "multiple types in double reduction");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "multiple types in double reduction");
return false;
}
@@ -4781,8 +4945,9 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
ops[1] = fold_convert (TREE_TYPE (ops[0]), ops[1]);
else
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "invalid types in dot-prod");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "invalid types in dot-prod");
return false;
}
@@ -4798,8 +4963,8 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi,
/** Transform. **/
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform reduction.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "transform reduction.");
/* FORNOW: Multiple types are not supported for condition. */
if (code == COND_EXPR)
@@ -5084,8 +5249,9 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
if (ncopies > 1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "multiple types in nested loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "multiple types in nested loop.");
return false;
}
@@ -5107,9 +5273,10 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
if (!(STMT_VINFO_RELEVANT_P (exit_phi_vinfo)
&& !STMT_VINFO_LIVE_P (exit_phi_vinfo)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "inner-loop induction only used outside "
- "of the outer vectorized loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "inner-loop induction only used outside "
+ "of the outer vectorized loop.");
return false;
}
}
@@ -5130,16 +5297,17 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
if (!vec_stmt) /* transformation not required. */
{
STMT_VINFO_TYPE (stmt_info) = induc_vec_info_type;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vectorizable_induction ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vectorizable_induction ===");
vect_model_induction_cost (stmt_info, ncopies);
return true;
}
/** Transform. **/
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform induction phi.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "transform induction phi.");
vec_def = get_initial_def_for_induction (phi);
*vec_stmt = SSA_NAME_DEF_STMT (vec_def);
@@ -5203,8 +5371,9 @@ vectorizable_live_operation (gimple stmt,
&& !vect_is_simple_use (op, stmt, loop_vinfo, NULL, &def_stmt, &def,
&dt))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
@@ -5241,8 +5410,9 @@ vect_loop_kill_debug_uses (struct loop *loop, gimple stmt)
{
if (gimple_debug_bind_p (ustmt))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "killing debug use");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "killing debug use");
gimple_debug_bind_reset_value (ustmt);
update_stmt (ustmt);
@@ -5280,8 +5450,8 @@ vect_transform_loop (loop_vec_info loop_vinfo)
bool check_profitability = false;
int th;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vec_transform_loop ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "=== vec_transform_loop ===");
/* Use the more conservative vectorization threshold. If the number
of iterations is constant assume the cost check has been performed
@@ -5294,9 +5464,9 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if (th >= LOOP_VINFO_VECT_FACTOR (loop_vinfo) - 1
&& !LOOP_VINFO_NITERS_KNOWN_P (loop_vinfo))
{
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump,
- "Profitability threshold is %d loop iterations.", th);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Profitability threshold is %d loop iterations.", th);
check_profitability = true;
}
@@ -5355,10 +5525,11 @@ vect_transform_loop (loop_vec_info loop_vinfo)
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
phi = gsi_stmt (si);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "------>vectorizing phi: ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "------>vectorizing phi: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
}
stmt_info = vinfo_for_stmt (phi);
if (!stmt_info)
@@ -5373,13 +5544,13 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if ((TYPE_VECTOR_SUBPARTS (STMT_VINFO_VECTYPE (stmt_info))
!= (unsigned HOST_WIDE_INT) vectorization_factor)
- && vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "multiple-types.");
+ && dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "multiple-types.");
if (STMT_VINFO_DEF_TYPE (stmt_info) == vect_induction_def)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform phi.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "transform phi.");
vect_transform_stmt (phi, NULL, NULL, NULL, NULL);
}
}
@@ -5394,10 +5565,11 @@ vect_transform_loop (loop_vec_info loop_vinfo)
else
stmt = gsi_stmt (si);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "------>vectorizing statement: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "------>vectorizing statement: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
stmt_info = vinfo_for_stmt (stmt);
@@ -5465,12 +5637,13 @@ vect_transform_loop (loop_vec_info loop_vinfo)
if (!gsi_end_p (pattern_def_si))
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> vectorizing pattern def"
- " stmt: ");
- print_gimple_stmt (vect_dump, pattern_def_stmt, 0,
- TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "==> vectorizing pattern def "
+ "stmt: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM,
+ pattern_def_stmt, 0);
}
stmt = pattern_def_stmt;
@@ -5491,10 +5664,11 @@ vect_transform_loop (loop_vec_info loop_vinfo)
STMT_VINFO_VECTYPE (stmt_info));
if (!STMT_SLP_TYPE (stmt_info)
&& nunits != (unsigned int) vectorization_factor
- && vect_print_dump_info (REPORT_DETAILS))
+ && dump_kind_p (MSG_NOTE))
/* For SLP VF is set according to unrolling factor, and not to
vector size, hence for SLP this print is not valid. */
- fprintf (vect_dump, "multiple-types.");
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "multiple-types.");
/* SLP. Schedule all the SLP instances when the first SLP stmt is
reached. */
@@ -5504,8 +5678,9 @@ vect_transform_loop (loop_vec_info loop_vinfo)
{
slp_scheduled = true;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== scheduling SLP instances ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== scheduling SLP instances ===");
vect_schedule_slp (loop_vinfo, NULL);
}
@@ -5523,8 +5698,8 @@ vect_transform_loop (loop_vec_info loop_vinfo)
}
/* -------- vectorize statement ------------ */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform statement.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "transform statement.");
grouped_store = false;
is_store = vect_transform_stmt (stmt, &si, &grouped_store, NULL, NULL);
@@ -5566,8 +5741,9 @@ vect_transform_loop (loop_vec_info loop_vinfo)
until all the loops have been transformed? */
update_ssa (TODO_update_ssa);
- if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
- fprintf (vect_dump, "LOOP VECTORIZED.");
- if (loop->inner && vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
- fprintf (vect_dump, "OUTER LOOP VECTORIZED.");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, "LOOP VECTORIZED.");
+ if (loop->inner && dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "OUTER LOOP VECTORIZED.");
}
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index ef65c3f88..b0974ec19 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -416,10 +416,11 @@ vect_recog_dot_prod_pattern (VEC (gimple, heap) **stmts, tree *type_in,
pattern_stmt = gimple_build_assign_with_ops (DOT_PROD_EXPR, var,
oprnd00, oprnd01, oprnd1);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
{
- fprintf (vect_dump, "vect_recog_dot_prod_pattern: detected: ");
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_dot_prod_pattern: detected: ");
+ dump_gimple_stmt (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, pattern_stmt, 0);
}
/* We don't allow changing the order of the computation in the inner-loop
@@ -675,8 +676,9 @@ vect_recog_widen_mult_pattern (VEC (gimple, heap) **stmts,
return NULL;
/* Pattern detected. */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_widen_mult_pattern: detected: ");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_widen_mult_pattern: detected: ");
/* Check target support */
vectype = get_vectype_for_scalar_type (half_type0);
@@ -697,8 +699,8 @@ vect_recog_widen_mult_pattern (VEC (gimple, heap) **stmts,
pattern_stmt = gimple_build_assign_with_ops (WIDEN_MULT_EXPR, var, oprnd0,
oprnd1);
- if (vect_print_dump_info (REPORT_DETAILS))
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ if (dump_kind_p (MSG_NOTE))
+ dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt, 0);
VEC_safe_push (gimple, heap, *stmts, last_stmt);
return pattern_stmt;
@@ -910,10 +912,11 @@ vect_recog_widen_sum_pattern (VEC (gimple, heap) **stmts, tree *type_in,
pattern_stmt = gimple_build_assign_with_ops (WIDEN_SUM_EXPR, var,
oprnd0, oprnd1);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
{
- fprintf (vect_dump, "vect_recog_widen_sum_pattern: detected: ");
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_widen_sum_pattern: detected: ");
+ dump_gimple_stmt (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, pattern_stmt, 0);
}
/* We don't allow changing the order of the computation in the inner-loop
@@ -1214,10 +1217,11 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts,
STMT_VINFO_RELATED_STMT (vinfo_for_stmt (stmt)) = pattern_stmt;
new_pattern_def_seq (vinfo_for_stmt (stmt), new_def_stmt);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
{
- fprintf (vect_dump, "created pattern stmt: ");
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "created pattern stmt: ");
+ dump_gimple_stmt (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, pattern_stmt, 0);
}
type = gimple_expr_type (stmt);
@@ -1281,10 +1285,11 @@ vect_recog_over_widening_pattern (VEC (gimple, heap) **stmts,
return NULL;
/* Pattern detected. */
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
{
- fprintf (vect_dump, "vect_recog_over_widening_pattern: detected: ");
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_over_widening_pattern: detected: ");
+ dump_gimple_stmt (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, pattern_stmt, 0);
}
return pattern_stmt;
@@ -1416,8 +1421,9 @@ vect_recog_widen_shift_pattern (VEC (gimple, heap) **stmts,
return NULL;
/* Pattern detected. */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_widen_shift_pattern: detected: ");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_widen_shift_pattern: detected: ");
/* Check target support. */
vectype = get_vectype_for_scalar_type (half_type0);
@@ -1439,8 +1445,8 @@ vect_recog_widen_shift_pattern (VEC (gimple, heap) **stmts,
pattern_stmt =
gimple_build_assign_with_ops (WIDEN_LSHIFT_EXPR, var, oprnd0, oprnd1);
- if (vect_print_dump_info (REPORT_DETAILS))
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ if (dump_kind_p (MSG_NOTE))
+ dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt, 0);
VEC_safe_push (gimple, heap, *stmts, last_stmt);
return pattern_stmt;
@@ -1561,15 +1567,16 @@ vect_recog_vector_vector_shift_pattern (VEC (gimple, heap) **stmts,
}
/* Pattern detected. */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_vector_vector_shift_pattern: detected: ");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_vector_vector_shift_pattern: detected: ");
/* Pattern supported. Create a stmt to be used to replace the pattern. */
var = vect_recog_temp_ssa_var (TREE_TYPE (oprnd0), NULL);
pattern_stmt = gimple_build_assign_with_ops (rhs_code, var, oprnd0, def);
- if (vect_print_dump_info (REPORT_DETAILS))
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ if (dump_kind_p (MSG_NOTE))
+ dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt, 0);
VEC_safe_push (gimple, heap, *stmts, last_stmt);
return pattern_stmt;
@@ -1678,8 +1685,9 @@ vect_recog_divmod_pattern (VEC (gimple, heap) **stmts,
return NULL;
/* Pattern detected. */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_divmod_pattern: detected: ");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_divmod_pattern: detected: ");
cond = build2 (LT_EXPR, boolean_type_node, oprnd0,
build_int_cst (itype, 0));
@@ -1781,8 +1789,9 @@ vect_recog_divmod_pattern (VEC (gimple, heap) **stmts,
signmask);
}
- if (vect_print_dump_info (REPORT_DETAILS))
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ if (dump_kind_p (MSG_NOTE))
+ dump_gimple_stmt_loc (MSG_NOTE, vect_location, TDF_SLIM, pattern_stmt,
+ 0);
VEC_safe_push (gimple, heap, *stmts, last_stmt);
@@ -2022,11 +2031,12 @@ vect_recog_divmod_pattern (VEC (gimple, heap) **stmts,
}
/* Pattern detected. */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_divmod_pattern: detected: ");
-
- if (vect_print_dump_info (REPORT_DETAILS))
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ {
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_divmod_pattern: detected: ");
+ dump_gimple_stmt (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, pattern_stmt, 0);
+ }
VEC_safe_push (gimple, heap, *stmts, last_stmt);
@@ -2189,8 +2199,9 @@ vect_recog_mixed_size_cond_pattern (VEC (gimple, heap) **stmts, tree *type_in,
*type_in = vecitype;
*type_out = vectype;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_mixed_size_cond_pattern: detected: ");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_mixed_size_cond_pattern: detected: ");
return pattern_stmt;
}
@@ -2581,8 +2592,9 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in,
*type_out = vectype;
*type_in = vectype;
VEC_safe_push (gimple, heap, *stmts, last_stmt);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_bool_pattern: detected: ");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_bool_pattern: detected: ");
return pattern_stmt;
}
@@ -2626,8 +2638,9 @@ vect_recog_bool_pattern (VEC (gimple, heap) **stmts, tree *type_in,
*type_out = vectype;
*type_in = vectype;
VEC_safe_push (gimple, heap, *stmts, last_stmt);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vect_recog_bool_pattern: detected: ");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "vect_recog_bool_pattern: detected: ");
return pattern_stmt;
}
else
@@ -2775,10 +2788,11 @@ vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func,
}
/* Found a vectorizable pattern. */
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
{
- fprintf (vect_dump, "pattern recognized: ");
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "pattern recognized: ");
+ dump_gimple_stmt (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, pattern_stmt, 0);
}
/* Mark the stmts that are involved in the pattern. */
@@ -2800,10 +2814,11 @@ vect_pattern_recog_1 (vect_recog_func_ptr vect_recog_func,
{
stmt_info = vinfo_for_stmt (stmt);
pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
{
- fprintf (vect_dump, "additional pattern stmt: ");
- print_gimple_stmt (vect_dump, pattern_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "additional pattern stmt: ");
+ dump_gimple_stmt (MSG_OPTIMIZED_LOCATIONS, TDF_SLIM, pattern_stmt, 0);
}
vect_mark_pattern_stmts (stmt, pattern_stmt, NULL_TREE);
@@ -2900,8 +2915,9 @@ vect_pattern_recog (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
VEC (gimple, heap) *stmts_to_replace = VEC_alloc (gimple, heap, 1);
gimple stmt;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_pattern_recog ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_pattern_recog ===");
if (loop_vinfo)
{
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index 83cbb49fb..c2429b286 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "dumpfile.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
@@ -237,10 +238,11 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
&def, &dt)
|| (!def_stmt && dt != vect_constant_def))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: can't find def for ");
- print_generic_expr (vect_dump, oprnd, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: can't find def for ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, oprnd);
}
return false;
@@ -261,11 +263,12 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
pattern = true;
if (!first && !oprnd_info->first_pattern)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: some of the stmts"
- " are in a pattern, and others are not ");
- print_generic_expr (vect_dump, oprnd, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: some of the stmts"
+ " are in a pattern, and others are not ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, oprnd);
}
return false;
@@ -276,8 +279,9 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (dt == vect_unknown_def_type)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Unsupported pattern.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Unsupported pattern.");
return false;
}
@@ -292,8 +296,9 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
break;
default:
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unsupported defining stmt: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported defining stmt: ");
return false;
}
}
@@ -356,8 +361,9 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
{
if (number_of_oprnds != 2)
{
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "Build SLP failed: different types ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: different types ");
return false;
}
@@ -382,10 +388,11 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
&& !types_compatible_p (oprnd_info->first_def_type,
TREE_TYPE (def_op0))))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Swapping operands of ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Swapping operands of ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
swap_tree_operands (stmt, gimple_assign_rhs1_ptr (stmt),
@@ -393,8 +400,9 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
}
else
{
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "Build SLP failed: different types ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: different types ");
return false;
}
@@ -427,10 +435,11 @@ vect_get_and_check_slp_defs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
default:
/* FORNOW: Not supported. */
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: illegal type of def ");
- print_generic_expr (vect_dump, def, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: illegal type of def ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, def);
}
return false;
@@ -495,20 +504,20 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
/* For every stmt in NODE find its def stmt/s. */
FOR_EACH_VEC_ELT (gimple, stmts, i, stmt)
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Build SLP for ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "Build SLP for ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
/* Fail to vectorize statements marked as unvectorizable. */
if (!STMT_VINFO_VECTORIZABLE (vinfo_for_stmt (stmt)))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "Build SLP failed: unvectorizable statement ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: unvectorizable statement ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -518,11 +527,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
lhs = gimple_get_lhs (stmt);
if (lhs == NULL_TREE)
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "Build SLP failed: not GIMPLE_ASSIGN nor GIMPLE_CALL ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: not GIMPLE_ASSIGN nor "
+ "GIMPLE_CALL ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -534,11 +544,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
&& (cond = gimple_assign_rhs1 (stmt))
&& !COMPARISON_CLASS_P (cond))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "Build SLP failed: condition is not comparison ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: condition is not "
+ "comparison ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -549,10 +560,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
vectype = get_vectype_for_scalar_type (scalar_type);
if (!vectype)
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: unsupported data-type ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: unsupported data-type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ scalar_type);
}
vect_free_oprnd_info (&oprnds_info);
@@ -578,11 +591,11 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
|| !gimple_call_nothrow_p (stmt)
|| gimple_call_chain (stmt))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "Build SLP failed: unsupported call type ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: unsupported call type ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -618,17 +631,19 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (!optab)
{
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "Build SLP failed: no optab.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: no optab.");
vect_free_oprnd_info (&oprnds_info);
return false;
}
icode = (int) optab_handler (optab, vec_mode);
if (icode == CODE_FOR_nothing)
{
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "Build SLP failed: "
- "op not supported by target.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: "
+ "op not supported by target.");
vect_free_oprnd_info (&oprnds_info);
return false;
}
@@ -659,11 +674,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
|| first_stmt_code == COMPONENT_REF
|| first_stmt_code == MEM_REF)))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "Build SLP failed: different operation in stmt ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: different operation "
+ "in stmt ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -673,11 +689,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (need_same_oprnds
&& !operand_equal_p (first_op1, gimple_assign_rhs2 (stmt), 0))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "Build SLP failed: different shift arguments in ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: different shift "
+ "arguments in ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -693,11 +710,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
|| gimple_call_fntype (first_stmt)
!= gimple_call_fntype (stmt))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump,
- "Build SLP failed: different calls in ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: different calls in ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -731,11 +749,13 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
|| (GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) != stmt
&& GROUP_GAP (vinfo_for_stmt (stmt)) != 1))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: grouped "
- "loads have gaps ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: grouped "
+ "loads have gaps ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -747,12 +767,14 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (loop_vinfo
&& GROUP_SIZE (vinfo_for_stmt (stmt)) > ncopies * group_size)
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: the number of "
- "interleaved loads is greater than"
- " the SLP group size ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: the number "
+ "of interleaved loads is greater than "
+ "the SLP group size ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -767,16 +789,19 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
chains in the same node. The only exception is complex
numbers. */
if (prev_first_load != first_load
- && rhs_code != REALPART_EXPR
+ && rhs_code != REALPART_EXPR
&& rhs_code != IMAGPART_EXPR)
- {
- if (vect_print_dump_info (REPORT_SLP))
+ {
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: different "
- "interleaving chains in one node ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION,
+ vect_location,
+ "Build SLP failed: different "
+ "interleaving chains in one node ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ stmt, 0);
}
-
+
vect_free_oprnd_info (&oprnds_info);
return false;
}
@@ -792,11 +817,14 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (vect_supportable_dr_alignment (first_dr, false)
== dr_unaligned_unsupported)
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: unsupported "
- "unaligned load ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION,
+ vect_location,
+ "Build SLP failed: unsupported "
+ "unaligned load ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -829,10 +857,11 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (TREE_CODE_CLASS (rhs_code) == tcc_reference)
{
/* Not grouped load. */
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: not grouped load ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: not grouped load ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
/* FORNOW: Not grouped loads are not supported. */
@@ -846,11 +875,12 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
&& rhs_code != COND_EXPR
&& rhs_code != CALL_EXPR)
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: operation");
- fprintf (vect_dump, " unsupported ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: operation");
+ dump_printf (MSG_MISSED_OPTIMIZATION, " unsupported ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -865,11 +895,13 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
first_cond_code = TREE_CODE (cond_expr);
else if (first_cond_code != TREE_CODE (cond_expr))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: different"
- " operation");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: different"
+ " operation");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ stmt, 0);
}
vect_free_oprnd_info (&oprnds_info);
@@ -944,9 +976,10 @@ vect_build_slp_tree (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
return true;
}
+/* Dump a slp tree NODE using flags specified in DUMP_KIND. */
static void
-vect_print_slp_tree (slp_tree node)
+vect_print_slp_tree (int dump_kind, slp_tree node)
{
int i;
gimple stmt;
@@ -955,16 +988,16 @@ vect_print_slp_tree (slp_tree node)
if (!node)
return;
- fprintf (vect_dump, "node ");
+ dump_printf (dump_kind, "node ");
FOR_EACH_VEC_ELT (gimple, SLP_TREE_SCALAR_STMTS (node), i, stmt)
{
- fprintf (vect_dump, "\n\tstmt %d ", i);
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf (dump_kind, "\n\tstmt %d ", i);
+ dump_gimple_stmt (dump_kind, TDF_SLIM, stmt, 0);
}
- fprintf (vect_dump, "\n");
+ dump_printf (dump_kind, "\n");
FOR_EACH_VEC_ELT (slp_void_p, SLP_TREE_CHILDREN (node), i, child)
- vect_print_slp_tree ((slp_tree) child);
+ vect_print_slp_tree (dump_kind, (slp_tree) child);
}
@@ -1047,11 +1080,13 @@ vect_supported_slp_permutation_p (slp_instance instance)
/* Check that the loads are all in the same interleaving chain. */
if (GROUP_FIRST_ELEMENT (vinfo_for_stmt (scalar_stmt)) != first_load)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: unsupported data "
- "permutation ");
- print_gimple_stmt (vect_dump, scalar_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: unsupported data "
+ "permutation ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ scalar_stmt, 0);
}
free (tmp_loads);
@@ -1134,11 +1169,11 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size,
if (!slp_instn)
return false;
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Load permutation ");
+ dump_printf_loc (MSG_NOTE, vect_location, "Load permutation ");
FOR_EACH_VEC_ELT (int, load_permutation, i, next)
- fprintf (vect_dump, "%d ", next);
+ dump_printf (MSG_NOTE, "%d ", next);
}
/* In case of reduction every load permutation is allowed, since the order
@@ -1341,11 +1376,13 @@ vect_supported_load_permutation_p (slp_instance slp_instn, int group_size,
if (vect_supportable_dr_alignment (dr, false)
== dr_unaligned_unsupported)
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "unsupported unaligned load ");
- print_gimple_stmt (vect_dump, first_load, 0,
- TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION,
+ vect_location,
+ "unsupported unaligned load ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ first_load, 0);
}
bad_permutation = true;
break;
@@ -1499,10 +1536,11 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (!vectype)
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: unsupported data-type ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: unsupported data-type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, scalar_type);
}
return false;
@@ -1518,9 +1556,10 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
unrolling_factor = least_common_multiple (nunits, group_size) / group_size;
if (unrolling_factor != 1 && !loop_vinfo)
{
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "Build SLP failed: unrolling required in basic"
- " block SLP");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: unrolling required in basic"
+ " block SLP");
return false;
}
@@ -1579,9 +1618,10 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (unrolling_factor != 1 && !loop_vinfo)
{
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "Build SLP failed: unrolling required in basic"
- " block SLP");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: unrolling required in basic"
+ " block SLP");
vect_free_slp_tree (node);
VEC_free (stmt_info_for_cost, heap, body_cost_vec);
VEC_free (stmt_info_for_cost, heap, prologue_cost_vec);
@@ -1605,11 +1645,12 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
if (!vect_supported_load_permutation_p (new_instance, group_size,
load_permutation))
{
- if (vect_print_dump_info (REPORT_SLP))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "Build SLP failed: unsupported load "
- "permutation ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Build SLP failed: unsupported load "
+ "permutation ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
vect_free_slp_instance (new_instance);
@@ -1644,8 +1685,8 @@ vect_analyze_slp_instance (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo,
VEC_safe_push (slp_instance, heap, BB_VINFO_SLP_INSTANCES (bb_vinfo),
new_instance);
- if (vect_print_dump_info (REPORT_SLP))
- vect_print_slp_tree (node);
+ if (dump_kind_p (MSG_NOTE))
+ vect_print_slp_tree (MSG_NOTE, node);
return true;
}
@@ -1676,8 +1717,8 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
gimple first_element;
bool ok = false;
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "=== vect_analyze_slp ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "=== vect_analyze_slp ===");
if (loop_vinfo)
{
@@ -1695,8 +1736,9 @@ vect_analyze_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
if (bb_vinfo && !ok)
{
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "Failed to SLP the basic block.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Failed to SLP the basic block.");
return false;
}
@@ -1738,8 +1780,8 @@ vect_make_slp_decision (loop_vec_info loop_vinfo)
slp_instance instance;
int decided_to_slp = 0;
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "=== vect_make_slp_decision ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "=== vect_make_slp_decision ===");
FOR_EACH_VEC_ELT (slp_instance, slp_instances, i, instance)
{
@@ -1756,9 +1798,10 @@ vect_make_slp_decision (loop_vec_info loop_vinfo)
LOOP_VINFO_SLP_UNROLLING_FACTOR (loop_vinfo) = unrolling_factor;
- if (decided_to_slp && vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "Decided to SLP %d instances. Unrolling factor %d",
- decided_to_slp, unrolling_factor);
+ if (decided_to_slp && dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "Decided to SLP %d instances. Unrolling factor %d",
+ decided_to_slp, unrolling_factor);
return (decided_to_slp > 0);
}
@@ -1820,8 +1863,8 @@ vect_detect_hybrid_slp (loop_vec_info loop_vinfo)
VEC (slp_instance, heap) *slp_instances = LOOP_VINFO_SLP_INSTANCES (loop_vinfo);
slp_instance instance;
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "=== vect_detect_hybrid_slp ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "=== vect_detect_hybrid_slp ===");
FOR_EACH_VEC_ELT (slp_instance, slp_instances, i, instance)
vect_detect_hybrid_slp_stmts (SLP_INSTANCE_TREE (instance));
@@ -2017,14 +2060,14 @@ vect_bb_vectorization_profitable_p (bb_vec_info bb_vinfo)
vec_outside_cost = vec_prologue_cost + vec_epilogue_cost;
- if (vect_print_dump_info (REPORT_COST))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "Cost model analysis: \n");
- fprintf (vect_dump, " Vector inside of basic block cost: %d\n",
- vec_inside_cost);
- fprintf (vect_dump, " Vector prologue cost: %d\n", vec_prologue_cost);
- fprintf (vect_dump, " Vector epilogue cost: %d\n", vec_epilogue_cost);
- fprintf (vect_dump, " Scalar cost of basic block: %d", scalar_cost);
+ dump_printf_loc (MSG_NOTE, vect_location, "Cost model analysis: \n");
+ dump_printf (MSG_NOTE, " Vector inside of basic block cost: %d\n",
+ vec_inside_cost);
+ dump_printf (MSG_NOTE, " Vector prologue cost: %d\n", vec_prologue_cost);
+ dump_printf (MSG_NOTE, " Vector epilogue cost: %d\n", vec_epilogue_cost);
+ dump_printf (MSG_NOTE, " Scalar cost of basic block: %d", scalar_cost);
}
/* Vectorization is profitable if its cost is less than the cost of scalar
@@ -2054,9 +2097,10 @@ vect_slp_analyze_bb_1 (basic_block bb)
if (!vect_analyze_data_refs (NULL, bb_vinfo, &min_vf))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: unhandled data-ref in basic "
- "block.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unhandled data-ref in basic "
+ "block.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
@@ -2065,9 +2109,10 @@ vect_slp_analyze_bb_1 (basic_block bb)
ddrs = BB_VINFO_DDRS (bb_vinfo);
if (!VEC_length (ddr_p, ddrs))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: not enough data-refs in basic "
- "block.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: not enough data-refs in "
+ "basic block.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
@@ -2078,9 +2123,10 @@ vect_slp_analyze_bb_1 (basic_block bb)
if (!vect_analyze_data_ref_dependences (NULL, bb_vinfo, &max_vf)
|| min_vf > max_vf)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: unhandled data dependence "
- "in basic block.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unhandled data dependence "
+ "in basic block.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
@@ -2088,9 +2134,10 @@ vect_slp_analyze_bb_1 (basic_block bb)
if (!vect_analyze_data_refs_alignment (NULL, bb_vinfo))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: bad data alignment in basic "
- "block.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: bad data alignment in basic "
+ "block.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
@@ -2098,9 +2145,10 @@ vect_slp_analyze_bb_1 (basic_block bb)
if (!vect_analyze_data_ref_accesses (NULL, bb_vinfo))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: unhandled data access in basic "
- "block.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unhandled data access in "
+ "basic block.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
@@ -2110,9 +2158,10 @@ vect_slp_analyze_bb_1 (basic_block bb)
trees. */
if (!vect_analyze_slp (NULL, bb_vinfo))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: failed to find SLP opportunities "
- "in basic block.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: failed to find SLP opportunities "
+ "in basic block.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
@@ -2130,18 +2179,19 @@ vect_slp_analyze_bb_1 (basic_block bb)
if (!vect_verify_datarefs_alignment (NULL, bb_vinfo))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: unsupported alignment in basic "
- "block.\n");
-
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported alignment in basic "
+ "block.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
}
if (!vect_slp_analyze_operations (bb_vinfo))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: bad operation in basic block.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: bad operation in basic block.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
@@ -2151,16 +2201,18 @@ vect_slp_analyze_bb_1 (basic_block bb)
if (flag_vect_cost_model
&& !vect_bb_vectorization_profitable_p (bb_vinfo))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: vectorization is not "
- "profitable.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: vectorization is not "
+ "profitable.\n");
destroy_bb_vec_info (bb_vinfo);
return NULL;
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Basic block will be vectorized using SLP\n");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Basic block will be vectorized using SLP\n");
return bb_vinfo;
}
@@ -2174,8 +2226,8 @@ vect_slp_analyze_bb (basic_block bb)
gimple_stmt_iterator gsi;
unsigned int vector_sizes;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "===vect_slp_analyze_bb===\n");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "===vect_slp_analyze_bb===\n");
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
@@ -2188,9 +2240,10 @@ vect_slp_analyze_bb (basic_block bb)
if (insns > PARAM_VALUE (PARAM_SLP_MAX_INSNS_IN_BB))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: too many instructions in basic "
- "block.\n");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: too many instructions in "
+ "basic block.\n");
return NULL;
}
@@ -2214,9 +2267,10 @@ vect_slp_analyze_bb (basic_block bb)
/* Try the next biggest vector size. */
current_vector_size = 1 << floor_log2 (vector_sizes);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "***** Re-trying analysis with "
- "vector size %d\n", current_vector_size);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "***** Re-trying analysis with "
+ "vector size %d\n", current_vector_size);
}
}
@@ -2238,8 +2292,9 @@ vect_update_slp_costs_according_to_vf (loop_vec_info loop_vinfo)
stmt_info_for_cost *si;
void *data = LOOP_VINFO_TARGET_COST_DATA (loop_vinfo);
- if (vect_print_dump_info (REPORT_SLP))
- fprintf (vect_dump, "=== vect_update_slp_costs_according_to_vf ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_update_slp_costs_according_to_vf ===");
FOR_EACH_VEC_ELT (slp_instance, slp_instances, i, instance)
{
@@ -2290,6 +2345,7 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
enum tree_code code = gimple_expr_code (stmt);
gimple def_stmt;
struct loop *loop;
+ gimple_seq ctor_seq = NULL;
if (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_reduction_def
&& reduc_index != -1)
@@ -2448,11 +2504,27 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
/* Create 'vect_ = {op0,op1,...,opn}'. */
number_of_places_left_in_vector--;
- if (constant_p
- && !types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
+ if (!types_compatible_p (TREE_TYPE (vector_type), TREE_TYPE (op)))
{
- op = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (vector_type), op);
- gcc_assert (op && CONSTANT_CLASS_P (op));
+ if (constant_p)
+ {
+ op = fold_unary (VIEW_CONVERT_EXPR,
+ TREE_TYPE (vector_type), op);
+ gcc_assert (op && CONSTANT_CLASS_P (op));
+ }
+ else
+ {
+ tree new_temp
+ = make_ssa_name (TREE_TYPE (vector_type), NULL);
+ gimple init_stmt;
+ op = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (vector_type),
+ op);
+ init_stmt
+ = gimple_build_assign_with_ops (VIEW_CONVERT_EXPR,
+ new_temp, op, NULL_TREE);
+ gimple_seq_add_stmt (&ctor_seq, init_stmt);
+ op = new_temp;
+ }
}
elts[number_of_places_left_in_vector] = op;
@@ -2474,6 +2546,15 @@ vect_get_constant_vectors (tree op, slp_tree slp_node,
VEC_quick_push (tree, voprnds,
vect_init_vector (stmt, vec_cst,
vector_type, NULL));
+ if (ctor_seq != NULL)
+ {
+ gimple init_stmt
+ = SSA_NAME_DEF_STMT (VEC_last (tree, voprnds));
+ gimple_stmt_iterator gsi = gsi_for_stmt (init_stmt);
+ gsi_insert_seq_before_without_update (&gsi, ctor_seq,
+ GSI_SAME_STMT);
+ ctor_seq = NULL;
+ }
}
}
}
@@ -2719,10 +2800,11 @@ vect_get_mask_element (gimple stmt, int first_mask_element, int m,
the next vector as well. */
if (only_one_vec && *current_mask_element >= mask_nunits)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "permutation requires at least two vectors ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "permutation requires at least two vectors ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
@@ -2736,11 +2818,12 @@ vect_get_mask_element (gimple stmt, int first_mask_element, int m,
/* We either need the first vector too or have already moved to the
next vector. In both cases, this permutation needs three
vectors. */
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "permutation requires at "
- "least three vectors ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "permutation requires at "
+ "least three vectors ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
@@ -2801,10 +2884,11 @@ vect_transform_slp_perm_load (gimple stmt, VEC (tree, heap) *dr_chain,
if (!can_vec_perm_p (mode, false, NULL))
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "no vect permute for ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no vect permute for ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
}
@@ -2880,12 +2964,15 @@ vect_transform_slp_perm_load (gimple stmt, VEC (tree, heap) *dr_chain,
if (!can_vec_perm_p (mode, false, mask))
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "unsupported vect permute { ");
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION,
+ vect_location,
+ "unsupported vect permute { ");
for (i = 0; i < nunits; ++i)
- fprintf (vect_dump, "%d ", mask[i]);
- fprintf (vect_dump, "}\n");
+ dump_printf (MSG_MISSED_OPTIMIZATION, "%d ",
+ mask[i]);
+ dump_printf (MSG_MISSED_OPTIMIZATION, "}\n");
}
return false;
}
@@ -2981,10 +3068,11 @@ vect_schedule_slp_instance (slp_tree node, slp_instance instance,
SLP_TREE_NUMBER_OF_VEC_STMTS (node) = vec_stmts_size;
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "------>vectorizing SLP node starting from: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE,vect_location,
+ "------>vectorizing SLP node starting from: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
/* Loads should be inserted before the first load. */
@@ -3089,9 +3177,9 @@ vect_schedule_slp (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
/* Schedule the tree of INSTANCE. */
is_store = vect_schedule_slp_instance (SLP_INSTANCE_TREE (instance),
instance, vf);
- if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS)
- || vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "vectorizing stmts using SLP.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vectorizing stmts using SLP.");
}
FOR_EACH_VEC_ELT (slp_instance, slp_instances, i, instance)
@@ -3134,18 +3222,19 @@ vect_slp_transform_bb (basic_block bb)
gcc_assert (bb_vinfo);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "SLPing BB\n");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "SLPing BB\n");
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
gimple stmt = gsi_stmt (si);
stmt_vec_info stmt_info;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "------>SLPing statement: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "------>SLPing statement: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
stmt_info = vinfo_for_stmt (stmt);
@@ -3159,9 +3248,8 @@ vect_slp_transform_bb (basic_block bb)
}
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "BASIC BLOCK VECTORIZED\n");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf (MSG_OPTIMIZED_LOCATIONS, "BASIC BLOCK VECTORIZED\n");
destroy_bb_vec_info (bb_vinfo);
}
-
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 210e5b572..92eaac48a 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "dumpfile.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
@@ -189,8 +190,9 @@ vect_mark_relevant (VEC(gimple,heap) **worklist, gimple stmt,
bool save_live_p = STMT_VINFO_LIVE_P (stmt_info);
gimple pattern_stmt;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "mark relevant %d, live %d.", relevant, live_p);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "mark relevant %d, live %d.", relevant, live_p);
/* If this stmt is an original stmt in a pattern, we might need to mark its
related pattern stmt instead of the original stmt. However, such stmts
@@ -244,9 +246,10 @@ vect_mark_relevant (VEC(gimple,heap) **worklist, gimple stmt,
pattern_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "last stmt in pattern. don't mark"
- " relevant/live.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "last stmt in pattern. don't mark"
+ " relevant/live.");
stmt_info = vinfo_for_stmt (pattern_stmt);
gcc_assert (STMT_VINFO_RELATED_STMT (stmt_info) == stmt);
save_relevant = STMT_VINFO_RELEVANT (stmt_info);
@@ -262,8 +265,9 @@ vect_mark_relevant (VEC(gimple,heap) **worklist, gimple stmt,
if (STMT_VINFO_RELEVANT (stmt_info) == save_relevant
&& STMT_VINFO_LIVE_P (stmt_info) == save_live_p)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "already marked relevant/live.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "already marked relevant/live.");
return;
}
@@ -306,8 +310,9 @@ vect_stmt_relevant_p (gimple stmt, loop_vec_info loop_vinfo,
if (gimple_code (stmt) != GIMPLE_PHI)
if (gimple_vdef (stmt))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vec_stmt_relevant_p: stmt has vdefs.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vec_stmt_relevant_p: stmt has vdefs.");
*relevant = vect_used_in_scope;
}
@@ -319,8 +324,9 @@ vect_stmt_relevant_p (gimple stmt, loop_vec_info loop_vinfo,
basic_block bb = gimple_bb (USE_STMT (use_p));
if (!flow_bb_inside_loop_p (loop, bb))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vec_stmt_relevant_p: used out of loop.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vec_stmt_relevant_p: used out of loop.");
if (is_gimple_debug (USE_STMT (use_p)))
continue;
@@ -431,8 +437,9 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
if (!vect_is_simple_use (use, stmt, loop_vinfo, NULL, &def_stmt, &def, &dt))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: unsupported use in stmt.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: unsupported use in stmt.");
return false;
}
@@ -442,8 +449,8 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
def_bb = gimple_bb (def_stmt);
if (!flow_bb_inside_loop_p (loop, def_bb))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "def_stmt is out of loop.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "def_stmt is out of loop.");
return true;
}
@@ -460,8 +467,9 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
&& STMT_VINFO_DEF_TYPE (dstmt_vinfo) == vect_reduction_def
&& bb->loop_father == def_bb->loop_father)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "reduc-stmt defining reduc-phi in the same nest.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "reduc-stmt defining reduc-phi in the same nest.");
if (STMT_VINFO_IN_PATTERN_P (dstmt_vinfo))
dstmt_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (dstmt_vinfo));
gcc_assert (STMT_VINFO_RELEVANT (dstmt_vinfo) < vect_used_by_reduction);
@@ -479,8 +487,9 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
... */
if (flow_loop_nested_p (def_bb->loop_father, bb->loop_father))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "outer-loop def-stmt defining inner-loop stmt.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "outer-loop def-stmt defining inner-loop stmt.");
switch (relevant)
{
@@ -516,8 +525,9 @@ process_use (gimple stmt, tree use, loop_vec_info loop_vinfo, bool live_p,
stmt # use (d) */
else if (flow_loop_nested_p (bb->loop_father, def_bb->loop_father))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "inner-loop def-stmt defining outer-loop stmt.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "inner-loop def-stmt defining outer-loop stmt.");
switch (relevant)
{
@@ -579,8 +589,9 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
enum vect_relevant relevant, tmp_relevant;
enum vect_def_type def_type;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vect_mark_stmts_to_be_vectorized ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vect_mark_stmts_to_be_vectorized ===");
worklist = VEC_alloc (gimple, heap, 64);
@@ -591,10 +602,10 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
{
phi = gsi_stmt (si);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "init: phi relevant? ");
- print_gimple_stmt (vect_dump, phi, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "init: phi relevant? ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, phi, 0);
}
if (vect_stmt_relevant_p (phi, loop_vinfo, &relevant, &live_p))
@@ -603,10 +614,10 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
{
stmt = gsi_stmt (si);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "init: stmt relevant? ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "init: stmt relevant? ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
if (vect_stmt_relevant_p (stmt, loop_vinfo, &relevant, &live_p))
@@ -621,10 +632,10 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
ssa_op_iter iter;
stmt = VEC_pop (gimple, worklist);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "worklist: examine stmt: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "worklist: examine stmt: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
/* Examine the USEs of STMT. For each USE, mark the stmt that defines it
@@ -666,9 +677,9 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
/* fall through */
default:
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unsupported use of reduction.");
-
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported use of reduction.");
VEC_free (gimple, heap, worklist);
return false;
}
@@ -681,8 +692,9 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
&& tmp_relevant != vect_used_in_outer_by_reduction
&& tmp_relevant != vect_used_in_outer)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unsupported use of nested cycle.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported use of nested cycle.");
VEC_free (gimple, heap, worklist);
return false;
@@ -695,8 +707,9 @@ vect_mark_stmts_to_be_vectorized (loop_vec_info loop_vinfo)
if (tmp_relevant != vect_unused_in_scope
&& tmp_relevant != vect_used_by_reduction)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unsupported use of double reduction.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported use of double reduction.");
VEC_free (gimple, heap, worklist);
return false;
@@ -817,9 +830,10 @@ vect_model_simple_cost (stmt_vec_info stmt_info, int ncopies,
inside_cost = record_stmt_cost (body_cost_vec, ncopies, vector_stmt,
stmt_info, 0, vect_body);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_simple_cost: inside_cost = %d, "
- "prologue_cost = %d .", inside_cost, prologue_cost);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_simple_cost: inside_cost = %d, "
+ "prologue_cost = %d .", inside_cost, prologue_cost);
}
@@ -862,9 +876,10 @@ vect_model_promotion_demotion_cost (stmt_vec_info stmt_info,
prologue_cost += add_stmt_cost (target_cost_data, 1, vector_stmt,
stmt_info, 0, vect_prologue);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_promotion_demotion_cost: inside_cost = %d, "
- "prologue_cost = %d .", inside_cost, prologue_cost);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_promotion_demotion_cost: inside_cost = %d, "
+ "prologue_cost = %d .", inside_cost, prologue_cost);
}
/* Function vect_cost_group_size
@@ -945,17 +960,19 @@ vect_model_store_cost (stmt_vec_info stmt_info, int ncopies,
inside_cost = record_stmt_cost (body_cost_vec, nstmts, vec_perm,
stmt_info, 0, vect_body);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_store_cost: strided group_size = %d .",
- group_size);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_store_cost: strided group_size = %d .",
+ group_size);
}
/* Costs of the stores. */
vect_get_store_cost (first_dr, ncopies, &inside_cost, body_cost_vec);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_store_cost: inside_cost = %d, "
- "prologue_cost = %d .", inside_cost, prologue_cost);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_store_cost: inside_cost = %d, "
+ "prologue_cost = %d .", inside_cost, prologue_cost);
}
@@ -977,9 +994,9 @@ vect_get_store_cost (struct data_reference *dr, int ncopies,
vector_store, stmt_info, 0,
vect_body);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_store_cost: aligned.");
-
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_store_cost: aligned.");
break;
}
@@ -989,11 +1006,10 @@ vect_get_store_cost (struct data_reference *dr, int ncopies,
*inside_cost += record_stmt_cost (body_cost_vec, ncopies,
unaligned_store, stmt_info,
DR_MISALIGNMENT (dr), vect_body);
-
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_store_cost: unaligned supported by "
- "hardware.");
-
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_store_cost: unaligned supported by "
+ "hardware.");
break;
}
@@ -1001,9 +1017,9 @@ vect_get_store_cost (struct data_reference *dr, int ncopies,
{
*inside_cost = VECT_MAX_COST;
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_store_cost: unsupported access.");
-
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "vect_model_store_cost: unsupported access.");
break;
}
@@ -1060,9 +1076,10 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies,
inside_cost += record_stmt_cost (body_cost_vec, nstmts, vec_perm,
stmt_info, 0, vect_body);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_load_cost: strided group_size = %d .",
- group_size);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: strided group_size = %d .",
+ group_size);
}
/* The loads themselves. */
@@ -1083,9 +1100,10 @@ vect_model_load_cost (stmt_vec_info stmt_info, int ncopies,
&inside_cost, &prologue_cost,
prologue_cost_vec, body_cost_vec, true);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_load_cost: inside_cost = %d, "
- "prologue_cost = %d .", inside_cost, prologue_cost);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: inside_cost = %d, "
+ "prologue_cost = %d .", inside_cost, prologue_cost);
}
@@ -1109,8 +1127,9 @@ vect_get_load_cost (struct data_reference *dr, int ncopies,
*inside_cost += record_stmt_cost (body_cost_vec, ncopies, vector_load,
stmt_info, 0, vect_body);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_load_cost: aligned.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: aligned.");
break;
}
@@ -1121,9 +1140,10 @@ vect_get_load_cost (struct data_reference *dr, int ncopies,
unaligned_load, stmt_info,
DR_MISALIGNMENT (dr), vect_body);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_load_cost: unaligned supported by "
- "hardware.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: unaligned supported by "
+ "hardware.");
break;
}
@@ -1141,16 +1161,18 @@ vect_get_load_cost (struct data_reference *dr, int ncopies,
*inside_cost += record_stmt_cost (body_cost_vec, 1, vector_stmt,
stmt_info, 0, vect_body);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_load_cost: explicit realign");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: explicit realign");
break;
}
case dr_explicit_realign_optimized:
{
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_load_cost: unaligned software "
- "pipelined.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: unaligned software "
+ "pipelined.");
/* Unaligned software pipeline has a load of an address, an initial
load, and possibly a mask operation to "prime" the loop. However,
@@ -1175,9 +1197,9 @@ vect_get_load_cost (struct data_reference *dr, int ncopies,
*inside_cost += record_stmt_cost (body_cost_vec, ncopies, vec_perm,
stmt_info, 0, vect_body);
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump,
- "vect_model_load_cost: explicit realign optimized");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_model_load_cost: explicit realign optimized");
break;
}
@@ -1186,9 +1208,9 @@ vect_get_load_cost (struct data_reference *dr, int ncopies,
{
*inside_cost = VECT_MAX_COST;
- if (vect_print_dump_info (REPORT_COST))
- fprintf (vect_dump, "vect_model_load_cost: unsupported access.");
-
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "vect_model_load_cost: unsupported access.");
break;
}
@@ -1236,10 +1258,11 @@ vect_init_vector_1 (gimple stmt, gimple new_stmt, gimple_stmt_iterator *gsi)
}
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "created new init_stmt: ");
- print_gimple_stmt (vect_dump, new_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "created new init_stmt: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, new_stmt, 0);
}
}
@@ -1317,26 +1340,32 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
bool is_simple_use;
tree vector_type;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "vect_get_vec_def_for_operand: ");
- print_generic_expr (vect_dump, op, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_get_vec_def_for_operand: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, op);
}
is_simple_use = vect_is_simple_use (op, stmt, loop_vinfo, NULL,
&def_stmt, &def, &dt);
gcc_assert (is_simple_use);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
+ int loc_printed = 0;
if (def)
{
- fprintf (vect_dump, "def = ");
- print_generic_expr (vect_dump, def, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "def = ");
+ loc_printed = 1;
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, def);
}
if (def_stmt)
{
- fprintf (vect_dump, " def_stmt = ");
- print_gimple_stmt (vect_dump, def_stmt, 0, TDF_SLIM);
+ if (loc_printed)
+ dump_printf (MSG_NOTE, " def_stmt = ");
+ else
+ dump_printf_loc (MSG_NOTE, vect_location, " def_stmt = ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, def_stmt, 0);
}
}
@@ -1353,8 +1382,9 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
*scalar_def = op;
/* Create 'vect_cst_ = {cst,cst,...,cst}' */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Create vector_cst. nunits = %d", nunits);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Create vector_cst. nunits = %d", nunits);
return vect_init_vector (stmt, op, vector_type, NULL);
}
@@ -1369,8 +1399,8 @@ vect_get_vec_def_for_operand (tree op, gimple stmt, tree *scalar_def)
*scalar_def = def;
/* Create 'vec_inv = {inv,inv,..,inv}' */
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Create vector_inv.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "Create vector_inv.");
return vect_init_vector (stmt, def, vector_type, NULL);
}
@@ -1631,10 +1661,10 @@ vect_finish_stmt_generation (gimple stmt, gimple vec_stmt,
set_vinfo_for_stmt (vec_stmt, new_stmt_vec_info (vec_stmt, loop_vinfo,
bb_vinfo));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "add new stmt: ");
- print_gimple_stmt (vect_dump, vec_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "add new stmt: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, vec_stmt, 0);
}
gimple_set_location (vec_stmt, gimple_location (stmt));
@@ -1734,8 +1764,9 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (rhs_type
&& !types_compatible_p (rhs_type, TREE_TYPE (op)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "argument types differ.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "argument types differ.");
return false;
}
if (!rhs_type)
@@ -1744,8 +1775,9 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (!vect_is_simple_use_1 (op, stmt, loop_vinfo, bb_vinfo,
&def_stmt, &def, &dt[i], &opvectype))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
@@ -1754,8 +1786,9 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
else if (opvectype
&& opvectype != vectype_in)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "argument vector types differ.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "argument vector types differ.");
return false;
}
}
@@ -1767,10 +1800,11 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
gcc_assert (vectype_in);
if (!vectype_in)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "no vectype for scalar type ");
- print_generic_expr (vect_dump, rhs_type, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no vectype for scalar type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, rhs_type);
}
return false;
@@ -1795,8 +1829,9 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
fndecl = vectorizable_function (stmt, vectype_out, vectype_in);
if (fndecl == NULL_TREE)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "function is not vectorizable.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "function is not vectorizable.");
return false;
}
@@ -1817,16 +1852,16 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (!vec_stmt) /* transformation not required. */
{
STMT_VINFO_TYPE (stmt_info) = call_vec_info_type;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vectorizable_call ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_call ===");
vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
return true;
}
/** Transform. **/
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform call.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "transform call.");
/* Handle def. */
scalar_dest = gimple_call_lhs (stmt);
@@ -2340,9 +2375,9 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
&& (TYPE_PRECISION (rhs_type)
!= GET_MODE_PRECISION (TYPE_MODE (rhs_type)))))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump,
- "type conversion to/from bit-precision unsupported.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "type conversion to/from bit-precision unsupported.");
return false;
}
@@ -2350,8 +2385,9 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo,
&def_stmt, &def, &dt[0], &vectype_in))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
if (op_type == binary_op)
@@ -2371,8 +2407,9 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
if (!ok)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
}
@@ -2385,10 +2422,11 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (vectype_in);
if (!vectype_in)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "no vectype for scalar type ");
- print_generic_expr (vect_dump, rhs_type, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no vectype for scalar type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM, rhs_type);
}
return false;
@@ -2428,8 +2466,9 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
break;
/* FALLTHRU */
unsupported:
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "conversion not supported by target.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "conversion not supported by target.");
return false;
case WIDEN:
@@ -2526,8 +2565,9 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
if (!vec_stmt) /* transformation not required. */
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vectorizable_conversion ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vectorizable_conversion ===");
if (code == FIX_TRUNC_EXPR || code == FLOAT_EXPR)
{
STMT_VINFO_TYPE (stmt_info) = type_conversion_vec_info_type;
@@ -2548,8 +2588,9 @@ vectorizable_conversion (gimple stmt, gimple_stmt_iterator *gsi,
}
/** Transform. **/
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform conversion. ncopies = %d.", ncopies);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "transform conversion. ncopies = %d.", ncopies);
if (op_type == binary_op)
{
@@ -2900,8 +2941,9 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
if (!vect_is_simple_use_1 (op, stmt, loop_vinfo, bb_vinfo,
&def_stmt, &def, &dt[0], &vectype_in))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
@@ -2928,24 +2970,26 @@ vectorizable_assignment (gimple stmt, gimple_stmt_iterator *gsi,
> TYPE_PRECISION (TREE_TYPE (op)))
&& TYPE_UNSIGNED (TREE_TYPE (op))))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "type conversion to/from bit-precision "
- "unsupported.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "type conversion to/from bit-precision "
+ "unsupported.");
return false;
}
if (!vec_stmt) /* transformation not required. */
{
STMT_VINFO_TYPE (stmt_info) = assignment_vec_info_type;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vectorizable_assignment ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vectorizable_assignment ===");
vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
return true;
}
/** Transform. **/
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform assignment.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "transform assignment.");
/* Handle def. */
vec_dest = vect_create_destination_var (scalar_dest, vectype);
@@ -3091,8 +3135,9 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
if (TYPE_PRECISION (TREE_TYPE (scalar_dest))
!= GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (scalar_dest))))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bit-precision shifts not supported.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bit-precision shifts not supported.");
return false;
}
@@ -3100,8 +3145,9 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo,
&def_stmt, &def, &dt[0], &vectype))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
/* If op0 is an external or constant def use a vector type with
@@ -3112,12 +3158,9 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (vectype);
if (!vectype)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- {
- fprintf (vect_dump, "no vectype for scalar type ");
- print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM);
- }
-
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no vectype for scalar type ");
return false;
}
@@ -3130,8 +3173,9 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
if (!vect_is_simple_use_1 (op1, stmt, loop_vinfo, bb_vinfo, &def_stmt,
&def, &dt[1], &op1_vectype))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
@@ -3174,8 +3218,9 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
}
else
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "operand mode requires invariant argument.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "operand mode requires invariant argument.");
return false;
}
@@ -3183,16 +3228,19 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
if (!scalar_shift_arg)
{
optab = optab_for_tree_code (code, vectype, optab_vector);
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vector/vector shift/rotate found.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vector/vector shift/rotate found.");
+
if (!op1_vectype)
op1_vectype = get_same_sized_vectype (TREE_TYPE (op1), vectype_out);
if (op1_vectype == NULL_TREE
|| TYPE_MODE (op1_vectype) != TYPE_MODE (vectype))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unusable type for last operand in"
- " vector/vector shift/rotate.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unusable type for last operand in"
+ " vector/vector shift/rotate.");
return false;
}
}
@@ -3204,8 +3252,9 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
if (optab
&& optab_handler (optab, TYPE_MODE (vectype)) != CODE_FOR_nothing)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vector/scalar shift/rotate found.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vector/scalar shift/rotate found.");
}
else
{
@@ -3216,8 +3265,9 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
{
scalar_shift_arg = false;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "vector/vector shift/rotate found.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vector/vector shift/rotate found.");
/* Unlike the other binary operators, shifts/rotates have
the rhs being int, instead of the same type as the lhs,
@@ -3232,9 +3282,10 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
&& TYPE_MODE (TREE_TYPE (vectype))
!= TYPE_MODE (TREE_TYPE (op1)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unusable type for last operand in"
- " vector/vector shift/rotate.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unusable type for last operand in"
+ " vector/vector shift/rotate.");
return false;
}
if (vec_stmt && !slp_node)
@@ -3251,23 +3302,25 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
/* Supportable by target? */
if (!optab)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no optab.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no optab.");
return false;
}
vec_mode = TYPE_MODE (vectype);
icode = (int) optab_handler (optab, vec_mode);
if (icode == CODE_FOR_nothing)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "op not supported by target.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "op not supported by target.");
/* Check only during analysis. */
if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
|| (vf < vect_min_worthwhile_factor (code)
&& !vec_stmt))
return false;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "proceeding using word mode.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "proceeding using word mode.");
}
/* Worthwhile without SIMD support? Check only during analysis. */
@@ -3275,24 +3328,26 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
&& vf < vect_min_worthwhile_factor (code)
&& !vec_stmt)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "not worthwhile without SIMD support.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not worthwhile without SIMD support.");
return false;
}
if (!vec_stmt) /* transformation not required. */
{
STMT_VINFO_TYPE (stmt_info) = shift_vec_info_type;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vectorizable_shift ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "=== vectorizable_shift ===");
vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
return true;
}
/** Transform. **/
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform binary/unary operation.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "transform binary/unary operation.");
/* Handle def. */
vec_dest = vect_create_destination_var (scalar_dest, vectype);
@@ -3327,8 +3382,9 @@ vectorizable_shift (gimple stmt, gimple_stmt_iterator *gsi,
optab_op2_mode = insn_data[icode].operand[2].mode;
if (!VECTOR_MODE_P (optab_op2_mode))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "operand 1 using scalar mode.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "operand 1 using scalar mode.");
vec_oprnd1 = op1;
VEC_quick_push (tree, vec_oprnds1, vec_oprnd1);
if (slp_node)
@@ -3454,9 +3510,10 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
op_type = TREE_CODE_LENGTH (code);
if (op_type != unary_op && op_type != binary_op && op_type != ternary_op)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "num. args = %d (not unary/binary/ternary op).",
- op_type);
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "num. args = %d (not unary/binary/ternary op).",
+ op_type);
return false;
}
@@ -3472,8 +3529,9 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
&& code != BIT_XOR_EXPR
&& code != BIT_AND_EXPR)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "bit-precision arithmetic not supported.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "bit-precision arithmetic not supported.");
return false;
}
@@ -3481,8 +3539,9 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
if (!vect_is_simple_use_1 (op0, stmt, loop_vinfo, bb_vinfo,
&def_stmt, &def, &dt[0], &vectype))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
/* If op0 is an external or constant def use a vector type with
@@ -3493,10 +3552,12 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
gcc_assert (vectype);
if (!vectype)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "no vectype for scalar type ");
- print_generic_expr (vect_dump, TREE_TYPE (op0), TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no vectype for scalar type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ TREE_TYPE (op0));
}
return false;
@@ -3513,8 +3574,9 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
if (!vect_is_simple_use (op1, stmt, loop_vinfo, bb_vinfo, &def_stmt,
&def, &dt[1]))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
}
@@ -3524,8 +3586,9 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
if (!vect_is_simple_use (op2, stmt, loop_vinfo, bb_vinfo, &def_stmt,
&def, &dt[2]))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
}
@@ -3565,8 +3628,9 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
optab = optab_for_tree_code (code, vectype, optab_default);
if (!optab)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no optab.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no optab.");
return false;
}
icode = (int) optab_handler (optab, vec_mode);
@@ -3574,14 +3638,15 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
if (icode == CODE_FOR_nothing)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "op not supported by target.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "op not supported by target.");
/* Check only during analysis. */
if (GET_MODE_SIZE (vec_mode) != UNITS_PER_WORD
|| (!vec_stmt && vf < vect_min_worthwhile_factor (code)))
return false;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "proceeding using word mode.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "proceeding using word mode.");
}
/* Worthwhile without SIMD support? Check only during analysis. */
@@ -3589,24 +3654,27 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
&& !vec_stmt
&& vf < vect_min_worthwhile_factor (code))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "not worthwhile without SIMD support.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not worthwhile without SIMD support.");
return false;
}
if (!vec_stmt) /* transformation not required. */
{
STMT_VINFO_TYPE (stmt_info) = op_vec_info_type;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "=== vectorizable_operation ===");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "=== vectorizable_operation ===");
vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL);
return true;
}
/** Transform. **/
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform binary/unary operation.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "transform binary/unary operation.");
/* Handle def. */
vec_dest = vect_create_destination_var (scalar_dest, vectype);
@@ -3792,8 +3860,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
/* FORNOW. This restriction should be relaxed. */
if (loop && nested_in_vect_loop_p (loop, stmt) && ncopies > 1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "multiple types in nested loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "multiple types in nested loop.");
return false;
}
@@ -3825,8 +3894,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (!vect_is_simple_use (op, stmt, loop_vinfo, bb_vinfo, &def_stmt,
&def, &dt))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
@@ -3845,8 +3915,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
? STMT_VINFO_DR_STEP (stmt_info) : DR_STEP (dr),
size_zero_node) < 0)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "negative step for store.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "negative step for store.");
return false;
}
@@ -3875,8 +3946,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (!vect_is_simple_use (op, next_stmt, loop_vinfo, bb_vinfo,
&def_stmt, &def, &dt))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "use not simple.");
return false;
}
next_stmt = GROUP_NEXT_ELEMENT (vinfo_for_stmt (next_stmt));
@@ -3936,8 +4008,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
group_size = vec_num = 1;
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform store. ncopies = %d",ncopies);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "transform store. ncopies = %d", ncopies);
dr_chain = VEC_alloc (tree, heap, group_size);
oprnds = VEC_alloc (tree, heap, group_size);
@@ -4323,8 +4396,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
/* FORNOW. This restriction should be relaxed. */
if (nested_in_vect_loop && ncopies > 1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "multiple types in nested loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "multiple types in nested loop.");
return false;
}
@@ -4362,8 +4436,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
(e.g. - data copies). */
if (optab_handler (mov_optab, mode) == CODE_FOR_nothing)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Aligned load, but unsupported type.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Aligned load, but unsupported type.");
return false;
}
@@ -4397,8 +4472,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
&def_stmt, &def, &gather_dt,
&gather_off_vectype))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "gather index use not simple.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "gather index use not simple.");
return false;
}
}
@@ -4416,8 +4492,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
size_zero_node) < 0;
if (negative && ncopies > 1)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "multiple types with negative step.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "multiple types with negative step.");
return false;
}
@@ -4428,14 +4505,16 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (alignment_support_scheme != dr_aligned
&& alignment_support_scheme != dr_unaligned_supported)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "negative step but alignment required.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "negative step but alignment required.");
return false;
}
if (!perm_mask_for_reverse (vectype))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "negative step and reversing not supported.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "negative step and reversing not supported.");
return false;
}
}
@@ -4448,8 +4527,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
return true;
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "transform load. ncopies = %d", ncopies);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "transform load. ncopies = %d", ncopies);
/** Transform. **/
@@ -5248,8 +5328,9 @@ vectorizable_condition (gimple stmt, gimple_stmt_iterator *gsi,
/* FORNOW: not yet supported. */
if (STMT_VINFO_LIVE_P (stmt_info))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "value used after loop.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "value used after loop.");
return false;
}
@@ -5447,16 +5528,17 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
gimple pattern_stmt;
gimple_seq pattern_def_seq;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> examining statement: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "==> examining statement: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
if (gimple_has_volatile_ops (stmt))
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
- fprintf (vect_dump, "not vectorized: stmt has volatile operands");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: stmt has volatile operands");
return false;
}
@@ -5487,16 +5569,17 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
/* Analyze PATTERN_STMT instead of the original stmt. */
stmt = pattern_stmt;
stmt_info = vinfo_for_stmt (pattern_stmt);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> examining pattern statement: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "==> examining pattern statement: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
}
else
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "irrelevant.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "irrelevant.");
return true;
}
@@ -5508,10 +5591,11 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
|| STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_stmt))))
{
/* Analyze PATTERN_STMT too. */
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> examining pattern statement: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "==> examining pattern statement: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, stmt, 0);
}
if (!vect_analyze_stmt (pattern_stmt, need_to_vectorize, node))
@@ -5531,10 +5615,11 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
|| STMT_VINFO_LIVE_P (vinfo_for_stmt (pattern_def_stmt)))
{
/* Analyze def stmt of STMT if it's a pattern stmt. */
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "==> examining pattern def statement: ");
- print_gimple_stmt (vect_dump, pattern_def_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "==> examining pattern def statement: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, pattern_def_stmt, 0);
}
if (!vect_analyze_stmt (pattern_def_stmt,
@@ -5569,27 +5654,30 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
gcc_assert (PURE_SLP_STMT (stmt_info));
scalar_type = TREE_TYPE (gimple_get_lhs (stmt));
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "get vectype for scalar type: ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "get vectype for scalar type: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type);
}
vectype = get_vectype_for_scalar_type (scalar_type);
if (!vectype)
{
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not SLPed: unsupported data-type ");
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not SLPed: unsupported data-type ");
+ dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
+ scalar_type);
}
return false;
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "vectype: ");
- print_generic_expr (vect_dump, vectype, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "vectype: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, vectype);
}
STMT_VINFO_VECTYPE (stmt_info) = vectype;
@@ -5630,11 +5718,12 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
if (!ok)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: relevant stmt not ");
- fprintf (vect_dump, "supported: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: relevant stmt not ");
+ dump_printf (MSG_MISSED_OPTIMIZATION, "supported: ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
@@ -5651,11 +5740,12 @@ vect_analyze_stmt (gimple stmt, bool *need_to_vectorize, slp_tree node)
if (!ok)
{
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS))
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
{
- fprintf (vect_dump, "not vectorized: live stmt not ");
- fprintf (vect_dump, "supported: ");
- print_gimple_stmt (vect_dump, stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not vectorized: live stmt not ");
+ dump_printf (MSG_MISSED_OPTIMIZATION, "supported: ");
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
}
return false;
@@ -5750,8 +5840,9 @@ vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi,
default:
if (!STMT_VINFO_LIVE_P (stmt_info))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "stmt not supported.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "stmt not supported.");
gcc_unreachable ();
}
}
@@ -5774,8 +5865,9 @@ vect_transform_stmt (gimple stmt, gimple_stmt_iterator *gsi,
tree scalar_dest;
gimple exit_phi;
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Record the vdef for outer-loop vectorization.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "Record the vdef for outer-loop vectorization.");
/* Find the relevant loop-exit phi-node, and reord the vec_stmt there
(to be used when vectorizing outer-loop stmts that use the DEF of
@@ -6005,26 +6097,28 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
return NULL_TREE;
vectype = build_vector_type (scalar_type, nunits);
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "get vectype with %d units of type ", nunits);
- print_generic_expr (vect_dump, scalar_type, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "get vectype with %d units of type ", nunits);
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, scalar_type);
}
if (!vectype)
return NULL_TREE;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "vectype: ");
- print_generic_expr (vect_dump, vectype, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "vectype: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, vectype);
}
if (!VECTOR_MODE_P (TYPE_MODE (vectype))
&& !INTEGRAL_MODE_P (TYPE_MODE (vectype)))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "mode not supported by target.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "mode not supported by target.");
return NULL_TREE;
}
@@ -6093,10 +6187,11 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo,
*def_stmt = NULL;
*def = NULL_TREE;
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "vect_is_simple_use: operand ");
- print_generic_expr (vect_dump, operand, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "vect_is_simple_use: operand ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, operand);
}
if (CONSTANT_CLASS_P (operand))
@@ -6114,30 +6209,32 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo,
if (TREE_CODE (operand) == PAREN_EXPR)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "non-associatable copy.");
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "non-associatable copy.");
operand = TREE_OPERAND (operand, 0);
}
if (TREE_CODE (operand) != SSA_NAME)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "not ssa-name.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "not ssa-name.");
return false;
}
*def_stmt = SSA_NAME_DEF_STMT (operand);
if (*def_stmt == NULL)
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "no def_stmt.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "no def_stmt.");
return false;
}
- if (vect_print_dump_info (REPORT_DETAILS))
+ if (dump_kind_p (MSG_NOTE))
{
- fprintf (vect_dump, "def_stmt: ");
- print_gimple_stmt (vect_dump, *def_stmt, 0, TDF_SLIM);
+ dump_printf_loc (MSG_NOTE, vect_location, "def_stmt: ");
+ dump_gimple_stmt (MSG_NOTE, TDF_SLIM, *def_stmt, 0);
}
/* Empty stmt is expected only in case of a function argument.
@@ -6166,13 +6263,14 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo,
&& *dt == vect_double_reduction_def
&& gimple_code (stmt) != GIMPLE_PHI))
{
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "Unsupported pattern.");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "Unsupported pattern.");
return false;
}
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "type of def: %d.",*dt);
+ if (dump_kind_p (MSG_NOTE))
+ dump_printf_loc (MSG_NOTE, vect_location, "type of def: %d.", *dt);
switch (gimple_code (*def_stmt))
{
@@ -6190,8 +6288,9 @@ vect_is_simple_use (tree operand, gimple stmt, loop_vec_info loop_vinfo,
break;
/* FALLTHRU */
default:
- if (vect_print_dump_info (REPORT_DETAILS))
- fprintf (vect_dump, "unsupported defining stmt: ");
+ if (dump_kind_p (MSG_MISSED_OPTIMIZATION))
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "unsupported defining stmt: ");
return false;
}
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 8856a2c51..4bd0e9b26 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "dumpfile.h"
#include "tm.h"
#include "ggc.h"
#include "tree.h"
@@ -67,13 +68,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-vectorizer.h"
#include "tree-pass.h"
-/* vect_dump will be set to stderr or dump_file if exist. */
-FILE *vect_dump;
-
-/* vect_verbosity_level set to an invalid value
- to mark that it's uninitialized. */
-static enum vect_verbosity_levels vect_verbosity_level = MAX_VERBOSITY_LEVEL;
-
/* Loop or bb location. */
LOC vect_location;
@@ -81,82 +75,6 @@ LOC vect_location;
VEC(vec_void_p,heap) *stmt_vec_info_vec;
-
-/* Function vect_set_dump_settings.
-
- Fix the verbosity level of the vectorizer if the
- requested level was not set explicitly using the flag
- -ftree-vectorizer-verbose=N.
- Decide where to print the debugging information (dump_file/stderr).
- If the user defined the verbosity level, but there is no dump file,
- print to stderr, otherwise print to the dump file. */
-
-static void
-vect_set_dump_settings (bool slp)
-{
- vect_dump = dump_file;
-
- /* Check if the verbosity level was defined by the user: */
- if (user_vect_verbosity_level != MAX_VERBOSITY_LEVEL)
- {
- vect_verbosity_level = user_vect_verbosity_level;
- /* Ignore user defined verbosity if dump flags require higher level of
- verbosity. */
- if (dump_file)
- {
- if (((dump_flags & TDF_DETAILS)
- && vect_verbosity_level >= REPORT_DETAILS)
- || ((dump_flags & TDF_STATS)
- && vect_verbosity_level >= REPORT_UNVECTORIZED_LOCATIONS))
- return;
- }
- else
- {
- /* If there is no dump file, print to stderr in case of loop
- vectorization. */
- if (!slp)
- vect_dump = stderr;
-
- return;
- }
- }
-
- /* User didn't specify verbosity level: */
- if (dump_file && (dump_flags & TDF_DETAILS))
- vect_verbosity_level = REPORT_DETAILS;
- else if (dump_file && (dump_flags & TDF_STATS))
- vect_verbosity_level = REPORT_UNVECTORIZED_LOCATIONS;
- else
- vect_verbosity_level = REPORT_NONE;
-
- gcc_assert (dump_file || vect_verbosity_level == REPORT_NONE);
-}
-
-
-/* Function debug_loop_details.
-
- For vectorization debug dumps. */
-
-bool
-vect_print_dump_info (enum vect_verbosity_levels vl)
-{
- if (vl > vect_verbosity_level)
- return false;
-
- if (!current_function_decl || !vect_dump)
- return false;
-
- if (vect_location == UNKNOWN_LOC)
- fprintf (vect_dump, "\n%s:%d: note: ",
- DECL_SOURCE_FILE (current_function_decl),
- DECL_SOURCE_LINE (current_function_decl));
- else
- fprintf (vect_dump, "\n%d: ", LOC_LINE (vect_location));
-
- return true;
-}
-
-
/* Function vectorize_loops.
Entry point to loop vectorization phase. */
@@ -176,9 +94,6 @@ vectorize_loops (void)
if (vect_loops_num <= 1)
return 0;
- /* Fix the verbosity level if not defined explicitly by the user. */
- vect_set_dump_settings (false);
-
init_stmt_vec_info_vec ();
/* ----------- Analyze loops. ----------- */
@@ -190,12 +105,11 @@ vectorize_loops (void)
if (optimize_loop_nest_for_speed_p (loop))
{
loop_vec_info loop_vinfo;
-
vect_location = find_loop_location (loop);
- if (vect_location != UNKNOWN_LOC
- && vect_verbosity_level > REPORT_NONE)
- fprintf (vect_dump, "\nAnalyzing loop at %s:%d\n",
- LOC_FILE (vect_location), LOC_LINE (vect_location));
+ if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC
+ && dump_kind_p (MSG_ALL))
+ dump_printf (MSG_ALL, "\nAnalyzing loop at %s:%d\n",
+ LOC_FILE (vect_location), LOC_LINE (vect_location));
loop_vinfo = vect_analyze_loop (loop);
loop->aux = loop_vinfo;
@@ -203,11 +117,10 @@ vectorize_loops (void)
if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
continue;
- if (vect_location != UNKNOWN_LOC
- && vect_verbosity_level > REPORT_NONE)
- fprintf (vect_dump, "\n\nVectorizing loop at %s:%d\n",
- LOC_FILE (vect_location), LOC_LINE (vect_location));
-
+ if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC
+ && dump_kind_p (MSG_ALL))
+ dump_printf (MSG_ALL, "\n\nVectorizing loop at %s:%d\n",
+ LOC_FILE (vect_location), LOC_LINE (vect_location));
vect_transform_loop (loop_vinfo);
num_vectorized_loops++;
}
@@ -215,11 +128,11 @@ vectorize_loops (void)
vect_location = UNKNOWN_LOC;
statistics_counter_event (cfun, "Vectorized loops", num_vectorized_loops);
- if (vect_print_dump_info (REPORT_UNVECTORIZED_LOCATIONS)
- || (num_vectorized_loops > 0
- && vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS)))
- fprintf (vect_dump, "vectorized %u loops in function.\n",
- num_vectorized_loops);
+ if (dump_kind_p (MSG_ALL)
+ || (num_vectorized_loops > 0 && dump_kind_p (MSG_ALL)))
+ dump_printf_loc (MSG_ALL, vect_location,
+ "vectorized %u loops in function.\n",
+ num_vectorized_loops);
/* ----------- Finalize. ----------- */
@@ -248,9 +161,6 @@ execute_vect_slp (void)
{
basic_block bb;
- /* Fix the verbosity level if not defined explicitly by the user. */
- vect_set_dump_settings (true);
-
init_stmt_vec_info_vec ();
FOR_EACH_BB (bb)
@@ -260,9 +170,9 @@ execute_vect_slp (void)
if (vect_slp_analyze_bb (bb))
{
vect_slp_transform_bb (bb);
-
- if (vect_print_dump_info (REPORT_VECTORIZED_LOCATIONS))
- fprintf (vect_dump, "basic block vectorized using SLP\n");
+ if (dump_kind_p (MSG_OPTIMIZED_LOCATIONS))
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "basic block vectorized using SLP\n");
}
}
@@ -335,12 +245,9 @@ increase_alignment (void)
{
DECL_ALIGN (decl) = TYPE_ALIGN (vectype);
DECL_USER_ALIGN (decl) = 1;
- if (dump_file)
- {
- fprintf (dump_file, "Increasing alignment of decl: ");
- print_generic_expr (dump_file, decl, TDF_SLIM);
- fprintf (dump_file, "\n");
- }
+ dump_printf (MSG_NOTE, "Increasing alignment of decl: ");
+ dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
+ dump_printf (MSG_NOTE, "\n");
}
}
return 0;
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index bad0fa241..5762e00b6 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -848,9 +848,8 @@ known_alignment_for_access_p (struct data_reference *data_ref_info)
return (DR_MISALIGNMENT (data_ref_info) != -1);
}
-/* vect_dump will be set to stderr or dump_file if exist. */
-extern FILE *vect_dump;
-extern LOC vect_loop_location;
+/* Source location */
+extern LOC vect_location;
/*-----------------------------------------------------------------*/
/* Function prototypes. */
@@ -977,7 +976,6 @@ extern bool vectorizable_live_operation (gimple, gimple_stmt_iterator *,
extern bool vectorizable_reduction (gimple, gimple_stmt_iterator *, gimple *,
slp_tree);
extern bool vectorizable_induction (gimple, gimple_stmt_iterator *, gimple *);
-extern int vect_estimate_min_profitable_iters (loop_vec_info);
extern tree get_initial_def_for_reduction (gimple, tree, tree *);
extern int vect_min_worthwhile_factor (enum tree_code);
extern int vect_get_known_peeling_cost (loop_vec_info, int, int *, int,
@@ -1012,7 +1010,5 @@ void vect_pattern_recog (loop_vec_info, bb_vec_info);
/* In tree-vectorizer.c. */
unsigned vectorize_loops (void);
-/* Vectorization debug information */
-extern bool vect_print_dump_info (enum vect_verbosity_levels);
#endif /* GCC_TREE_VECTORIZER_H */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index b728dddb8..de3eb2c6a 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -4712,6 +4712,11 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
tree val2 = NULL_TREE;
double_int mask = double_int_zero;
unsigned int prec = TYPE_PRECISION (TREE_TYPE (val));
+ 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);
/* Add asserts for NAME cmp CST and NAME being defined
as NAME = (int) NAME2. */
@@ -4721,7 +4726,7 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
&& gimple_assign_cast_p (def_stmt))
{
name2 = gimple_assign_rhs1 (def_stmt);
- if (CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
+ if (CONVERT_EXPR_CODE_P (rhs_code)
&& INTEGRAL_TYPE_P (TREE_TYPE (name2))
&& TYPE_UNSIGNED (TREE_TYPE (name2))
&& prec == TYPE_PRECISION (TREE_TYPE (name2))
@@ -4767,8 +4772,7 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
NAME = NAME2 >> CST2.
Extract CST2 from the right shift. */
- if (is_gimple_assign (def_stmt)
- && gimple_assign_rhs_code (def_stmt) == RSHIFT_EXPR)
+ if (rhs_code == RSHIFT_EXPR)
{
name2 = gimple_assign_rhs1 (def_stmt);
cst2 = gimple_assign_rhs2 (def_stmt);
@@ -4840,21 +4844,37 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
/* Add asserts for NAME cmp CST and NAME being defined as
NAME = NAME2 & CST2.
- Extract CST2 from the and. */
+ 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 (is_gimple_assign (def_stmt)
- && gimple_assign_rhs_code (def_stmt) == BIT_AND_EXPR)
+ if (rhs_code == BIT_AND_EXPR
+ || (CONVERT_EXPR_CODE_P (rhs_code)
+ && TREE_CODE (TREE_TYPE (val)) == INTEGER_TYPE
+ && TYPE_UNSIGNED (TREE_TYPE (val))
+ && TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (def_stmt)))
+ > prec
+ && !retval))
{
name2 = gimple_assign_rhs1 (def_stmt);
- cst2 = gimple_assign_rhs2 (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)
- && prec <= HOST_BITS_PER_DOUBLE_INT
- && (prec > 1
+ && nprec <= HOST_BITS_PER_DOUBLE_INT
+ && (nprec > 1
|| TYPE_UNSIGNED (TREE_TYPE (val))))
{
gimple def_stmt2 = SSA_NAME_DEF_STMT (name2);
@@ -4881,12 +4901,12 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
bool valid_p = false, valn = false, cst2n = false;
enum tree_code ccode = comp_code;
- valv = tree_to_double_int (val).zext (prec);
- cst2v = tree_to_double_int (cst2).zext (prec);
+ valv = tree_to_double_int (val).zext (nprec);
+ cst2v = tree_to_double_int (cst2).zext (nprec);
if (!TYPE_UNSIGNED (TREE_TYPE (val)))
{
- valn = valv.sext (prec).is_negative ();
- cst2n = cst2v.sext (prec).is_negative ();
+ valn = valv.sext (nprec).is_negative ();
+ cst2n = cst2v.sext (nprec).is_negative ();
}
/* If CST2 doesn't have most significant bit set,
but VAL is negative, we have comparison like
@@ -4894,7 +4914,7 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
if (!cst2n && valn)
ccode = ERROR_MARK;
if (cst2n)
- sgnbit = double_int_one.llshift (prec - 1, prec).zext (prec);
+ sgnbit = double_int_one.llshift (nprec - 1, nprec).zext (nprec);
else
sgnbit = double_int_zero;
minv = valv & cst2v;
@@ -4906,12 +4926,12 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
have folded the comparison into false) and
maximum unsigned value is VAL | ~CST2. */
maxv = valv | ~cst2v;
- maxv = maxv.zext (prec);
+ maxv = maxv.zext (nprec);
valid_p = true;
break;
case NE_EXPR:
tem = valv | ~cst2v;
- tem = tem.zext (prec);
+ tem = tem.zext (nprec);
/* If VAL is 0, handle (X & CST2) != 0 as (X & CST2) > 0U. */
if (valv.is_zero ())
{
@@ -4921,7 +4941,7 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
}
/* If (VAL | ~CST2) is all ones, handle it as
(X & CST2) < VAL. */
- if (tem == double_int::mask (prec))
+ if (tem == double_int::mask (nprec))
{
cst2n = false;
valn = false;
@@ -4929,8 +4949,9 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
goto lt_expr;
}
if (!cst2n
- && cst2v.sext (prec).is_negative ())
- sgnbit = double_int_one.llshift (prec - 1, prec).zext (prec);
+ && cst2v.sext (nprec).is_negative ())
+ sgnbit
+ = double_int_one.llshift (nprec - 1, nprec).zext (nprec);
if (!sgnbit.is_zero ())
{
if (valv == sgnbit)
@@ -4939,7 +4960,7 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
valn = true;
goto gt_expr;
}
- if (tem == double_int::mask (prec - 1))
+ if (tem == double_int::mask (nprec - 1))
{
cst2n = true;
goto lt_expr;
@@ -4958,22 +4979,22 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
{
/* If (VAL & CST2) != VAL, X & CST2 can't be equal to
VAL. */
- minv = masked_increment (valv, cst2v, sgnbit, prec);
+ minv = masked_increment (valv, cst2v, sgnbit, nprec);
if (minv == valv)
break;
}
- maxv = double_int::mask (prec - (cst2n ? 1 : 0));
+ maxv = double_int::mask (nprec - (cst2n ? 1 : 0));
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 << (prec - 1). */
- minv = masked_increment (valv, cst2v, sgnbit, prec);
+ CST2 has MSB set, compute it biased by 1 << (nprec - 1). */
+ minv = masked_increment (valv, cst2v, sgnbit, nprec);
if (minv == valv)
break;
- maxv = double_int::mask (prec - (cst2n ? 1 : 0));
+ maxv = double_int::mask (nprec - (cst2n ? 1 : 0));
valid_p = true;
break;
case LE_EXPR:
@@ -4989,13 +5010,13 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
maxv = valv;
else
{
- maxv = masked_increment (valv, cst2v, sgnbit, prec);
+ maxv = masked_increment (valv, cst2v, sgnbit, nprec);
if (maxv == valv)
break;
maxv -= double_int_one;
}
maxv |= ~cst2v;
- maxv = maxv.zext (prec);
+ maxv = maxv.zext (nprec);
minv = sgnbit;
valid_p = true;
break;
@@ -5017,13 +5038,13 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
}
else
{
- maxv = masked_increment (valv, cst2v, sgnbit, prec);
+ maxv = masked_increment (valv, cst2v, sgnbit, nprec);
if (maxv == valv)
break;
}
maxv -= double_int_one;
maxv |= ~cst2v;
- maxv = maxv.zext (prec);
+ maxv = maxv.zext (nprec);
minv = sgnbit;
valid_p = true;
break;
@@ -5031,7 +5052,7 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
break;
}
if (valid_p
- && (maxv - minv).zext (prec) != double_int::mask (prec))
+ && (maxv - minv).zext (nprec) != double_int::mask (nprec))
{
tree tmp, new_val, type;
int i;
@@ -5044,7 +5065,7 @@ register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi,
type = TREE_TYPE (names[i]);
if (!TYPE_UNSIGNED (type))
{
- type = build_nonstandard_integer_type (prec, 1);
+ type = build_nonstandard_integer_type (nprec, 1);
tmp = build1 (NOP_EXPR, type, names[i]);
}
if (!minv.is_zero ())
diff --git a/gcc/tree.h b/gcc/tree.h
index 0130ce464..ff4ae52e2 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -712,6 +712,9 @@ struct GTY(()) tree_base {
SSA_NAME_IS_DEFAULT_DEF in
SSA_NAME
+
+ DECL_NONLOCAL_FRAME in
+ VAR_DECL
*/
struct GTY(()) tree_typed {
@@ -3270,9 +3273,14 @@ extern void decl_fini_priority_insert (tree, priority_type);
libraries. */
#define MAX_RESERVED_INIT_PRIORITY 100
+/* In a VAR_DECL, nonzero if this is a global variable for VOPs. */
#define VAR_DECL_IS_VIRTUAL_OPERAND(NODE) \
(VAR_DECL_CHECK (NODE)->base.u.bits.saturating_flag)
+/* In a VAR_DECL, nonzero if this is a non-local frame structure. */
+#define DECL_NONLOCAL_FRAME(NODE) \
+ (VAR_DECL_CHECK (NODE)->base.default_def_flag)
+
struct GTY(()) tree_var_decl {
struct tree_decl_with_vis common;
};
@@ -6266,7 +6274,6 @@ tree target_for_debug_bind (tree);
/* In tree-ssa-address.c. */
extern tree tree_mem_ref_addr (tree, tree);
-extern void copy_mem_ref_info (tree, tree);
extern void copy_ref_info (tree, tree);
/* In tree-vrp.c */
diff --git a/gcc/valtrack.c b/gcc/valtrack.c
index 2cdb06b17..52f5ed653 100644
--- a/gcc/valtrack.c
+++ b/gcc/valtrack.c
@@ -182,14 +182,108 @@ propagate_for_debug (rtx insn, rtx last, rtx dest, rtx src,
}
/* Initialize DEBUG to an empty list, and clear USED, if given. */
+
+void
+dead_debug_global_init (struct dead_debug_global *debug, bitmap used)
+{
+ debug->used = used;
+ if (used)
+ bitmap_clear (used);
+}
+
+/* Initialize DEBUG to an empty list, and clear USED, if given. Link
+ back to GLOBAL, if given, and bring in used bits from it. */
+
void
-dead_debug_init (struct dead_debug *debug, bitmap used)
+dead_debug_local_init (struct dead_debug_local *debug, bitmap used,
+ struct dead_debug_global *global)
{
+ if (!used && global && global->used)
+ used = BITMAP_ALLOC (NULL);
+
debug->head = NULL;
+ debug->global = global;
debug->used = used;
debug->to_rescan = NULL;
+
if (used)
- bitmap_clear (used);
+ {
+ if (global && global->used)
+ bitmap_copy (used, global->used);
+ else
+ bitmap_clear (used);
+ }
+}
+
+/* Locate the entry for REG in GLOBAL->htab. */
+
+static dead_debug_global_entry *
+dead_debug_global_find (struct dead_debug_global *global, rtx reg)
+{
+ dead_debug_global_entry temp_entry;
+ temp_entry.reg = reg;
+
+ dead_debug_global_entry *entry = global->htab.find (&temp_entry);
+ gcc_checking_assert (entry && entry->reg == temp_entry.reg);
+ gcc_checking_assert (entry->dtemp);
+
+ return entry;
+}
+
+/* Insert an entry mapping REG to DTEMP in GLOBAL->htab. */
+
+static void
+dead_debug_global_insert (struct dead_debug_global *global, rtx reg, rtx dtemp)
+{
+ dead_debug_global_entry temp_entry;
+ temp_entry.reg = reg;
+ temp_entry.dtemp = dtemp;
+
+ if (!global->htab.is_created ())
+ global->htab.create (31);
+
+ dead_debug_global_entry **slot = global->htab.find_slot (&temp_entry, INSERT);
+ gcc_checking_assert (!*slot);
+ *slot = XNEW (dead_debug_global_entry);
+ **slot = temp_entry;
+}
+
+/* If UREGNO, referenced by USE, is a pseudo marked as used in GLOBAL,
+ replace it with with a USE of the debug temp recorded for it, and
+ return TRUE. Otherwise, just return FALSE.
+
+ If PTO_RESCAN is given, instead of rescanning modified INSNs right
+ away, add their UIDs to the bitmap, allocating one of *PTO_RESCAN
+ is NULL. */
+
+static bool
+dead_debug_global_replace_temp (struct dead_debug_global *global,
+ df_ref use, unsigned int uregno,
+ bitmap *pto_rescan)
+{
+ if (!global || uregno < FIRST_PSEUDO_REGISTER
+ || !global->used
+ || !bitmap_bit_p (global->used, uregno))
+ return false;
+
+ gcc_checking_assert (REGNO (*DF_REF_REAL_LOC (use)) == uregno);
+
+ dead_debug_global_entry *entry
+ = dead_debug_global_find (global, *DF_REF_REAL_LOC (use));
+ gcc_checking_assert (GET_CODE (entry->reg) == REG
+ && REGNO (entry->reg) == uregno);
+
+ *DF_REF_REAL_LOC (use) = entry->dtemp;
+ if (!pto_rescan)
+ df_insn_rescan (DF_REF_INSN (use));
+ else
+ {
+ if (!*pto_rescan)
+ *pto_rescan = BITMAP_ALLOC (NULL);
+ bitmap_set_bit (*pto_rescan, INSN_UID (DF_REF_INSN (use)));
+ }
+
+ return true;
}
/* Reset all debug uses in HEAD, and clear DEBUG->to_rescan bits of
@@ -199,7 +293,8 @@ dead_debug_init (struct dead_debug *debug, bitmap used)
will be removed, and only then rescanned. */
static void
-dead_debug_reset_uses (struct dead_debug *debug, struct dead_debug_use *head)
+dead_debug_reset_uses (struct dead_debug_local *debug,
+ struct dead_debug_use *head)
{
bool got_head = (debug->head == head);
bitmap rescan;
@@ -258,15 +353,57 @@ dead_debug_reset_uses (struct dead_debug *debug, struct dead_debug_use *head)
BITMAP_FREE (rescan);
}
+/* Promote pending local uses of pseudos in DEBUG to global
+ substitutions. Uses of non-pseudos are left alone for
+ resetting. */
+
+static void
+dead_debug_promote_uses (struct dead_debug_local *debug)
+{
+ for (struct dead_debug_use *head = debug->head, **headp = &debug->head;
+ head; head = *headp)
+ {
+ rtx reg = *DF_REF_REAL_LOC (head->use);
+
+ if (GET_CODE (reg) != REG
+ || REGNO (reg) < FIRST_PSEUDO_REGISTER)
+ {
+ headp = &head->next;
+ continue;
+ }
+
+ if (!debug->global->used)
+ debug->global->used = BITMAP_ALLOC (NULL);
+
+ if (bitmap_set_bit (debug->global->used, REGNO (reg)))
+ dead_debug_global_insert (debug->global, reg,
+ make_debug_expr_from_rtl (reg));
+
+ if (!dead_debug_global_replace_temp (debug->global, head->use,
+ REGNO (reg), &debug->to_rescan))
+ {
+ headp = &head->next;
+ continue;
+ }
+
+ *headp = head->next;
+ XDELETE (head);
+ }
+}
+
/* Reset all debug insns with pending uses. Release the bitmap in it,
unless it is USED. USED must be the same bitmap passed to
- dead_debug_init. */
+ dead_debug_local_init. */
+
void
-dead_debug_finish (struct dead_debug *debug, bitmap used)
+dead_debug_local_finish (struct dead_debug_local *debug, bitmap used)
{
if (debug->used != used)
BITMAP_FREE (debug->used);
+ if (debug->global)
+ dead_debug_promote_uses (debug);
+
dead_debug_reset_uses (debug, debug->head);
if (debug->to_rescan)
@@ -284,11 +421,30 @@ dead_debug_finish (struct dead_debug *debug, bitmap used)
}
}
-/* Add USE to DEBUG. It must be a dead reference to UREGNO in a debug
- insn. Create a bitmap for DEBUG as needed. */
+/* Release GLOBAL->used unless it is the same as USED. Release the
+ mapping hash table if it was initialized. */
+
+void
+dead_debug_global_finish (struct dead_debug_global *global, bitmap used)
+{
+ if (global->used != used)
+ BITMAP_FREE (global->used);
+
+ if (global->htab.is_created ())
+ global->htab.dispose ();
+}
+
+/* Add USE to DEBUG, or substitute it right away if it's a pseudo in
+ the global substitution list. USE must be a dead reference to
+ UREGNO in a debug insn. Create a bitmap for DEBUG as needed. */
+
void
-dead_debug_add (struct dead_debug *debug, df_ref use, unsigned int uregno)
+dead_debug_add (struct dead_debug_local *debug, df_ref use, unsigned int uregno)
{
+ if (dead_debug_global_replace_temp (debug->global, use, uregno,
+ &debug->to_rescan))
+ return;
+
struct dead_debug_use *newddu = XNEW (struct dead_debug_use);
newddu->use = use;
@@ -305,26 +461,34 @@ dead_debug_add (struct dead_debug *debug, df_ref use, unsigned int uregno)
}
/* If UREGNO is referenced by any entry in DEBUG, emit a debug insn
- before or after INSN (depending on WHERE), that binds a debug temp
- to the widest-mode use of UREGNO, if WHERE is *_WITH_REG, or the
- value stored in UREGNO by INSN otherwise, and replace all uses of
- UREGNO in DEBUG with uses of the debug temp. INSN must be where
- UREGNO dies, if WHERE is *_BEFORE_*, or where it is set otherwise.
- Return the number of debug insns emitted. */
+ before or after INSN (depending on WHERE), that binds a (possibly
+ global) debug temp to the widest-mode use of UREGNO, if WHERE is
+ *_WITH_REG, or the value stored in UREGNO by INSN otherwise, and
+ replace all uses of UREGNO in DEBUG with uses of the debug temp.
+ INSN must be where UREGNO dies, if WHERE is *_BEFORE_*, or where it
+ is set otherwise. Return the number of debug insns emitted. */
+
int
-dead_debug_insert_temp (struct dead_debug *debug, unsigned int uregno,
+dead_debug_insert_temp (struct dead_debug_local *debug, unsigned int uregno,
rtx insn, enum debug_temp_where where)
{
struct dead_debug_use **tailp = &debug->head;
struct dead_debug_use *cur;
struct dead_debug_use *uses = NULL;
struct dead_debug_use **usesp = &uses;
- rtx reg = NULL;
+ rtx reg = NULL_RTX;
rtx breg;
- rtx dval;
+ rtx dval = NULL_RTX;
rtx bind;
+ bool global;
- if (!debug->used || !bitmap_clear_bit (debug->used, uregno))
+ if (!debug->used)
+ return 0;
+
+ global = (debug->global && debug->global->used
+ && bitmap_bit_p (debug->global->used, uregno));
+
+ if (!global && !bitmap_clear_bit (debug->used, uregno))
return 0;
/* Move all uses of uregno from debug->head to uses, setting mode to
@@ -359,10 +523,21 @@ dead_debug_insert_temp (struct dead_debug *debug, unsigned int uregno,
if (reg == NULL)
{
gcc_checking_assert (!uses);
- return 0;
+ if (!global)
+ return 0;
+ }
+
+ if (global)
+ {
+ if (!reg)
+ reg = regno_reg_rtx[uregno];
+ dead_debug_global_entry *entry
+ = dead_debug_global_find (debug->global, reg);
+ gcc_checking_assert (entry->reg == reg);
+ dval = entry->dtemp;
}
- gcc_checking_assert (uses);
+ gcc_checking_assert (uses || global);
breg = reg;
/* Recover the expression INSN stores in REG. */
@@ -464,8 +639,9 @@ dead_debug_insert_temp (struct dead_debug *debug, unsigned int uregno,
}
}
- /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL). */
- dval = make_debug_expr_from_rtl (reg);
+ if (!global)
+ /* Create DEBUG_EXPR (and DEBUG_EXPR_DECL). */
+ dval = make_debug_expr_from_rtl (reg);
/* Emit a debug bind insn before the insn in which reg dies. */
bind = gen_rtx_VAR_LOCATION (GET_MODE (reg),
diff --git a/gcc/valtrack.h b/gcc/valtrack.h
index 9f96f210b..303ffa43a 100644
--- a/gcc/valtrack.h
+++ b/gcc/valtrack.h
@@ -26,10 +26,71 @@ along with GCC; see the file COPYING3. If not see
#include "df.h"
#include "rtl.h"
#include "basic-block.h"
+#include "hash-table.h"
/* Debug uses of dead regs. */
+/* Entry that maps a dead pseudo (REG) used in a debug insns that dies
+ at different blocks to the debug temp (DTEMP) it was replaced
+ with. */
+
+struct dead_debug_global_entry
+{
+ rtx reg;
+ rtx dtemp;
+};
+
+/* Descriptor for hash_table to hash by dead_debug_global_entry's REG
+ and map to DTEMP. */
+
+struct dead_debug_hash_descr
+{
+ /* The hash table contains pointers to entries of this type. */
+ typedef struct dead_debug_global_entry T;
+ /* Hash on the pseudo number. */
+ static inline hashval_t hash (T const *my);
+ /* Entries are identical if they refer to the same pseudo. */
+ static inline bool equal (T const *my, T const *other);
+ /* Release entries when they're removed. */
+ static inline void remove (T *p);
+};
+
+/* Hash on the pseudo number. */
+inline hashval_t
+dead_debug_hash_descr::hash (T const *my)
+{
+ return REGNO (my->reg);
+}
+
+/* Entries are identical if they refer to the same pseudo. */
+inline bool
+dead_debug_hash_descr::equal (T const *my, T const *other)
+{
+ return my->reg == other->reg;
+}
+
+/* Release entries when they're removed. */
+inline void
+dead_debug_hash_descr::remove (T *p)
+{
+ XDELETE (p);
+}
+
+/* Maintain a global table of pseudos used in debug insns after their
+ deaths in other blocks, and debug temps their deathpoint values are
+ to be bound to. */
+
+struct dead_debug_global
+{
+ /* This hash table that maps pseudos to debug temps. */
+ hash_table <dead_debug_hash_descr> htab;
+ /* For each entry in htab, the bit corresponding to its REGNO will
+ be set. */
+ bitmap used;
+};
+
/* Node of a linked list of uses of dead REGs in debug insns. */
+
struct dead_debug_use
{
df_ref use;
@@ -38,15 +99,25 @@ struct dead_debug_use
/* Linked list of the above, with a bitmap of the REGs in the
list. */
-struct dead_debug
+
+struct dead_debug_local
{
+ /* The first dead_debug_use entry in the list. */
struct dead_debug_use *head;
+ /* A pointer to the global tracking data structure. */
+ struct dead_debug_global *global;
+ /* A bitmap that has bits set for each REG used in the
+ dead_debug_use list, and for each entry in the global hash
+ table. */
bitmap used;
+ /* A bitmap that has bits set for each INSN that is to be
+ rescanned. */
bitmap to_rescan;
};
/* This type controls the behavior of dead_debug_insert_temp WRT
UREGNO and INSN. */
+
enum debug_temp_where
{
/* Bind a newly-created debug temporary to a REG for UREGNO, and
@@ -62,10 +133,13 @@ enum debug_temp_where
DEBUG_TEMP_AFTER_WITH_REG = 1
};
-extern void dead_debug_init (struct dead_debug *, bitmap);
-extern void dead_debug_finish (struct dead_debug *, bitmap);
-extern void dead_debug_add (struct dead_debug *, df_ref, unsigned int);
-extern int dead_debug_insert_temp (struct dead_debug *,
+extern void dead_debug_global_init (struct dead_debug_global *, bitmap);
+extern void dead_debug_global_finish (struct dead_debug_global *, bitmap);
+extern void dead_debug_local_init (struct dead_debug_local *, bitmap,
+ struct dead_debug_global *);
+extern void dead_debug_local_finish (struct dead_debug_local *, bitmap);
+extern void dead_debug_add (struct dead_debug_local *, df_ref, unsigned int);
+extern int dead_debug_insert_temp (struct dead_debug_local *,
unsigned int uregno, rtx insn,
enum debug_temp_where);
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 9f5bc1261..bbd2f4b69 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -9428,6 +9428,7 @@ vt_add_function_parameter (tree parm)
&& GET_CODE (incoming) != PARALLEL)
{
cselib_val *val;
+ rtx lowpart;
/* ??? We shouldn't ever hit this, but it may happen because
arguments passed by invisible reference aren't dealt with
@@ -9436,7 +9437,11 @@ vt_add_function_parameter (tree parm)
if (offset)
return;
- val = cselib_lookup_from_insn (var_lowpart (mode, incoming), mode, true,
+ lowpart = var_lowpart (mode, incoming);
+ if (!lowpart)
+ return;
+
+ val = cselib_lookup_from_insn (lowpart, mode, true,
VOIDmode, get_insns ());
/* ??? Float-typed values in memory are not handled by
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index c5725793f..16410566d 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,25 @@
+2012-10-04 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * btest.c (f23): Avoid uninitialized variable warning.
+
+2012-10-04 Ian Lance Taylor <iant@google.com>
+
+ * dwarf.c: If the system header files do not declare strnlen,
+ provide our own version.
+
+2012-10-03 Ian Lance Taylor <iant@google.com>
+
+ * dwarf.c (read_uleb128): Fix overflow test.
+ (read_sleb128): Likewise.
+ (build_address_map): Don't change unit_buf.start.
+
+2012-10-02 Uros Bizjak <ubizjak@gmail.com>
+
+ PR other/54761
+ * configure.ac (EXTRA_FLAGS): New.
+ * Makefile.am (AM_FLAGS): Add $(EXTRA_FLAGS).
+ * configure, Makefile.in: Regenerate.
+
2012-09-29 Ian Lance Taylor <iant@google.com>
PR other/54749
diff --git a/libbacktrace/Makefile.am b/libbacktrace/Makefile.am
index a90a602d4..da1250234 100644
--- a/libbacktrace/Makefile.am
+++ b/libbacktrace/Makefile.am
@@ -12,7 +12,7 @@
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
-
+
# (3) The name of the author may not be used to
# endorse or promote products derived from this software without
# specific prior written permission.
@@ -34,7 +34,7 @@ ACLOCAL_AMFLAGS = -I .. -I ../config
AM_CPPFLAGS = -I $(top_srcdir)/../include -I $(top_srcdir)/../libgcc \
-I ../libgcc -I ../gcc/include -I $(MULTIBUILDTOP)../../gcc/include
-AM_CFLAGS = $(WARN_FLAGS) $(PIC_FLAG)
+AM_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) $(PIC_FLAG)
noinst_LTLIBRARIES = libbacktrace.la
diff --git a/libbacktrace/Makefile.in b/libbacktrace/Makefile.in
index b416c267b..3e7c91a1a 100644
--- a/libbacktrace/Makefile.in
+++ b/libbacktrace/Makefile.in
@@ -152,6 +152,7 @@ ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
+EXTRA_FLAGS = @EXTRA_FLAGS@
FGREP = @FGREP@
FORMAT_FILE = @FORMAT_FILE@
GREP = @GREP@
@@ -253,7 +254,7 @@ ACLOCAL_AMFLAGS = -I .. -I ../config
AM_CPPFLAGS = -I $(top_srcdir)/../include -I $(top_srcdir)/../libgcc \
-I ../libgcc -I ../gcc/include -I $(MULTIBUILDTOP)../../gcc/include
-AM_CFLAGS = $(WARN_FLAGS) $(PIC_FLAG)
+AM_CFLAGS = $(EXTRA_FLAGS) $(WARN_FLAGS) $(PIC_FLAG)
noinst_LTLIBRARIES = libbacktrace.la
libbacktrace_la_SOURCES = \
backtrace.h \
diff --git a/libbacktrace/btest.c b/libbacktrace/btest.c
index 085891a6e..16f25b450 100644
--- a/libbacktrace/btest.c
+++ b/libbacktrace/btest.c
@@ -486,7 +486,7 @@ f23 (int f1line, int f2line)
case 2:
expected = "test3";
break;
- case 3:
+ default:
assert (0);
}
diff --git a/libbacktrace/configure b/libbacktrace/configure
index 51a509cf0..8e2ea413c 100755
--- a/libbacktrace/configure
+++ b/libbacktrace/configure
@@ -612,6 +612,7 @@ FORMAT_FILE
BACKTRACE_SUPPORTS_THREADS
PIC_FLAG
WARN_FLAGS
+EXTRA_FLAGS
BACKTRACE_FILE
multi_basedir
OTOOL64
@@ -11080,7 +11081,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11083 "configure"
+#line 11084 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11186,7 +11187,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11189 "configure"
+#line 11190 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11488,6 +11489,12 @@ fi
fi
+EXTRA_FLAGS=
+if test "x$GCC" = "xyes"; then
+ EXTRA_FLAGS=-funwind-tables
+fi
+
+
WARN_FLAGS=
save_CFLAGS="$CFLAGS"
for real_option in -W -Wall -Wwrite-strings -Wstrict-prototypes \
diff --git a/libbacktrace/configure.ac b/libbacktrace/configure.ac
index dbd0a81e8..1ea8860f9 100644
--- a/libbacktrace/configure.ac
+++ b/libbacktrace/configure.ac
@@ -96,6 +96,12 @@ else
fi
AC_SUBST(BACKTRACE_FILE)
+EXTRA_FLAGS=
+if test "x$GCC" = "xyes"; then
+ EXTRA_FLAGS=-funwind-tables
+fi
+AC_SUBST(EXTRA_FLAGS)
+
ACX_PROG_CC_WARNING_OPTS([-W -Wall -Wwrite-strings -Wstrict-prototypes \
-Wmissing-prototypes -Wold-style-definition \
-Wmissing-format-attribute -Wcast-qual],
diff --git a/libbacktrace/dwarf.c b/libbacktrace/dwarf.c
index 68ebb4e3a..4e13fc541 100644
--- a/libbacktrace/dwarf.c
+++ b/libbacktrace/dwarf.c
@@ -44,8 +44,22 @@ POSSIBILITY OF SUCH DAMAGE. */
#include "internal.h"
#if !defined(HAVE_DECL_STRNLEN) || !HAVE_DECL_STRNLEN
-/* The function is defined in libiberty if needed. */
-extern size_t strnlen (const char *, size_t);
+
+/* If strnlen is not declared, provide our own version. */
+
+static size_t
+xstrnlen (const char *s, size_t maxlen)
+{
+ size_t i;
+
+ for (i = 0; i < maxlen; ++i)
+ if (s[i] == '\0')
+ break;
+ return i;
+}
+
+#define strnlen xstrnlen
+
#endif
/* A buffer to read DWARF info. */
@@ -524,10 +538,12 @@ read_uleb128 (struct dwarf_buf *buf)
{
uint64_t ret;
unsigned int shift;
+ int overflow;
unsigned char b;
ret = 0;
shift = 0;
+ overflow = 0;
do
{
const unsigned char *p;
@@ -536,14 +552,17 @@ read_uleb128 (struct dwarf_buf *buf)
if (!advance (buf, 1))
return 0;
b = *p;
- ret |= ((uint64_t) (b & 0x7f)) << shift;
+ if (shift < 64)
+ ret |= ((uint64_t) (b & 0x7f)) << shift;
+ else if (!overflow)
+ {
+ dwarf_buf_error (buf, "LEB128 overflows uint64_t");
+ overflow = 1;
+ }
shift += 7;
}
while ((b & 0x80) != 0);
- if (shift > 64)
- dwarf_buf_error (buf, "LEB128 overflows uint64_5");
-
return ret;
}
@@ -554,10 +573,12 @@ read_sleb128 (struct dwarf_buf *buf)
{
uint64_t val;
unsigned int shift;
+ int overflow;
unsigned char b;
val = 0;
shift = 0;
+ overflow = 0;
do
{
const unsigned char *p;
@@ -566,15 +587,18 @@ read_sleb128 (struct dwarf_buf *buf)
if (!advance (buf, 1))
return 0;
b = *p;
- val |= ((uint64_t) (b & 0x7f)) << shift;
+ if (shift < 64)
+ val |= ((uint64_t) (b & 0x7f)) << shift;
+ else if (!overflow)
+ {
+ dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
+ overflow = 1;
+ }
shift += 7;
}
while ((b & 0x80) != 0);
- if (shift > 64)
- dwarf_buf_error (buf, "signed LEB128 overflows uint64_t");
-
- if ((b & 0x40) != 0)
+ if ((b & 0x40) != 0 && shift < 64)
val |= ((uint64_t) -1) << shift;
return (int64_t) val;
@@ -1262,7 +1286,6 @@ build_address_map (struct backtrace_state *state,
}
unit_buf = info;
- unit_buf.start = info.buf;
unit_buf.left = len;
if (!advance (&info, len))
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index a26def2b1..957b216d4 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,10 @@
+2012-10-04 Florian Weimer <fweimer@redhat.com>
+
+ * directives.c (do_pragma_warning_or_error): New.
+ (do_pragma_warning): New.
+ (do_pragma_error): New.
+ (_cpp_init_internal_pragmas): Register new pragmas.
+
2012-09-25 Dehao Chen <dehao@google.com>
PR middle-end/54704
diff --git a/libcpp/directives.c b/libcpp/directives.c
index a8f2cc431..3c79b6d72 100644
--- a/libcpp/directives.c
+++ b/libcpp/directives.c
@@ -1,7 +1,5 @@
/* CPP Library. (Directive handling.)
- Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 1986-2012 Free Software Foundation, Inc.
Contributed by Per Bothner, 1994-95.
Based on CCCP program by Paul Rubin, June 1986
Adapted to ANSI C, Richard Stallman, Jan 1987
@@ -118,6 +116,9 @@ static void do_pragma_once (cpp_reader *);
static void do_pragma_poison (cpp_reader *);
static void do_pragma_system_header (cpp_reader *);
static void do_pragma_dependency (cpp_reader *);
+static void do_pragma_warning_or_error (cpp_reader *, bool error);
+static void do_pragma_warning (cpp_reader *);
+static void do_pragma_error (cpp_reader *);
static void do_linemarker (cpp_reader *);
static const cpp_token *get_token_no_padding (cpp_reader *);
static const cpp_token *get__Pragma_string (cpp_reader *);
@@ -1263,6 +1264,8 @@ _cpp_init_internal_pragmas (cpp_reader *pfile)
register_pragma_internal (pfile, "GCC", "system_header",
do_pragma_system_header);
register_pragma_internal (pfile, "GCC", "dependency", do_pragma_dependency);
+ register_pragma_internal (pfile, "GCC", "warning", do_pragma_warning);
+ register_pragma_internal (pfile, "GCC", "error", do_pragma_error);
}
/* Return the number of registered pragmas in PE. */
@@ -1634,6 +1637,42 @@ do_pragma_dependency (cpp_reader *pfile)
free ((void *) fname);
}
+/* Issue a diagnostic with the message taken from the pragma. If
+ ERROR is true, the diagnostic is a warning, otherwise, it is an
+ error. */
+static void
+do_pragma_warning_or_error (cpp_reader *pfile, bool error)
+{
+ const cpp_token *tok = _cpp_lex_token (pfile);
+ cpp_string str;
+ if (tok->type != CPP_STRING
+ || !cpp_interpret_string_notranslate (pfile, &tok->val.str, 1, &str,
+ CPP_STRING)
+ || str.len == 0)
+ {
+ cpp_error (pfile, CPP_DL_ERROR, "invalid \"#pragma GCC %s\" directive",
+ error ? "error" : "warning");
+ return;
+ }
+ cpp_error (pfile, error ? CPP_DL_ERROR : CPP_DL_WARNING,
+ "%s", str.text);
+ free ((void *)str.text);
+}
+
+/* Issue a warning diagnostic. */
+static void
+do_pragma_warning (cpp_reader *pfile)
+{
+ do_pragma_warning_or_error (pfile, false);
+}
+
+/* Issue an error diagnostic. */
+static void
+do_pragma_error (cpp_reader *pfile)
+{
+ do_pragma_warning_or_error (pfile, true);
+}
+
/* Get a token but skip padding. */
static const cpp_token *
get_token_no_padding (cpp_reader *pfile)
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 42308dba7..b09c22fe5 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,7 +1,59 @@
+2012-10-07 Matthias Klose <doko@ubuntu.com>
+
+ * config/arm/unwind-arm.h (__gnu_unwind_24bit): Mark parameters
+ as unused.
+ (_Unwind_decode_typeinfo_ptr): Mark base as unused.
+
+2012-10-06 Mark Kettenis <kettenis@openbsd.org>
+
+ * config.host (*-*-openbsd*): Add t-eh-dw2-dip to tmake_file.
+ * unwind-dw2-fde-dip.c: Don't include <elf.h> on OpenBSD.
+ (USE_PT_GNU_EH_FRAME): Define for OpenBSD.
+ (ElfW): Likewise.
+
+2012-10-05 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR other/53889
+ * config/i386/gthr-win32.h (__gthread_recursive_mutex_destroy):
+ Fix parameter names.
+
+2012-10-04 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/33135
+ * config/sh/t-sh (HOST_LIBGCC2_CFLAGS): Delete.
+ * config/sh/t-netbsd (HOST_LIBGCC2_CFLAGS): Delete.
+ * config/sh/t-linux (HOST_LIBGCC2_CFLAGS): Remove mieee option.
+
+2012-10-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/50457
+ * config/sh/linux-atomic.S: Delete.
+ * config/sh/linux-atomic.c: New.
+ * config/sh/t-linux (LIB2ADD): Replace linux-atomic.S with
+ linux-atomic.c. Add cflags to disable warnings.
+
+2012-10-02 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR other/53889
+ * gthr.h (__gthread_recursive_mutex_destroy): Document new required
+ function.
+ * gthr-posix.h (__gthread_recursive_mutex_destroy): Define.
+ * gthr-single.h (__gthread_recursive_mutex_destroy): Likewise.
+ * config/gthr-rtems.h (__gthread_recursive_mutex_destroy): Likewise.
+ * config/gthr-vxworks.h (__gthread_recursive_mutex_destroy): Likewise.
+ * config/i386/gthr-win32.c (__gthread_win32_recursive_mutex_destroy):
+ Likewise.
+ * config/i386/gthr-win32.h (__gthread_recursive_mutex_destroy):
+ Likewise.
+ * config/mips/gthr-mipssde.h (__gthread_recursive_mutex_destroy):
+ Likewise.
+ * config/pa/gthr-dce.h (__gthread_recursive_mutex_destroy): Likewise.
+ * config/s390/gthr-tpf.h (__gthread_recursive_mutex_destroy): Likewise.
+
2012-09-19 Mark Kettenis <kettenis@openbsd.org>
- * config.host (hppa-*-openbsd*): New target.
- * config/pa/t-openbsd: New file.
+ * config.host (hppa-*-openbsd*): New target.
+ * config/pa/t-openbsd: New file.
2012-09-15 Georg-Johann Lay <avr@gjlay.de>
@@ -34,9 +86,9 @@
2012-09-07 Teresa Johnson <tejohnson@google.com>
- PR gcov-profile/54487
+ PR gcov-profile/54487
* libgcc/libgcov.c (gcov_exit): Avoid warning on histogram
- differences.
+ differences.
2012-09-05 Georg-Johann Lay <avr@gjlay.de>
diff --git a/libgcc/config.host b/libgcc/config.host
index f8e163b1a..96c93a4e6 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -216,7 +216,7 @@ case ${host} in
esac
;;
*-*-openbsd*)
- tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic"
+ tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip"
case ${target_thread_file} in
posix)
tmake_file="$tmake_file t-openbsd-thread"
diff --git a/libgcc/config/arm/unwind-arm.h b/libgcc/config/arm/unwind-arm.h
index 4300c8e31..74f72b0fd 100644
--- a/libgcc/config/arm/unwind-arm.h
+++ b/libgcc/config/arm/unwind-arm.h
@@ -39,7 +39,8 @@ extern "C" {
#endif
/* Decode an R_ARM_TARGET2 relocation. */
static inline _Unwind_Word
- _Unwind_decode_typeinfo_ptr (_Unwind_Word base, _Unwind_Word ptr)
+ _Unwind_decode_typeinfo_ptr (_Unwind_Word base __attribute__ ((unused)),
+ _Unwind_Word ptr)
{
_Unwind_Word tmp;
@@ -65,7 +66,9 @@ extern "C" {
}
static inline _Unwind_Reason_Code
- __gnu_unwind_24bit (_Unwind_Context * context, _uw data, int compact)
+ __gnu_unwind_24bit (_Unwind_Context * context __attribute__ ((unused)),
+ _uw data __attribute__ ((unused)),
+ int compact __attribute__ ((unused)))
{
return _URC_FAILURE;
}
diff --git a/libgcc/config/gthr-rtems.h b/libgcc/config/gthr-rtems.h
index c5bd52292..3bfa67bc2 100644
--- a/libgcc/config/gthr-rtems.h
+++ b/libgcc/config/gthr-rtems.h
@@ -1,8 +1,7 @@
/* RTEMS threads compatibility routines for libgcc2 and libobjc.
by: Rosimildo da Silva( rdasilva@connecttel.com ) */
/* Compile this one with gcc. */
-/* Copyright (C) 1997, 1999, 2000, 2002, 2003, 2005, 2008, 2009
- Free Software Foundation, Inc.
+/* Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -150,6 +149,14 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
return rtems_gxx_recursive_mutex_unlock( __mutex );
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
+{
+ /* This requires that recursive and non-recursive mutexes have the same
+ representation. */
+ return rtems_gxx_mutex_destroy (__mutex );
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/libgcc/config/gthr-vxworks.h b/libgcc/config/gthr-vxworks.h
index 63116c460..b48c5ac4c 100644
--- a/libgcc/config/gthr-vxworks.h
+++ b/libgcc/config/gthr-vxworks.h
@@ -1,7 +1,6 @@
/* Threads compatibility routines for libgcc2 and libobjc for VxWorks. */
/* Compile this one with gcc. */
-/* Copyright (C) 1997, 1999, 2000, 2008, 2009, 2011
- Free Software Foundation, Inc.
+/* Copyright (C) 1997-2012 Free Software Foundation, Inc.
Contributed by Mike Stump <mrs@wrs.com>.
This file is part of GCC.
@@ -111,6 +110,12 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
return __gthread_mutex_unlock (mutex);
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
+{
+ return __gthread_mutex_destroy (__mutex);
+}
+
/* pthread_once is complicated enough that it's implemented
out-of-line. See config/vxlib.c. */
diff --git a/libgcc/config/i386/gthr-win32.c b/libgcc/config/i386/gthr-win32.c
index ab1b69fd4..fcb15df1d 100644
--- a/libgcc/config/i386/gthr-win32.c
+++ b/libgcc/config/i386/gthr-win32.c
@@ -1,8 +1,7 @@
/* Implementation of W32-specific threads compatibility routines for
libgcc2. */
-/* Copyright (C) 1999, 2000, 2002, 2004, 2008, 2009, 2011
- Free Software Foundation, Inc.
+/* Copyright (C) 1999-2012 Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
Modified and moved to separate file by Danny Smith
<dannysmith@users.sourceforge.net>.
@@ -259,3 +258,10 @@ __gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *mutex)
return 0;
}
+
+int
+__gthr_win32_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex)
+{
+ CloseHandle ((HANDLE) mutex->sema);
+ return 0;
+}
diff --git a/libgcc/config/i386/gthr-win32.h b/libgcc/config/i386/gthr-win32.h
index 53f8396cc..ecde94132 100644
--- a/libgcc/config/i386/gthr-win32.h
+++ b/libgcc/config/i386/gthr-win32.h
@@ -1,8 +1,7 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
-/* Copyright (C) 1999, 2000, 2002, 2003, 2004, 2005, 2008, 2009
- Free Software Foundation, Inc.
+/* Copyright (C) 1999-2012 Free Software Foundation, Inc.
Contributed by Mumit Khan <khan@xraylith.wisc.edu>.
This file is part of GCC.
@@ -430,6 +429,8 @@ extern int
__gthr_win32_recursive_mutex_trylock (__gthread_recursive_mutex_t *);
extern int __gthr_win32_recursive_mutex_unlock (__gthread_recursive_mutex_t *);
extern void __gthr_win32_mutex_destroy (__gthread_mutex_t *);
+extern int
+ __gthr_win32_recursive_mutex_destroy (__gthread_recursive_mutex_t *);
static inline int
__gthread_once (__gthread_once_t *__once, void (*__func) (void))
@@ -536,6 +537,12 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
return 0;
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
+{
+ return __gthr_win32_recursive_mutex_destroy (__mutex);
+}
+
#else /* ! __GTHREAD_HIDE_WIN32API */
#include <windows.h>
@@ -761,6 +768,13 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
return 0;
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
+{
+ CloseHandle ((HANDLE) __mutex->sema);
+ return 0;
+}
+
#endif /* __GTHREAD_HIDE_WIN32API */
#ifdef __cplusplus
diff --git a/libgcc/config/mips/gthr-mipssde.h b/libgcc/config/mips/gthr-mipssde.h
index 34f9b6cf5..2ce22580b 100644
--- a/libgcc/config/mips/gthr-mipssde.h
+++ b/libgcc/config/mips/gthr-mipssde.h
@@ -1,6 +1,6 @@
/* MIPS SDE threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
-/* Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+/* Copyright (C) 2006-2012 Free Software Foundation, Inc.
Contributed by Nigel Stephens <nigel@mips.com>
This file is part of GCC.
@@ -223,6 +223,13 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
return 0;
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t
+ * UNUSED(__mutex))
+{
+ return 0;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/libgcc/config/pa/gthr-dce.h b/libgcc/config/pa/gthr-dce.h
index d32155a93..3ba43a187 100644
--- a/libgcc/config/pa/gthr-dce.h
+++ b/libgcc/config/pa/gthr-dce.h
@@ -1,7 +1,6 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
-/* Copyright (C) 1997, 1999, 2000, 2001, 2004, 2005, 2008, 2009
- Free Software Foundation, Inc.
+/* Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -557,6 +556,12 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
return __gthread_mutex_unlock (__mutex);
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
+{
+ return __gthread_mutex_destroy (__mutex);
+}
+
#endif /* _LIBOBJC */
#endif
diff --git a/libgcc/config/s390/gthr-tpf.h b/libgcc/config/s390/gthr-tpf.h
index fb23e91cf..49bce4c20 100644
--- a/libgcc/config/s390/gthr-tpf.h
+++ b/libgcc/config/s390/gthr-tpf.h
@@ -1,6 +1,6 @@
/* Threads compatibility routines for libgcc2 and libobjc.
Compile this one with gcc.
- Copyright (C) 2004, 2005, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2004-2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -225,5 +225,10 @@ __gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
return 0;
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
+{
+ return __gthread_mutex_destroy (__mutex);
+}
#endif /* ! GCC_GTHR_TPF_H */
diff --git a/libgcc/config/sh/linux-atomic.S b/libgcc/config/sh/linux-atomic.S
deleted file mode 100644
index 743c61bb7..000000000
--- a/libgcc/config/sh/linux-atomic.S
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Copyright (C) 2006, 2008, 2009 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/>. */
-
-
-!! Linux specific atomic routines for the Renesas / SuperH SH CPUs.
-!! Linux kernel for SH3/4 has implemented the support for software
-!! atomic sequences.
-
-#define FUNC(X) .type X,@function
-#define HIDDEN_FUNC(X) FUNC(X); .hidden X
-#define ENDFUNC0(X) .Lfe_##X: .size X,.Lfe_##X-X
-#define ENDFUNC(X) ENDFUNC0(X)
-
-#if ! __SH5__
-
-#define ATOMIC_TEST_AND_SET(N,T,EXT) \
- .global __sync_lock_test_and_set_##N; \
- HIDDEN_FUNC(__sync_lock_test_and_set_##N); \
- .align 2; \
-__sync_lock_test_and_set_##N:; \
- mova 1f, r0; \
- nop; \
- mov r15, r1; \
- mov #(0f-1f), r15; \
-0: mov.##T @r4, r2; \
- mov.##T r5, @r4; \
-1: mov r1, r15; \
- rts; \
- EXT r2, r0; \
- ENDFUNC(__sync_lock_test_and_set_##N)
-
-ATOMIC_TEST_AND_SET (1,b,extu.b)
-ATOMIC_TEST_AND_SET (2,w,extu.w)
-ATOMIC_TEST_AND_SET (4,l,mov)
-
-#define ATOMIC_COMPARE_AND_SWAP(N,T,EXTS,EXT) \
- .global __sync_val_compare_and_swap_##N; \
- HIDDEN_FUNC(__sync_val_compare_and_swap_##N); \
- .align 2; \
-__sync_val_compare_and_swap_##N:; \
- mova 1f, r0; \
- EXTS r5, r5; \
- mov r15, r1; \
- mov #(0f-1f), r15; \
-0: mov.##T @r4, r2; \
- cmp/eq r2, r5; \
- bf 1f; \
- mov.##T r6, @r4; \
-1: mov r1, r15; \
- rts; \
- EXT r2, r0; \
- ENDFUNC(__sync_val_compare_and_swap_##N)
-
-ATOMIC_COMPARE_AND_SWAP (1,b,exts.b,extu.b)
-ATOMIC_COMPARE_AND_SWAP (2,w,exts.w,extu.w)
-ATOMIC_COMPARE_AND_SWAP (4,l,mov,mov)
-
-#define ATOMIC_BOOL_COMPARE_AND_SWAP(N,T,EXTS) \
- .global __sync_bool_compare_and_swap_##N; \
- HIDDEN_FUNC(__sync_bool_compare_and_swap_##N); \
- .align 2; \
-__sync_bool_compare_and_swap_##N:; \
- mova 1f, r0; \
- EXTS r5, r5; \
- mov r15, r1; \
- mov #(0f-1f), r15; \
-0: mov.##T @r4, r2; \
- cmp/eq r2, r5; \
- bf 1f; \
- mov.##T r6, @r4; \
-1: mov r1, r15; \
- rts; \
- movt r0; \
- ENDFUNC(__sync_bool_compare_and_swap_##N)
-
-ATOMIC_BOOL_COMPARE_AND_SWAP (1,b,exts.b)
-ATOMIC_BOOL_COMPARE_AND_SWAP (2,w,exts.w)
-ATOMIC_BOOL_COMPARE_AND_SWAP (4,l,mov)
-
-#define ATOMIC_FETCH_AND_OP(OP,N,T,EXT) \
- .global __sync_fetch_and_##OP##_##N; \
- HIDDEN_FUNC(__sync_fetch_and_##OP##_##N); \
- .align 2; \
-__sync_fetch_and_##OP##_##N:; \
- mova 1f, r0; \
- nop; \
- mov r15, r1; \
- mov #(0f-1f), r15; \
-0: mov.##T @r4, r2; \
- mov r5, r3; \
- OP r2, r3; \
- mov.##T r3, @r4; \
-1: mov r1, r15; \
- rts; \
- EXT r2, r0; \
- ENDFUNC(__sync_fetch_and_##OP##_##N)
-
-ATOMIC_FETCH_AND_OP(add,1,b,extu.b)
-ATOMIC_FETCH_AND_OP(add,2,w,extu.w)
-ATOMIC_FETCH_AND_OP(add,4,l,mov)
-
-ATOMIC_FETCH_AND_OP(or,1,b,extu.b)
-ATOMIC_FETCH_AND_OP(or,2,w,extu.w)
-ATOMIC_FETCH_AND_OP(or,4,l,mov)
-
-ATOMIC_FETCH_AND_OP(and,1,b,extu.b)
-ATOMIC_FETCH_AND_OP(and,2,w,extu.w)
-ATOMIC_FETCH_AND_OP(and,4,l,mov)
-
-ATOMIC_FETCH_AND_OP(xor,1,b,extu.b)
-ATOMIC_FETCH_AND_OP(xor,2,w,extu.w)
-ATOMIC_FETCH_AND_OP(xor,4,l,mov)
-
-#define ATOMIC_FETCH_AND_COMBOP(OP,OP0,OP1,N,T,EXT) \
- .global __sync_fetch_and_##OP##_##N; \
- HIDDEN_FUNC(__sync_fetch_and_##OP##_##N); \
- .align 2; \
-__sync_fetch_and_##OP##_##N:; \
- mova 1f, r0; \
- mov r15, r1; \
- mov #(0f-1f), r15; \
-0: mov.##T @r4, r2; \
- mov r5, r3; \
- OP0 r2, r3; \
- OP1 r3, r3; \
- mov.##T r3, @r4; \
-1: mov r1, r15; \
- rts; \
- EXT r2, r0; \
- ENDFUNC(__sync_fetch_and_##OP##_##N)
-
-ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,1,b,extu.b)
-ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,2,w,extu.w)
-ATOMIC_FETCH_AND_COMBOP(sub,sub,neg,4,l,mov)
-
-ATOMIC_FETCH_AND_COMBOP(nand,and,not,1,b,extu.b)
-ATOMIC_FETCH_AND_COMBOP(nand,and,not,2,w,extu.w)
-ATOMIC_FETCH_AND_COMBOP(nand,and,not,4,l,mov)
-
-#define ATOMIC_OP_AND_FETCH(OP,N,T,EXT) \
- .global __sync_##OP##_and_fetch_##N; \
- HIDDEN_FUNC(__sync_##OP##_and_fetch_##N); \
- .align 2; \
-__sync_##OP##_and_fetch_##N:; \
- mova 1f, r0; \
- nop; \
- mov r15, r1; \
- mov #(0f-1f), r15; \
-0: mov.##T @r4, r2; \
- mov r5, r3; \
- OP r2, r3; \
- mov.##T r3, @r4; \
-1: mov r1, r15; \
- rts; \
- EXT r3, r0; \
- ENDFUNC(__sync_##OP##_and_fetch_##N)
-
-ATOMIC_OP_AND_FETCH(add,1,b,extu.b)
-ATOMIC_OP_AND_FETCH(add,2,w,extu.w)
-ATOMIC_OP_AND_FETCH(add,4,l,mov)
-
-ATOMIC_OP_AND_FETCH(or,1,b,extu.b)
-ATOMIC_OP_AND_FETCH(or,2,w,extu.w)
-ATOMIC_OP_AND_FETCH(or,4,l,mov)
-
-ATOMIC_OP_AND_FETCH(and,1,b,extu.b)
-ATOMIC_OP_AND_FETCH(and,2,w,extu.w)
-ATOMIC_OP_AND_FETCH(and,4,l,mov)
-
-ATOMIC_OP_AND_FETCH(xor,1,b,extu.b)
-ATOMIC_OP_AND_FETCH(xor,2,w,extu.w)
-ATOMIC_OP_AND_FETCH(xor,4,l,mov)
-
-#define ATOMIC_COMBOP_AND_FETCH(OP,OP0,OP1,N,T,EXT) \
- .global __sync_##OP##_and_fetch_##N; \
- HIDDEN_FUNC(__sync_##OP##_and_fetch_##N); \
- .align 2; \
-__sync_##OP##_and_fetch_##N:; \
- mova 1f, r0; \
- mov r15, r1; \
- mov #(0f-1f), r15; \
-0: mov.##T @r4, r2; \
- mov r5, r3; \
- OP0 r2, r3; \
- OP1 r3, r3; \
- mov.##T r3, @r4; \
-1: mov r1, r15; \
- rts; \
- EXT r3, r0; \
- ENDFUNC(__sync_##OP##_and_fetch_##N)
-
-ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,1,b,extu.b)
-ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,2,w,extu.w)
-ATOMIC_COMBOP_AND_FETCH(sub,sub,neg,4,l,mov)
-
-ATOMIC_COMBOP_AND_FETCH(nand,and,not,1,b,extu.b)
-ATOMIC_COMBOP_AND_FETCH(nand,and,not,2,w,extu.w)
-ATOMIC_COMBOP_AND_FETCH(nand,and,not,4,l,mov)
-
-.section .note.GNU-stack,"",%progbits
-.previous
-
-#endif /* ! __SH5__ */
diff --git a/libgcc/config/sh/linux-atomic.c b/libgcc/config/sh/linux-atomic.c
new file mode 100644
index 000000000..a5249c6dc
--- /dev/null
+++ b/libgcc/config/sh/linux-atomic.c
@@ -0,0 +1,81 @@
+/* Copyright (C) 2012 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/>. */
+
+/* Atomic built-in C functions for link compatibility with older code that
+ was compiled to emit function calls for atomic built-ins.
+ Notice that if no atomic model has been selected the functions in this
+ file must not be generated, or else they will result in infinite no-op
+ loops.
+ Notice also, that all the generated functions below take three parameters,
+ which is not actually true for some of the built-in functions. However,
+ on SH this does not matter, since the first four parameters are always
+ passed in call clobbered registers.
+ The return type for the sync_bool_compare_and_swap functions is also
+ actually supposed to be a bool, but this also doesn't matter since any
+ int return type <= 32 bit is returned in R0 on SH. */
+
+#if !__SH_ATOMIC_MODEL_NONE__
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+
+#define uint8_t_sz 1
+#define uint16_t_sz 2
+#define uint32_t_sz 4
+
+#define typesz(x) x##_sz
+
+#define concat(x,y) __ ## x ## _ ## y
+#define eval(x,y) concat (x,y)
+#define genname(f,t) eval(f, typesz (t))
+
+#define func1(name, type) \
+ type __attribute__((visibility("hidden"))) \
+ genname (name, type) (type* x, type y, type z) \
+ { \
+ return __##name (x, y, z); \
+ }
+
+#define genfuncs(name) \
+ func1 (name, uint8_t) \
+ func1 (name, uint16_t) \
+ func1 (name, uint32_t)
+
+genfuncs (sync_lock_test_and_set)
+genfuncs (sync_val_compare_and_swap)
+genfuncs (sync_bool_compare_and_swap)
+genfuncs (sync_fetch_and_add)
+genfuncs (sync_fetch_and_or)
+genfuncs (sync_fetch_and_and)
+genfuncs (sync_fetch_and_xor)
+genfuncs (sync_fetch_and_sub)
+genfuncs (sync_fetch_and_nand)
+genfuncs (sync_add_and_fetch)
+genfuncs (sync_or_and_fetch)
+genfuncs (sync_and_and_fetch)
+genfuncs (sync_xor_and_fetch)
+genfuncs (sync_sub_and_fetch)
+genfuncs (sync_nand_and_fetch)
+
+#endif
diff --git a/libgcc/config/sh/t-linux b/libgcc/config/sh/t-linux
index d0f92405f..d316db937 100644
--- a/libgcc/config/sh/t-linux
+++ b/libgcc/config/sh/t-linux
@@ -1,8 +1,12 @@
LIB1ASMFUNCS_CACHE = _ic_invalidate _ic_invalidate_array
-LIB2ADD = $(srcdir)/config/sh/linux-atomic.S
+LIB2ADD = $(srcdir)/config/sh/linux-atomic.c
-HOST_LIBGCC2_CFLAGS += -mieee -DNO_FPSCR_VALUES
+HOST_LIBGCC2_CFLAGS += -DNO_FPSCR_VALUES
+
+# Silence atomic built-in related warnings in linux-atomic.c.
+# Unfortunately the conflicting types warning can't be disabled selectively.
+HOST_LIBGCC2_CFLAGS += -w -Wno-sync-nand
# Override t-slibgcc-elf-ver to export some libgcc symbols with
# the symbol versions that glibc used, and hide some lib1func
diff --git a/libgcc/config/sh/t-netbsd b/libgcc/config/sh/t-netbsd
index 3c5739e2f..93fe287e5 100644
--- a/libgcc/config/sh/t-netbsd
+++ b/libgcc/config/sh/t-netbsd
@@ -1,3 +1,2 @@
LIB1ASMFUNCS_CACHE = _ic_invalidate
-HOST_LIBGCC2_CFLAGS += -mieee
diff --git a/libgcc/config/sh/t-sh b/libgcc/config/sh/t-sh
index efbaff847..61cfe79a6 100644
--- a/libgcc/config/sh/t-sh
+++ b/libgcc/config/sh/t-sh
@@ -59,5 +59,3 @@ div_table-4-300.o: $(srcdir)/config/sh/lib1funcs-4-300.S
libgcc-4-300.a: div_table-4-300.o
$(AR_CREATE_FOR_TARGET) $@ div_table-4-300.o
-HOST_LIBGCC2_CFLAGS += -mieee
-
diff --git a/libgcc/gthr-posix.h b/libgcc/gthr-posix.h
index cc4e518f5..1e7ddfeb2 100644
--- a/libgcc/gthr-posix.h
+++ b/libgcc/gthr-posix.h
@@ -832,6 +832,12 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
return __gthread_mutex_unlock (__mutex);
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
+{
+ return __gthread_mutex_destroy (__mutex);
+}
+
#ifdef _GTHREAD_USE_COND_INIT_FUNC
static inline void
__gthread_cond_init_function (__gthread_cond_t *__cond)
diff --git a/libgcc/gthr-single.h b/libgcc/gthr-single.h
index 4e3967977..717e6cb37 100644
--- a/libgcc/gthr-single.h
+++ b/libgcc/gthr-single.h
@@ -1,7 +1,6 @@
/* Threads compatibility routines for libgcc2 and libobjc. */
/* Compile this one with gcc. */
-/* Copyright (C) 1997, 1999, 2000, 2004, 2008, 2009
- Free Software Foundation, Inc.
+/* Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -286,6 +285,12 @@ __gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
return __gthread_mutex_unlock (__mutex);
}
+static inline int
+__gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *__mutex)
+{
+ return __gthread_mutex_destroy (__mutex);
+}
+
#endif /* _LIBOBJC */
#undef UNUSED
diff --git a/libgcc/gthr.h b/libgcc/gthr.h
index 813abe1e5..9f2b53d23 100644
--- a/libgcc/gthr.h
+++ b/libgcc/gthr.h
@@ -1,7 +1,6 @@
/* Threads compatibility routines for libgcc2. */
/* Compile this one with gcc. */
-/* Copyright (C) 1997, 1998, 2004, 2008, 2009, 2011
- Free Software Foundation, Inc.
+/* Copyright (C) 1997-2012 Free Software Foundation, Inc.
This file is part of GCC.
@@ -73,6 +72,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
int __gthread_setspecific (__gthread_key_t key, const void *ptr)
int __gthread_mutex_destroy (__gthread_mutex_t *mutex);
+ int __gthread_recursive_mutex_destroy (__gthread_recursive_mutex_t *mutex);
int __gthread_mutex_lock (__gthread_mutex_t *mutex);
int __gthread_mutex_trylock (__gthread_mutex_t *mutex);
diff --git a/libgcc/unwind-dw2-fde-dip.c b/libgcc/unwind-dw2-fde-dip.c
index 92f8ab546..2ce3af80b 100644
--- a/libgcc/unwind-dw2-fde-dip.c
+++ b/libgcc/unwind-dw2-fde-dip.c
@@ -33,7 +33,7 @@
#include "tconfig.h"
#include "tsystem.h"
-#ifndef inhibit_libc
+#if !defined(inhibit_libc) && !defined(__OpenBSD__)
#include <elf.h> /* Get DT_CONFIG. */
#endif
#include "coretypes.h"
@@ -65,6 +65,12 @@
#endif
#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
+ && defined(__OpenBSD__)
+# define ElfW(type) Elf_##type
+# define USE_PT_GNU_EH_FRAME
+#endif
+
+#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) \
&& defined(TARGET_DL_ITERATE_PHDR) \
&& defined(__sun__) && defined(__svr4__)
# define USE_PT_GNU_EH_FRAME
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index feeb10a41..74d6294b3 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,19 @@
+2012-10-06 Janne Blomqvist <jb@gcc.gnu.org>
+
+ * configure.ac: Check for presence of secure_getenv.
+ * libgfortran.h: Use HAVE_SECURE_GETENV.
+ * Makefile.in: Regenerated.
+ * aclocal.m4: Regenerated.
+ * config.h.in: Regenerated.
+ * configure: Regenerated.
+
+2012-10-06 Thomas König <tkoenig@gcc.gnu.org>
+
+ PR libfortran/54736
+ * runtime/environ.c (search_unit): Correct logic
+ for binary search.
+ (mark_single): Fix index errors.
+
2012-09-29 Thomas König <tkoenig@gcc.gnu.org>
PR fortran/52724
diff --git a/libgfortran/Makefile.in b/libgfortran/Makefile.in
index aa23e85e3..62b9f7abf 100644
--- a/libgfortran/Makefile.in
+++ b/libgfortran/Makefile.in
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -87,6 +87,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+ test -z "$$files" \
+ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+ $(am__cd) "$$dir" && rm -f $$files; }; \
+ }
am__installdirs = "$(DESTDIR)$(cafexeclibdir)" \
"$(DESTDIR)$(myexeclibdir)" "$(DESTDIR)$(toolexeclibdir)" \
"$(DESTDIR)$(toolexeclibdir)"
@@ -1276,7 +1282,7 @@ all: $(BUILT_SOURCES) config.h
.SUFFIXES:
.SUFFIXES: .F90 .c .f90 .lo .o .obj
-am--refresh:
+am--refresh: Makefile
@:
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
@@ -1312,10 +1318,8 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
$(am__aclocal_m4_deps):
config.h: stamp-h1
- @if test ! -f $@; then \
- rm -f stamp-h1; \
- $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
- else :; fi
+ @if test ! -f $@; then rm -f stamp-h1; else :; fi
+ @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
@@ -1422,11 +1426,11 @@ clean-toolexeclibLTLIBRARIES:
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
-libcaf_single.la: $(libcaf_single_la_OBJECTS) $(libcaf_single_la_DEPENDENCIES)
+libcaf_single.la: $(libcaf_single_la_OBJECTS) $(libcaf_single_la_DEPENDENCIES) $(EXTRA_libcaf_single_la_DEPENDENCIES)
$(libcaf_single_la_LINK) -rpath $(cafexeclibdir) $(libcaf_single_la_OBJECTS) $(libcaf_single_la_LIBADD) $(LIBS)
-libgfortran.la: $(libgfortran_la_OBJECTS) $(libgfortran_la_DEPENDENCIES)
+libgfortran.la: $(libgfortran_la_OBJECTS) $(libgfortran_la_DEPENDENCIES) $(EXTRA_libgfortran_la_DEPENDENCIES)
$(libgfortran_la_LINK) -rpath $(toolexeclibdir) $(libgfortran_la_OBJECTS) $(libgfortran_la_LIBADD) $(LIBS)
-libgfortranbegin.la: $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_DEPENDENCIES)
+libgfortranbegin.la: $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_DEPENDENCIES) $(EXTRA_libgfortranbegin_la_DEPENDENCIES)
$(libgfortranbegin_la_LINK) -rpath $(myexeclibdir) $(libgfortranbegin_la_OBJECTS) $(libgfortranbegin_la_LIBADD) $(LIBS)
mostlyclean-compile:
@@ -5686,9 +5690,7 @@ uninstall-toolexeclibDATA:
@$(NORMAL_UNINSTALL)
@list='$(toolexeclib_DATA)'; test -n "$(toolexeclibdir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
- test -n "$$files" || exit 0; \
- echo " ( cd '$(DESTDIR)$(toolexeclibdir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(toolexeclibdir)" && rm -f $$files
+ dir='$(DESTDIR)$(toolexeclibdir)'; $(am__uninstall_files_from_dir)
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -5760,10 +5762,15 @@ install-am: all-am
installcheck: installcheck-am
install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+ if test -z '$(STRIP)'; then \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ install; \
+ else \
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+ fi
mostlyclean-generic:
clean-generic:
diff --git a/libgfortran/aclocal.m4 b/libgfortran/aclocal.m4
index 8673daa1a..351be9d25 100644
--- a/libgfortran/aclocal.m4
+++ b/libgfortran/aclocal.m4
@@ -1,7 +1,8 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+# Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@@ -19,12 +20,15 @@ You have another version of autoconf. It may work, but is not guaranteed to.
If you have problems, you may need to regenerate the build system entirely.
To do so, use the procedure documented by the package, typically `autoreconf'.])])
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
+# Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
@@ -34,7 +38,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
[am__api_version='1.11'
dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
+m4_if([$1], [1.11.3], [],
[AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
])
@@ -50,19 +54,21 @@ m4_define([_AM_AUTOCONF_VERSION], [])
# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
+[AM_AUTOMAKE_VERSION([1.11.3])dnl
m4_ifndef([AC_AUTOCONF_VERSION],
[m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
@@ -144,14 +150,14 @@ AC_CONFIG_COMMANDS_PRE(
Usually this means the macro was only invoked conditionally.]])
fi])])
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
+# 2010, 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 10
+# serial 12
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
@@ -191,6 +197,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -255,7 +262,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
break
fi
;;
- msvisualcpp | msvcmsys)
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@@ -320,10 +327,13 @@ AC_DEFUN([AM_DEP_TRACK],
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
+ am__nodep='_no'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])dnl
_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
@@ -545,12 +555,15 @@ for _am_header in $config_headers :; do
done
echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
+# Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
@@ -569,8 +582,8 @@ AC_SUBST(install_sh)])
# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
# From Jim Meyering
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
+# 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -590,7 +603,7 @@ AC_DEFUN([AM_MAINTAINER_MODE],
[disable], [m4_define([am_maintainer_other], [enable])],
[m4_define([am_maintainer_other], [enable])
m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
dnl maintainer-mode's default is 'disable' unless 'enable' is passed
AC_ARG_ENABLE([maintainer-mode],
[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
@@ -736,12 +749,15 @@ else
fi
])
-# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
+# Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# AM_PROG_MKDIR_P
# ---------------
# Check for `mkdir -p'.
@@ -764,13 +780,14 @@ esac
# Helper functions for option handling. -*- Autoconf -*-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
+# Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 4
+# serial 5
# _AM_MANGLE_OPTION(NAME)
# -----------------------
@@ -778,13 +795,13 @@ AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
-# ------------------------------
+# --------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
+# ------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
@@ -860,12 +877,14 @@ Check your system clock])
fi
AC_MSG_RESULT(yes)])
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
+# serial 1
+
# AM_PROG_INSTALL_STRIP
# ---------------------
# One issue with vendor `install' (even GNU) is that you can't
@@ -888,13 +907,13 @@ fi
INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
-# serial 2
+# serial 3
# _AM_SUBST_NOTMAKE(VARIABLE)
# ---------------------------
@@ -903,13 +922,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
AC_DEFUN([_AM_SUBST_NOTMAKE])
# AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
+# --------------------------
# Public sister of _AM_SUBST_NOTMAKE.
AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# Check how to create a tarball. -*- Autoconf -*-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
#
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -931,10 +950,11 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
# a tarball read from stdin.
# $(am__untar) < result.tar
AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
+[# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
m4_if([$1], [v7],
- [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
[m4_case([$1], [ustar],, [pax],,
[m4_fatal([Unknown tar format])])
AC_MSG_CHECKING([how to create a $1 tar archive])
diff --git a/libgfortran/config.h.in b/libgfortran/config.h.in
index 43ba02598..ee4c14f52 100644
--- a/libgfortran/config.h.in
+++ b/libgfortran/config.h.in
@@ -648,6 +648,9 @@
/* Define to 1 if you have the `scalbnl' function. */
#undef HAVE_SCALBNL
+/* Define to 1 if you have the `secure_getenv' function. */
+#undef HAVE_SECURE_GETENV
+
/* Define to 1 if you have the `setmode' function. */
#undef HAVE_SETMODE
diff --git a/libgfortran/configure b/libgfortran/configure
index 5ee6f23aa..5ad56aa29 100755
--- a/libgfortran/configure
+++ b/libgfortran/configure
@@ -653,6 +653,7 @@ CPP
am__fastdepCC_FALSE
am__fastdepCC_TRUE
CCDEPMODE
+am__nodep
AMDEPBACKSLASH
AMDEP_FALSE
AMDEP_TRUE
@@ -2592,6 +2593,7 @@ as_fn_append ac_func_list " getuid"
as_fn_append ac_func_list " geteuid"
as_fn_append ac_func_list " umask"
as_fn_append ac_func_list " getegid"
+as_fn_append ac_func_list " secure_getenv"
as_fn_append ac_func_list " __secure_getenv"
as_fn_append ac_header_list " math.h"
# Check that the precious variables saved in the cache have kept the same
@@ -3383,11 +3385,11 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
-# Always define AMTAR for backward compatibility.
+# Always define AMTAR for backward compatibility. Yes, it's still used
+# in the wild :-( We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
@@ -3520,6 +3522,7 @@ fi
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
+ am__nodep='_no'
fi
if test "x$enable_dependency_tracking" != xno; then
AMDEP_TRUE=
@@ -4337,6 +4340,7 @@ else
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -4396,7 +4400,7 @@ else
break
fi
;;
- msvisualcpp | msvcmsys)
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@@ -5512,6 +5516,7 @@ else
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
+ rm -rf conftest.dir
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
@@ -5571,7 +5576,7 @@ else
break
fi
;;
- msvisualcpp | msvcmsys)
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
# This compiler won't grok `-c -o', but also, the minuso test has
# not run yet. These depmodes are late enough in the game, and
# so weak that their functioning should not be impacted.
@@ -12328,7 +12333,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12331 "configure"
+#line 12336 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -12434,7 +12439,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 12437 "configure"
+#line 12442 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -16548,6 +16553,8 @@ done
+
+
# Check strerror_r, cannot be above as versions with two and three arguments exist
ac_save_CFLAGS="$CFLAGS"
diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index 97b337e33..86cb330fe 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -266,7 +266,8 @@ ftruncate chsize chdir getlogin gethostname kill link symlink sleep ttyname \
alarm access fork execl wait setmode execve pipe dup2 close \
strcasestr getrlimit gettimeofday stat fstat lstat getpwuid vsnprintf dup \
getcwd localtime_r gmtime_r getpwuid_r ttyname_r clock_gettime \
-readlink getgid getpid getppid getuid geteuid umask getegid __secure_getenv)
+readlink getgid getpid getppid getuid geteuid umask getegid \
+secure_getenv __secure_getenv)
# Check strerror_r, cannot be above as versions with two and three arguments exist
LIBGFOR_CHECK_STRERROR_R
diff --git a/libgfortran/libgfortran.h b/libgfortran/libgfortran.h
index 7dafd940e..a8c336361 100644
--- a/libgfortran/libgfortran.h
+++ b/libgfortran/libgfortran.h
@@ -772,6 +772,7 @@ unit_convert get_unformatted_convert (int);
internal_proto(get_unformatted_convert);
/* Secure getenv() which returns NULL if running as SUID/SGID. */
+#ifndef HAVE_SECURE_GETENV
#ifdef HAVE___SECURE_GETENV
#define secure_getenv __secure_getenv
#elif defined(HAVE_GETUID) && defined(HAVE_GETEUID) \
@@ -782,6 +783,7 @@ internal_proto(secure_getenv);
#else
#define secure_getenv getenv
#endif
+#endif
/* string.c */
diff --git a/libgfortran/runtime/environ.c b/libgfortran/runtime/environ.c
index bcb91f446..1f7339770 100644
--- a/libgfortran/runtime/environ.c
+++ b/libgfortran/runtime/environ.c
@@ -459,21 +459,35 @@ search_unit (int unit, int *ip)
{
int low, high, mid;
- low = -1;
- high = n_elist;
- while (high - low > 1)
+ if (n_elist == 0)
+ {
+ *ip = 0;
+ return 0;
+ }
+
+ low = 0;
+ high = n_elist - 1;
+
+ do
{
mid = (low + high) / 2;
- if (unit <= elist[mid].unit)
- high = mid;
+ if (unit == elist[mid].unit)
+ {
+ *ip = mid;
+ return 1;
+ }
+ else if (unit > elist[mid].unit)
+ low = mid + 1;
else
- low = mid;
- }
- *ip = high;
- if (elist[high].unit == unit)
- return 1;
+ high = mid - 1;
+ } while (low <= high);
+
+ if (unit > elist[mid].unit)
+ *ip = mid + 1;
else
- return 0;
+ *ip = mid;
+
+ return 0;
}
/* This matches a keyword. If it is found, return the token supplied,
@@ -588,13 +602,13 @@ mark_single (int unit)
}
if (search_unit (unit, &i))
{
- elist[unit].conv = endian;
+ elist[i].conv = endian;
}
else
{
- for (j=n_elist; j>=i; j--)
+ for (j=n_elist-1; j>=i; j--)
elist[j+1] = elist[j];
-
+
n_elist += 1;
elist[i].unit = unit;
elist[i].conv = endian;
diff --git a/libgo/MERGE b/libgo/MERGE
index e3e47d3bd..89116d1fe 100644
--- a/libgo/MERGE
+++ b/libgo/MERGE
@@ -1,4 +1,4 @@
-5e806355a9e1
+2d8bc3c94ecb
The first line of this file holds the Mercurial revision number of the
last merge done from the master library sources.
diff --git a/libgo/Makefile.am b/libgo/Makefile.am
index 084399d41..b2eb39e59 100644
--- a/libgo/Makefile.am
+++ b/libgo/Makefile.am
@@ -743,6 +743,7 @@ go_net_files = \
go/net/lookup_unix.go \
go/net/mac.go \
go/net/net.go \
+ go/net/net_posix.go \
go/net/parse.go \
go/net/pipe.go \
go/net/port.go \
diff --git a/libgo/Makefile.in b/libgo/Makefile.in
index 8fd098679..597056429 100644
--- a/libgo/Makefile.in
+++ b/libgo/Makefile.in
@@ -1000,6 +1000,7 @@ go_net_files = \
go/net/lookup_unix.go \
go/net/mac.go \
go/net/net.go \
+ go/net/net_posix.go \
go/net/parse.go \
go/net/pipe.go \
go/net/port.go \
diff --git a/libgo/go/bufio/bufio.go b/libgo/go/bufio/bufio.go
index b44d0e7d1..0e284825b 100644
--- a/libgo/go/bufio/bufio.go
+++ b/libgo/go/bufio/bufio.go
@@ -272,6 +272,9 @@ func (b *Reader) ReadSlice(delim byte) (line []byte, err error) {
panic("not reached")
}
+// ReadLine is a low-level line-reading primitive. Most callers should use
+// ReadBytes('\n') or ReadString('\n') instead.
+//
// ReadLine tries to return a single line, not including the end-of-line bytes.
// If the line was too long for the buffer then isPrefix is set and the
// beginning of the line is returned. The rest of the line will be returned
diff --git a/libgo/go/builtin/builtin.go b/libgo/go/builtin/builtin.go
index e81616ca4..a30943b89 100644
--- a/libgo/go/builtin/builtin.go
+++ b/libgo/go/builtin/builtin.go
@@ -81,9 +81,8 @@ type uintptr uintptr
// integer values.
type byte byte
-// rune is an alias for int and is equivalent to int in all ways. It is
+// rune is an alias for int32 and is equivalent to int32 in all ways. It is
// used, by convention, to distinguish character values from integer values.
-// In a future version of Go, it will change to an alias of int32.
type rune rune
// Type is here for the purposes of documentation only. It is a stand-in
diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go
index 7d1426fb4..09b3c1a27 100644
--- a/libgo/go/bytes/bytes.go
+++ b/libgo/go/bytes/bytes.go
@@ -415,7 +415,7 @@ func Repeat(b []byte, count int) []byte {
// ToUpper returns a copy of the byte array s with all Unicode letters mapped to their upper case.
func ToUpper(s []byte) []byte { return Map(unicode.ToUpper, s) }
-// ToUpper returns a copy of the byte array s with all Unicode letters mapped to their lower case.
+// ToLower returns a copy of the byte array s with all Unicode letters mapped to their lower case.
func ToLower(s []byte) []byte { return Map(unicode.ToLower, s) }
// ToTitle returns a copy of the byte array s with all Unicode letters mapped to their title case.
diff --git a/libgo/go/compress/flate/inflate.go b/libgo/go/compress/flate/inflate.go
index 3f2042bfe..394c32fa3 100644
--- a/libgo/go/compress/flate/inflate.go
+++ b/libgo/go/compress/flate/inflate.go
@@ -16,9 +16,10 @@ import (
const (
maxCodeLen = 16 // max length of Huffman code
maxHist = 32768 // max history required
- maxLit = 286
- maxDist = 32
- numCodes = 19 // number of codes in Huffman meta-code
+ // The next three numbers come from the RFC, section 3.2.7.
+ maxLit = 286
+ maxDist = 32
+ numCodes = 19 // number of codes in Huffman meta-code
)
// A CorruptInputError reports the presence of corrupt input at a given offset.
@@ -306,10 +307,15 @@ func (f *decompressor) readHuffman() error {
}
}
nlit := int(f.b&0x1F) + 257
+ if nlit > maxLit {
+ return CorruptInputError(f.roffset)
+ }
f.b >>= 5
ndist := int(f.b&0x1F) + 1
+ // maxDist is 32, so ndist is always valid.
f.b >>= 5
nclen := int(f.b&0xF) + 4
+ // numCodes is 19, so nclen is always valid.
f.b >>= 4
f.nb -= 5 + 5 + 4
diff --git a/libgo/go/compress/flate/reader_test.go b/libgo/go/compress/flate/reader_test.go
new file mode 100644
index 000000000..54ed788db
--- /dev/null
+++ b/libgo/go/compress/flate/reader_test.go
@@ -0,0 +1,95 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package flate
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+ "runtime"
+ "strings"
+ "testing"
+)
+
+func TestNlitOutOfRange(t *testing.T) {
+ // Trying to decode this bogus flate data, which has a Huffman table
+ // with nlit=288, should not panic.
+ io.Copy(ioutil.Discard, NewReader(strings.NewReader(
+ "\xfc\xfe\x36\xe7\x5e\x1c\xef\xb3\x55\x58\x77\xb6\x56\xb5\x43\xf4"+
+ "\x6f\xf2\xd2\xe6\x3d\x99\xa0\x85\x8c\x48\xeb\xf8\xda\x83\x04\x2a"+
+ "\x75\xc4\xf8\x0f\x12\x11\xb9\xb4\x4b\x09\xa0\xbe\x8b\x91\x4c")))
+}
+
+const (
+ digits = iota
+ twain
+)
+
+var testfiles = []string{
+ // Digits is the digits of the irrational number e. Its decimal representation
+ // does not repeat, but there are only 10 posible digits, so it should be
+ // reasonably compressible.
+ digits: "../testdata/e.txt",
+ // Twain is Project Gutenberg's edition of Mark Twain's classic English novel.
+ twain: "../testdata/Mark.Twain-Tom.Sawyer.txt",
+}
+
+func benchmarkDecode(b *testing.B, testfile, level, n int) {
+ b.StopTimer()
+ b.SetBytes(int64(n))
+ buf0, err := ioutil.ReadFile(testfiles[testfile])
+ if err != nil {
+ b.Fatal(err)
+ }
+ if len(buf0) == 0 {
+ b.Fatalf("test file %q has no data", testfiles[testfile])
+ }
+ compressed := new(bytes.Buffer)
+ w, err := NewWriter(compressed, level)
+ if err != nil {
+ b.Fatal(err)
+ }
+ for i := 0; i < n; i += len(buf0) {
+ if len(buf0) > n-i {
+ buf0 = buf0[:n-i]
+ }
+ io.Copy(w, bytes.NewBuffer(buf0))
+ }
+ w.Close()
+ buf1 := compressed.Bytes()
+ buf0, compressed, w = nil, nil, nil
+ runtime.GC()
+ b.StartTimer()
+ for i := 0; i < b.N; i++ {
+ io.Copy(ioutil.Discard, NewReader(bytes.NewBuffer(buf1)))
+ }
+}
+
+// These short names are so that gofmt doesn't break the BenchmarkXxx function
+// bodies below over multiple lines.
+const (
+ speed = BestSpeed
+ default_ = DefaultCompression
+ compress = BestCompression
+)
+
+func BenchmarkDecodeDigitsSpeed1e4(b *testing.B) { benchmarkDecode(b, digits, speed, 1e4) }
+func BenchmarkDecodeDigitsSpeed1e5(b *testing.B) { benchmarkDecode(b, digits, speed, 1e5) }
+func BenchmarkDecodeDigitsSpeed1e6(b *testing.B) { benchmarkDecode(b, digits, speed, 1e6) }
+func BenchmarkDecodeDigitsDefault1e4(b *testing.B) { benchmarkDecode(b, digits, default_, 1e4) }
+func BenchmarkDecodeDigitsDefault1e5(b *testing.B) { benchmarkDecode(b, digits, default_, 1e5) }
+func BenchmarkDecodeDigitsDefault1e6(b *testing.B) { benchmarkDecode(b, digits, default_, 1e6) }
+func BenchmarkDecodeDigitsCompress1e4(b *testing.B) { benchmarkDecode(b, digits, compress, 1e4) }
+func BenchmarkDecodeDigitsCompress1e5(b *testing.B) { benchmarkDecode(b, digits, compress, 1e5) }
+func BenchmarkDecodeDigitsCompress1e6(b *testing.B) { benchmarkDecode(b, digits, compress, 1e6) }
+func BenchmarkDecodeTwainSpeed1e4(b *testing.B) { benchmarkDecode(b, twain, speed, 1e4) }
+func BenchmarkDecodeTwainSpeed1e5(b *testing.B) { benchmarkDecode(b, twain, speed, 1e5) }
+func BenchmarkDecodeTwainSpeed1e6(b *testing.B) { benchmarkDecode(b, twain, speed, 1e6) }
+func BenchmarkDecodeTwainDefault1e4(b *testing.B) { benchmarkDecode(b, twain, default_, 1e4) }
+func BenchmarkDecodeTwainDefault1e5(b *testing.B) { benchmarkDecode(b, twain, default_, 1e5) }
+func BenchmarkDecodeTwainDefault1e6(b *testing.B) { benchmarkDecode(b, twain, default_, 1e6) }
+func BenchmarkDecodeTwainCompress1e4(b *testing.B) { benchmarkDecode(b, twain, compress, 1e4) }
+func BenchmarkDecodeTwainCompress1e5(b *testing.B) { benchmarkDecode(b, twain, compress, 1e5) }
+func BenchmarkDecodeTwainCompress1e6(b *testing.B) { benchmarkDecode(b, twain, compress, 1e6) }
diff --git a/libgo/go/crypto/elliptic/elliptic.go b/libgo/go/crypto/elliptic/elliptic.go
index 30835a90b..a3990891b 100644
--- a/libgo/go/crypto/elliptic/elliptic.go
+++ b/libgo/go/crypto/elliptic/elliptic.go
@@ -370,7 +370,7 @@ func P384() Curve {
return p384
}
-// P256 returns a Curve which implements P-521 (see FIPS 186-3, section D.2.5)
+// P521 returns a Curve which implements P-521 (see FIPS 186-3, section D.2.5)
func P521() Curve {
initonce.Do(initAll)
return p521
diff --git a/libgo/go/crypto/rand/rand_test.go b/libgo/go/crypto/rand/rand_test.go
index da091ba8c..e46e61d37 100644
--- a/libgo/go/crypto/rand/rand_test.go
+++ b/libgo/go/crypto/rand/rand_test.go
@@ -30,3 +30,14 @@ func TestRead(t *testing.T) {
t.Fatalf("Compressed %d -> %d", len(b), z.Len())
}
}
+
+func TestReadEmpty(t *testing.T) {
+ n, err := Reader.Read(make([]byte, 0))
+ if n != 0 || err != nil {
+ t.Fatalf("Read(make([]byte, 0)) = %d, %v", n, err)
+ }
+ n, err = Reader.Read(nil)
+ if n != 0 || err != nil {
+ t.Fatalf("Read(nil) = %d, %v", n, err)
+ }
+}
diff --git a/libgo/go/crypto/rand/rand_windows.go b/libgo/go/crypto/rand/rand_windows.go
index 2b2bd4bba..82b39b64a 100644
--- a/libgo/go/crypto/rand/rand_windows.go
+++ b/libgo/go/crypto/rand/rand_windows.go
@@ -35,6 +35,10 @@ func (r *rngReader) Read(b []byte) (n int, err error) {
}
}
r.mu.Unlock()
+
+ if len(b) == 0 {
+ return 0, nil
+ }
err = syscall.CryptGenRandom(r.prov, uint32(len(b)), &b[0])
if err != nil {
return 0, os.NewSyscallError("CryptGenRandom", err)
diff --git a/libgo/go/crypto/rsa/pkcs1v15.go b/libgo/go/crypto/rsa/pkcs1v15.go
index a32236e47..f39a48a6a 100644
--- a/libgo/go/crypto/rsa/pkcs1v15.go
+++ b/libgo/go/crypto/rsa/pkcs1v15.go
@@ -25,10 +25,10 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er
return
}
- // EM = 0x02 || PS || 0x00 || M
- em := make([]byte, k-1)
- em[0] = 2
- ps, mm := em[1:len(em)-len(msg)-1], em[len(em)-len(msg):]
+ // EM = 0x00 || 0x02 || PS || 0x00 || M
+ em := make([]byte, k)
+ em[1] = 2
+ ps, mm := em[2:len(em)-len(msg)-1], em[len(em)-len(msg):]
err = nonZeroRandomBytes(ps, rand)
if err != nil {
return
@@ -38,7 +38,9 @@ func EncryptPKCS1v15(rand io.Reader, pub *PublicKey, msg []byte) (out []byte, er
m := new(big.Int).SetBytes(em)
c := encrypt(new(big.Int), pub, m)
- out = c.Bytes()
+
+ copyWithLeftPad(em, c.Bytes())
+ out = em
return
}
@@ -185,9 +187,12 @@ func SignPKCS1v15(rand io.Reader, priv *PrivateKey, hash crypto.Hash, hashed []b
m := new(big.Int).SetBytes(em)
c, err := decrypt(rand, priv, m)
- if err == nil {
- s = c.Bytes()
+ if err != nil {
+ return
}
+
+ copyWithLeftPad(em, c.Bytes())
+ s = em
return
}
@@ -241,3 +246,13 @@ func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte,
}
return
}
+
+// copyWithLeftPad copies src to the end of dest, padding with zero bytes as
+// needed.
+func copyWithLeftPad(dest, src []byte) {
+ numPaddingBytes := len(dest) - len(src)
+ for i := 0; i < numPaddingBytes; i++ {
+ dest[i] = 0
+ }
+ copy(dest[numPaddingBytes:], src)
+}
diff --git a/libgo/go/crypto/tls/conn.go b/libgo/go/crypto/tls/conn.go
index 2a5115dc6..455910af4 100644
--- a/libgo/go/crypto/tls/conn.go
+++ b/libgo/go/crypto/tls/conn.go
@@ -487,6 +487,16 @@ Again:
return err
}
typ := recordType(b.data[0])
+
+ // No valid TLS record has a type of 0x80, however SSLv2 handshakes
+ // start with a uint16 length where the MSB is set and the first record
+ // is always < 256 bytes long. Therefore typ == 0x80 strongly suggests
+ // an SSLv2 client.
+ if want == recordTypeHandshake && typ == 0x80 {
+ c.sendAlert(alertProtocolVersion)
+ return errors.New("tls: unsupported SSLv2 handshake received")
+ }
+
vers := uint16(b.data[1])<<8 | uint16(b.data[2])
n := int(b.data[3])<<8 | int(b.data[4])
if c.haveVers && vers != c.vers {
diff --git a/libgo/go/crypto/x509/verify.go b/libgo/go/crypto/x509/verify.go
index 307c5ef03..28814539d 100644
--- a/libgo/go/crypto/x509/verify.go
+++ b/libgo/go/crypto/x509/verify.go
@@ -39,7 +39,7 @@ type CertificateInvalidError struct {
func (e CertificateInvalidError) Error() string {
switch e.Reason {
case NotAuthorizedToSign:
- return "x509: certificate is not authorized to sign other other certificates"
+ return "x509: certificate is not authorized to sign other certificates"
case Expired:
return "x509: certificate has expired or is not yet valid"
case CANotAuthorizedForThisName:
diff --git a/libgo/go/crypto/x509/x509.go b/libgo/go/crypto/x509/x509.go
index c4d85e67f..e6b0c58ee 100644
--- a/libgo/go/crypto/x509/x509.go
+++ b/libgo/go/crypto/x509/x509.go
@@ -344,6 +344,55 @@ func (c *Certificate) Equal(other *Certificate) bool {
return bytes.Equal(c.Raw, other.Raw)
}
+// Entrust have a broken root certificate (CN=Entrust.net Certification
+// Authority (2048)) which isn't marked as a CA certificate and is thus invalid
+// according to PKIX.
+// We recognise this certificate by its SubjectPublicKeyInfo and exempt it
+// from the Basic Constraints requirement.
+// See http://www.entrust.net/knowledge-base/technote.cfm?tn=7869
+//
+// TODO(agl): remove this hack once their reissued root is sufficiently
+// widespread.
+var entrustBrokenSPKI = []byte{
+ 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09,
+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
+ 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01,
+ 0x00, 0x97, 0xa3, 0x2d, 0x3c, 0x9e, 0xde, 0x05,
+ 0xda, 0x13, 0xc2, 0x11, 0x8d, 0x9d, 0x8e, 0xe3,
+ 0x7f, 0xc7, 0x4b, 0x7e, 0x5a, 0x9f, 0xb3, 0xff,
+ 0x62, 0xab, 0x73, 0xc8, 0x28, 0x6b, 0xba, 0x10,
+ 0x64, 0x82, 0x87, 0x13, 0xcd, 0x57, 0x18, 0xff,
+ 0x28, 0xce, 0xc0, 0xe6, 0x0e, 0x06, 0x91, 0x50,
+ 0x29, 0x83, 0xd1, 0xf2, 0xc3, 0x2a, 0xdb, 0xd8,
+ 0xdb, 0x4e, 0x04, 0xcc, 0x00, 0xeb, 0x8b, 0xb6,
+ 0x96, 0xdc, 0xbc, 0xaa, 0xfa, 0x52, 0x77, 0x04,
+ 0xc1, 0xdb, 0x19, 0xe4, 0xae, 0x9c, 0xfd, 0x3c,
+ 0x8b, 0x03, 0xef, 0x4d, 0xbc, 0x1a, 0x03, 0x65,
+ 0xf9, 0xc1, 0xb1, 0x3f, 0x72, 0x86, 0xf2, 0x38,
+ 0xaa, 0x19, 0xae, 0x10, 0x88, 0x78, 0x28, 0xda,
+ 0x75, 0xc3, 0x3d, 0x02, 0x82, 0x02, 0x9c, 0xb9,
+ 0xc1, 0x65, 0x77, 0x76, 0x24, 0x4c, 0x98, 0xf7,
+ 0x6d, 0x31, 0x38, 0xfb, 0xdb, 0xfe, 0xdb, 0x37,
+ 0x02, 0x76, 0xa1, 0x18, 0x97, 0xa6, 0xcc, 0xde,
+ 0x20, 0x09, 0x49, 0x36, 0x24, 0x69, 0x42, 0xf6,
+ 0xe4, 0x37, 0x62, 0xf1, 0x59, 0x6d, 0xa9, 0x3c,
+ 0xed, 0x34, 0x9c, 0xa3, 0x8e, 0xdb, 0xdc, 0x3a,
+ 0xd7, 0xf7, 0x0a, 0x6f, 0xef, 0x2e, 0xd8, 0xd5,
+ 0x93, 0x5a, 0x7a, 0xed, 0x08, 0x49, 0x68, 0xe2,
+ 0x41, 0xe3, 0x5a, 0x90, 0xc1, 0x86, 0x55, 0xfc,
+ 0x51, 0x43, 0x9d, 0xe0, 0xb2, 0xc4, 0x67, 0xb4,
+ 0xcb, 0x32, 0x31, 0x25, 0xf0, 0x54, 0x9f, 0x4b,
+ 0xd1, 0x6f, 0xdb, 0xd4, 0xdd, 0xfc, 0xaf, 0x5e,
+ 0x6c, 0x78, 0x90, 0x95, 0xde, 0xca, 0x3a, 0x48,
+ 0xb9, 0x79, 0x3c, 0x9b, 0x19, 0xd6, 0x75, 0x05,
+ 0xa0, 0xf9, 0x88, 0xd7, 0xc1, 0xe8, 0xa5, 0x09,
+ 0xe4, 0x1a, 0x15, 0xdc, 0x87, 0x23, 0xaa, 0xb2,
+ 0x75, 0x8c, 0x63, 0x25, 0x87, 0xd8, 0xf8, 0x3d,
+ 0xa6, 0xc2, 0xcc, 0x66, 0xff, 0xa5, 0x66, 0x68,
+ 0x55, 0x02, 0x03, 0x01, 0x00, 0x01,
+}
+
// CheckSignatureFrom verifies that the signature on c is a valid signature
// from parent.
func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
@@ -352,8 +401,10 @@ func (c *Certificate) CheckSignatureFrom(parent *Certificate) (err error) {
// certificate, or the extension is present but the cA boolean is not
// asserted, then the certified public key MUST NOT be used to verify
// certificate signatures."
- if parent.Version == 3 && !parent.BasicConstraintsValid ||
- parent.BasicConstraintsValid && !parent.IsCA {
+ // (except for Entrust, see comment above entrustBrokenSPKI)
+ if (parent.Version == 3 && !parent.BasicConstraintsValid ||
+ parent.BasicConstraintsValid && !parent.IsCA) &&
+ !bytes.Equal(c.RawSubjectPublicKeyInfo, entrustBrokenSPKI) {
return ConstraintViolationError{}
}
diff --git a/libgo/go/database/sql/fakedb_test.go b/libgo/go/database/sql/fakedb_test.go
index 184e7756c..a11fb788e 100644
--- a/libgo/go/database/sql/fakedb_test.go
+++ b/libgo/go/database/sql/fakedb_test.go
@@ -31,7 +31,7 @@ var _ = log.Printf
// INSERT|<tablename>|col=val,col2=val2,col3=?
// SELECT|<tablename>|projectcol1,projectcol2|filtercol=?,filtercol2=?
//
-// When opening a a fakeDriver's database, it starts empty with no
+// When opening a fakeDriver's database, it starts empty with no
// tables. All tables and data are stored in memory only.
type fakeDriver struct {
mu sync.Mutex
@@ -234,7 +234,7 @@ func checkSubsetTypes(args []driver.Value) error {
func (c *fakeConn) Exec(query string, args []driver.Value) (driver.Result, error) {
// This is an optional interface, but it's implemented here
- // just to check that all the args of of the proper types.
+ // just to check that all the args are of the proper types.
// ErrSkip is returned so the caller acts as if we didn't
// implement this at all.
err := checkSubsetTypes(args)
@@ -249,7 +249,7 @@ func errf(msg string, args ...interface{}) error {
}
// parts are table|selectCol1,selectCol2|whereCol=?,whereCol2=?
-// (note that where where columns must always contain ? marks,
+// (note that where columns must always contain ? marks,
// just a limitation for fakedb)
func (c *fakeConn) prepareSelect(stmt *fakeStmt, parts []string) (driver.Stmt, error) {
if len(parts) != 3 {
diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go
index 89136ef6e..d557fc830 100644
--- a/libgo/go/database/sql/sql.go
+++ b/libgo/go/database/sql/sql.go
@@ -311,7 +311,10 @@ func (db *DB) prepare(query string) (stmt *Stmt, err error) {
if err != nil {
return nil, err
}
- defer db.putConn(ci, err)
+ defer func() {
+ db.putConn(ci, err)
+ }()
+
si, err := ci.Prepare(query)
if err != nil {
return nil, err
@@ -345,7 +348,9 @@ func (db *DB) exec(query string, sargs []driver.Value) (res Result, err error) {
if err != nil {
return nil, err
}
- defer db.putConn(ci, err)
+ defer func() {
+ db.putConn(ci, err)
+ }()
if execer, ok := ci.(driver.Execer); ok {
resi, err := execer.Exec(query, sargs)
diff --git a/libgo/go/encoding/binary/varint.go b/libgo/go/encoding/binary/varint.go
index b756afdd0..719018b60 100644
--- a/libgo/go/encoding/binary/varint.go
+++ b/libgo/go/encoding/binary/varint.go
@@ -123,7 +123,7 @@ func ReadUvarint(r io.ByteReader) (uint64, error) {
panic("unreachable")
}
-// ReadVarint reads an encoded unsigned integer from r and returns it as a uint64.
+// ReadVarint reads an encoded unsigned integer from r and returns it as an int64.
func ReadVarint(r io.ByteReader) (int64, error) {
ux, err := ReadUvarint(r) // ok to continue in presence of error
x := int64(ux >> 1)
diff --git a/libgo/go/encoding/gob/decode.go b/libgo/go/encoding/gob/decode.go
index e32a178ab..8690b35d7 100644
--- a/libgo/go/encoding/gob/decode.go
+++ b/libgo/go/encoding/gob/decode.go
@@ -562,6 +562,9 @@ func (dec *Decoder) ignoreSingle(engine *decEngine) {
func (dec *Decoder) decodeArrayHelper(state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, length, elemIndir int, ovfl error) {
instr := &decInstr{elemOp, 0, elemIndir, 0, ovfl}
for i := 0; i < length; i++ {
+ if state.b.Len() == 0 {
+ errorf("decoding array or slice: length exceeds input size (%d elements)", length)
+ }
up := unsafe.Pointer(p)
if elemIndir > 1 {
up = decIndirect(up, elemIndir)
@@ -652,9 +655,6 @@ func (dec *Decoder) ignoreMap(state *decoderState, keyOp, elemOp decOp) {
// Slices are encoded as an unsigned length followed by the elements.
func (dec *Decoder) decodeSlice(atyp reflect.Type, state *decoderState, p uintptr, elemOp decOp, elemWid uintptr, indir, elemIndir int, ovfl error) {
nr := state.decodeUint()
- if nr > uint64(state.b.Len()) {
- errorf("length of slice exceeds input size (%d elements)", nr)
- }
n := int(nr)
if indir > 0 {
up := unsafe.Pointer(p)
diff --git a/libgo/go/encoding/gob/doc.go b/libgo/go/encoding/gob/doc.go
index 821d9a3fe..6d77c171f 100644
--- a/libgo/go/encoding/gob/doc.go
+++ b/libgo/go/encoding/gob/doc.go
@@ -118,7 +118,7 @@ elements using the standard gob encoding for their type, recursively.
Maps are sent as an unsigned count followed by that many key, element
pairs. Empty but non-nil maps are sent, so if the sender has allocated
-a map, the receiver will allocate a map even no elements are
+a map, the receiver will allocate a map even if no elements are
transmitted.
Structs are sent as a sequence of (field number, field value) pairs. The field
diff --git a/libgo/go/encoding/gob/encoder_test.go b/libgo/go/encoding/gob/encoder_test.go
index c4947cbb8..db824d999 100644
--- a/libgo/go/encoding/gob/encoder_test.go
+++ b/libgo/go/encoding/gob/encoder_test.go
@@ -736,3 +736,32 @@ func TestPtrToMapOfMap(t *testing.T) {
t.Fatalf("expected %v got %v", data, newData)
}
}
+
+// There was an error check comparing the length of the input with the
+// length of the slice being decoded. It was wrong because the next
+// thing in the input might be a type definition, which would lead to
+// an incorrect length check. This test reproduces the corner case.
+
+type Z struct {
+}
+
+func Test29ElementSlice(t *testing.T) {
+ Register(Z{})
+ src := make([]interface{}, 100) // Size needs to be bigger than size of type definition.
+ for i := range src {
+ src[i] = Z{}
+ }
+ buf := new(bytes.Buffer)
+ err := NewEncoder(buf).Encode(src)
+ if err != nil {
+ t.Fatalf("encode: %v", err)
+ return
+ }
+
+ var dst []interface{}
+ err = NewDecoder(buf).Decode(&dst)
+ if err != nil {
+ t.Errorf("decode: %v", err)
+ return
+ }
+}
diff --git a/libgo/go/encoding/gob/type.go b/libgo/go/encoding/gob/type.go
index 0dd7a0a77..a8ee2fa4a 100644
--- a/libgo/go/encoding/gob/type.go
+++ b/libgo/go/encoding/gob/type.go
@@ -749,12 +749,28 @@ func Register(value interface{}) {
rt := reflect.TypeOf(value)
name := rt.String()
- // But for named types (or pointers to them), qualify with import path.
+ // But for named types (or pointers to them), qualify with import path (but see inner comment).
// Dereference one pointer looking for a named type.
star := ""
if rt.Name() == "" {
if pt := rt; pt.Kind() == reflect.Ptr {
star = "*"
+ // NOTE: The following line should be rt = pt.Elem() to implement
+ // what the comment above claims, but fixing it would break compatibility
+ // with existing gobs.
+ //
+ // Given package p imported as "full/p" with these definitions:
+ // package p
+ // type T1 struct { ... }
+ // this table shows the intended and actual strings used by gob to
+ // name the types:
+ //
+ // Type Correct string Actual string
+ //
+ // T1 full/p.T1 full/p.T1
+ // *T1 *full/p.T1 *p.T1
+ //
+ // The missing full path cannot be fixed without breaking existing gob decoders.
rt = pt
}
}
diff --git a/libgo/go/encoding/json/encode.go b/libgo/go/encoding/json/encode.go
index b6e1cb16e..d2c1c4424 100644
--- a/libgo/go/encoding/json/encode.go
+++ b/libgo/go/encoding/json/encode.go
@@ -55,7 +55,7 @@ import (
// nil pointer or interface value, and any array, slice, map, or string of
// length zero. The object's default key string is the struct field name
// but can be specified in the struct field's tag value. The "json" key in
-// struct field's tag value is the key name, followed by an optional comma
+// the struct field's tag value is the key name, followed by an optional comma
// and options. Examples:
//
// // Field is ignored by this package.
diff --git a/libgo/go/flag/flag.go b/libgo/go/flag/flag.go
index 5444ad141..bbabd88c8 100644
--- a/libgo/go/flag/flag.go
+++ b/libgo/go/flag/flag.go
@@ -33,7 +33,7 @@
After parsing, the arguments after the flag are available as the
slice flag.Args() or individually as flag.Arg(i).
- The arguments are indexed from 0 up to flag.NArg().
+ The arguments are indexed from 0 through flag.NArg()-1.
Command line flag syntax:
-flag
@@ -707,7 +707,7 @@ func (f *FlagSet) parseOne() (bool, error) {
if fv, ok := flag.Value.(*boolValue); ok { // special case: doesn't need an arg
if has_value {
if err := fv.Set(value); err != nil {
- f.failf("invalid boolean value %q for -%s: %v", value, name, err)
+ return false, f.failf("invalid boolean value %q for -%s: %v", value, name, err)
}
} else {
fv.Set("true")
diff --git a/libgo/go/fmt/fmt_test.go b/libgo/go/fmt/fmt_test.go
index 500a45944..98ebfb741 100644
--- a/libgo/go/fmt/fmt_test.go
+++ b/libgo/go/fmt/fmt_test.go
@@ -844,3 +844,15 @@ func TestIsSpace(t *testing.T) {
}
}
}
+
+func TestNilDoesNotBecomeTyped(t *testing.T) {
+ type A struct{}
+ type B struct{}
+ var a *A = nil
+ var b B = B{}
+ got := Sprintf("%s %s %s %s %s", nil, a, nil, b, nil)
+ const expect = "%!s(<nil>) %!s(*fmt_test.A=<nil>) %!s(<nil>) {} %!s(<nil>)"
+ if got != expect {
+ t.Errorf("expected:\n\t%q\ngot:\n\t%q", expect, got)
+ }
+}
diff --git a/libgo/go/fmt/print.go b/libgo/go/fmt/print.go
index 13438243c..f29e8c8e9 100644
--- a/libgo/go/fmt/print.go
+++ b/libgo/go/fmt/print.go
@@ -712,6 +712,9 @@ func (p *pp) handleMethods(verb rune, plus, goSyntax bool, depth int) (wasString
}
func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth int) (wasString bool) {
+ p.field = field
+ p.value = reflect.Value{}
+
if field == nil {
if verb == 'T' || verb == 'v' {
p.buf.Write(nilAngleBytes)
@@ -721,8 +724,6 @@ func (p *pp) printField(field interface{}, verb rune, plus, goSyntax bool, depth
return false
}
- p.field = field
- p.value = reflect.Value{}
// Special processing considerations.
// %T (the value's type) and %p (its address) are special; we always do them first.
switch verb {
diff --git a/libgo/go/go/ast/print.go b/libgo/go/go/ast/print.go
index 02cf9e022..2de9af299 100644
--- a/libgo/go/go/ast/print.go
+++ b/libgo/go/go/ast/print.go
@@ -34,7 +34,8 @@ func NotNilFilter(_ string, v reflect.Value) bool {
//
// A non-nil FieldFilter f may be provided to control the output:
// struct fields for which f(fieldname, fieldvalue) is true are
-// are printed; all others are filtered from the output.
+// are printed; all others are filtered from the output. Unexported
+// struct fields are never printed.
//
func Fprint(w io.Writer, fset *token.FileSet, x interface{}, f FieldFilter) (err error) {
// setup printer
@@ -145,15 +146,18 @@ func (p *printer) print(x reflect.Value) {
p.print(x.Elem())
case reflect.Map:
- p.printf("%s (len = %d) {\n", x.Type(), x.Len())
- p.indent++
- for _, key := range x.MapKeys() {
- p.print(key)
- p.printf(": ")
- p.print(x.MapIndex(key))
+ p.printf("%s (len = %d) {", x.Type(), x.Len())
+ if x.Len() > 0 {
+ p.indent++
p.printf("\n")
+ for _, key := range x.MapKeys() {
+ p.print(key)
+ p.printf(": ")
+ p.print(x.MapIndex(key))
+ p.printf("\n")
+ }
+ p.indent--
}
- p.indent--
p.printf("}")
case reflect.Ptr:
@@ -169,32 +173,57 @@ func (p *printer) print(x reflect.Value) {
p.print(x.Elem())
}
+ case reflect.Array:
+ p.printf("%s {", x.Type())
+ if x.Len() > 0 {
+ p.indent++
+ p.printf("\n")
+ for i, n := 0, x.Len(); i < n; i++ {
+ p.printf("%d: ", i)
+ p.print(x.Index(i))
+ p.printf("\n")
+ }
+ p.indent--
+ }
+ p.printf("}")
+
case reflect.Slice:
if s, ok := x.Interface().([]byte); ok {
p.printf("%#q", s)
return
}
- p.printf("%s (len = %d) {\n", x.Type(), x.Len())
- p.indent++
- for i, n := 0, x.Len(); i < n; i++ {
- p.printf("%d: ", i)
- p.print(x.Index(i))
+ p.printf("%s (len = %d) {", x.Type(), x.Len())
+ if x.Len() > 0 {
+ p.indent++
p.printf("\n")
+ for i, n := 0, x.Len(); i < n; i++ {
+ p.printf("%d: ", i)
+ p.print(x.Index(i))
+ p.printf("\n")
+ }
+ p.indent--
}
- p.indent--
p.printf("}")
case reflect.Struct:
- p.printf("%s {\n", x.Type())
- p.indent++
t := x.Type()
+ p.printf("%s {", t)
+ p.indent++
+ first := true
for i, n := 0, t.NumField(); i < n; i++ {
- name := t.Field(i).Name
- value := x.Field(i)
- if p.filter == nil || p.filter(name, value) {
- p.printf("%s: ", name)
- p.print(value)
- p.printf("\n")
+ // exclude non-exported fields because their
+ // values cannot be accessed via reflection
+ if name := t.Field(i).Name; IsExported(name) {
+ value := x.Field(i)
+ if p.filter == nil || p.filter(name, value) {
+ if first {
+ p.printf("\n")
+ first = false
+ }
+ p.printf("%s: ", name)
+ p.print(value)
+ p.printf("\n")
+ }
}
}
p.indent--
diff --git a/libgo/go/go/ast/print_test.go b/libgo/go/go/ast/print_test.go
index 71c028e75..210f16430 100644
--- a/libgo/go/go/ast/print_test.go
+++ b/libgo/go/go/ast/print_test.go
@@ -23,6 +23,7 @@ var tests = []struct {
{"foobar", "0 \"foobar\""},
// maps
+ {map[Expr]string{}, `0 map[ast.Expr]string (len = 0) {}`},
{map[string]int{"a": 1},
`0 map[string]int (len = 1) {
1 . "a": 1
@@ -31,7 +32,21 @@ var tests = []struct {
// pointers
{new(int), "0 *0"},
+ // arrays
+ {[0]int{}, `0 [0]int {}`},
+ {[3]int{1, 2, 3},
+ `0 [3]int {
+ 1 . 0: 1
+ 2 . 1: 2
+ 3 . 2: 3
+ 4 }`},
+ {[...]int{42},
+ `0 [1]int {
+ 1 . 0: 42
+ 2 }`},
+
// slices
+ {[]int{}, `0 []int (len = 0) {}`},
{[]int{1, 2, 3},
`0 []int (len = 3) {
1 . 0: 1
@@ -40,6 +55,12 @@ var tests = []struct {
4 }`},
// structs
+ {struct{}{}, `0 struct {} {}`},
+ {struct{ x int }{007}, `0 struct { x int } {}`},
+ {struct{ X, y int }{42, 991},
+ `0 struct { X int; y int } {
+ 1 . X: 42
+ 2 }`},
{struct{ X, Y int }{42, 991},
`0 struct { X int; Y int } {
1 . X: 42
diff --git a/libgo/go/go/ast/resolve.go b/libgo/go/go/ast/resolve.go
index 908e61c5d..54b5d7325 100644
--- a/libgo/go/go/ast/resolve.go
+++ b/libgo/go/go/ast/resolve.go
@@ -136,7 +136,7 @@ func NewPackage(fset *token.FileSet, files map[string]*File, importer Importer,
for _, obj := range pkg.Data.(*Scope).Objects {
p.declare(fileScope, pkgScope, obj)
}
- } else {
+ } else if name != "_" {
// declare imported package object in file scope
// (do not re-use pkg in the file scope but create
// a new object instead; the Decl field is different
diff --git a/libgo/go/go/ast/walk.go b/libgo/go/go/ast/walk.go
index 181cfd149..66b1dc249 100644
--- a/libgo/go/go/ast/walk.go
+++ b/libgo/go/go/ast/walk.go
@@ -344,9 +344,6 @@ func Walk(v Visitor, node Node) {
}
Walk(v, n.Name)
walkDeclList(v, n.Decls)
- for _, g := range n.Comments {
- Walk(v, g)
- }
// don't walk n.Comments - they have been
// visited already through the individual
// nodes
diff --git a/libgo/go/go/build/build.go b/libgo/go/go/build/build.go
index 7a81d5030..67e73c5e4 100644
--- a/libgo/go/go/build/build.go
+++ b/libgo/go/go/build/build.go
@@ -536,7 +536,7 @@ Found:
return p, err
}
- pkg := string(pf.Name.Name)
+ pkg := pf.Name.Name
if pkg == "documentation" {
continue
}
@@ -570,7 +570,7 @@ Found:
if !ok {
continue
}
- quoted := string(spec.Path.Value)
+ quoted := spec.Path.Value
path, err := strconv.Unquote(quoted)
if err != nil {
log.Panicf("%s: parser returned invalid quoted string: <%s>", filename, quoted)
@@ -678,7 +678,7 @@ func (ctxt *Context) shouldBuild(content []byte) bool {
}
line = bytes.TrimSpace(line)
if len(line) == 0 { // Blank line
- end = cap(content) - cap(line) // &line[0] - &content[0]
+ end = len(content) - len(p)
continue
}
if !bytes.HasPrefix(line, slashslash) { // Not comment line
diff --git a/libgo/go/go/build/build_test.go b/libgo/go/go/build/build_test.go
index 560ebad5c..caa4f26f3 100644
--- a/libgo/go/go/build/build_test.go
+++ b/libgo/go/go/build/build_test.go
@@ -75,3 +75,32 @@ func TestLocalDirectory(t *testing.T) {
t.Fatalf("ImportPath=%q, want %q", p.ImportPath, "go/build")
}
}
+
+func TestShouldBuild(t *testing.T) {
+ const file1 = "// +build tag1\n\n" +
+ "package main\n"
+
+ const file2 = "// +build cgo\n\n" +
+ "// This package implements parsing of tags like\n" +
+ "// +build tag1\n" +
+ "package build"
+
+ const file3 = "// Copyright The Go Authors.\n\n" +
+ "package build\n\n" +
+ "// shouldBuild checks tags given by lines of the form\n" +
+ "// +build tag\n" +
+ "func shouldBuild(content []byte)\n"
+
+ ctx := &Context{BuildTags: []string{"tag1"}}
+ if !ctx.shouldBuild([]byte(file1)) {
+ t.Errorf("should not build file1, expected the contrary")
+ }
+ if ctx.shouldBuild([]byte(file2)) {
+ t.Errorf("should build file2, expected the contrary")
+ }
+
+ ctx = &Context{BuildTags: nil}
+ if !ctx.shouldBuild([]byte(file3)) {
+ t.Errorf("should not build file3, expected the contrary")
+ }
+}
diff --git a/libgo/go/go/build/doc.go b/libgo/go/go/build/doc.go
index 67c26ac7f..9b7a946f2 100644
--- a/libgo/go/go/build/doc.go
+++ b/libgo/go/go/build/doc.go
@@ -60,7 +60,7 @@
// A build constraint is a line comment beginning with the directive +build
// that lists the conditions under which a file should be included in the package.
// Constraints may appear in any kind of source file (not just Go), but
-// they must be appear near the top of the file, preceded
+// they must appear near the top of the file, preceded
// only by blank lines and other line comments.
//
// A build constraint is evaluated as the OR of space-separated options;
diff --git a/libgo/go/go/doc/reader.go b/libgo/go/go/doc/reader.go
index 5eaae37b7..60b174fec 100644
--- a/libgo/go/go/doc/reader.go
+++ b/libgo/go/go/doc/reader.go
@@ -494,7 +494,7 @@ func (r *reader) readPackage(pkg *ast.Package, mode Mode) {
r.funcs = make(methodSet)
// sort package files before reading them so that the
- // result result does not depend on map iteration order
+ // result does not depend on map iteration order
i := 0
for filename := range pkg.Files {
r.filenames[i] = filename
diff --git a/libgo/go/go/doc/testdata/error2.1.golden b/libgo/go/go/doc/testdata/error2.1.golden
index 776bd1b3e..dbcc1b03e 100644
--- a/libgo/go/go/doc/testdata/error2.1.golden
+++ b/libgo/go/go/doc/testdata/error2.1.golden
@@ -10,7 +10,7 @@ FILENAMES
TYPES
//
type I0 interface {
- // When embedded, the the locally declared error interface
+ // When embedded, the locally-declared error interface
// is only visible if all declarations are shown.
error
}
diff --git a/libgo/go/go/doc/testdata/error2.go b/libgo/go/go/doc/testdata/error2.go
index 6cc36feef..6ee96c245 100644
--- a/libgo/go/go/doc/testdata/error2.go
+++ b/libgo/go/go/doc/testdata/error2.go
@@ -5,7 +5,7 @@
package error2
type I0 interface {
- // When embedded, the the locally declared error interface
+ // When embedded, the locally-declared error interface
// is only visible if all declarations are shown.
error
}
diff --git a/libgo/go/go/printer/nodes.go b/libgo/go/go/printer/nodes.go
index f13f9a5a8..e346b9364 100644
--- a/libgo/go/go/printer/nodes.go
+++ b/libgo/go/go/printer/nodes.go
@@ -325,9 +325,14 @@ func (p *printer) parameters(fields *ast.FieldList) {
}
func (p *printer) signature(params, result *ast.FieldList) {
- p.parameters(params)
+ if params != nil {
+ p.parameters(params)
+ } else {
+ p.print(token.LPAREN, token.RPAREN)
+ }
n := result.NumFields()
if n > 0 {
+ // result != nil
p.print(blank)
if n == 1 && result.List[0].Names == nil {
// single anonymous result; no ()'s
diff --git a/libgo/go/go/printer/printer_test.go b/libgo/go/go/printer/printer_test.go
index 497d671f2..ab9e9b2ec 100644
--- a/libgo/go/go/printer/printer_test.go
+++ b/libgo/go/go/printer/printer_test.go
@@ -385,6 +385,35 @@ func (t *t) foo(a, b, c int) int {
}
}
+// TestFuncType tests that an ast.FuncType with a nil Params field
+// can be printed (per go/ast specification). Test case for issue 3870.
+func TestFuncType(t *testing.T) {
+ src := &ast.File{
+ Name: &ast.Ident{Name: "p"},
+ Decls: []ast.Decl{
+ &ast.FuncDecl{
+ Name: &ast.Ident{Name: "f"},
+ Type: &ast.FuncType{},
+ },
+ },
+ }
+
+ var buf bytes.Buffer
+ if err := Fprint(&buf, fset, src); err != nil {
+ t.Fatal(err)
+ }
+ got := buf.String()
+
+ const want = `package p
+
+func f()
+`
+
+ if got != want {
+ t.Fatalf("got:\n%s\nwant:\n%s\n", got, want)
+ }
+}
+
// TextX is a skeleton test that can be filled in for debugging one-off cases.
// Do not remove.
func TestX(t *testing.T) {
diff --git a/libgo/go/go/scanner/errors.go b/libgo/go/go/scanner/errors.go
index 8a75a9650..22de69c3c 100644
--- a/libgo/go/go/scanner/errors.go
+++ b/libgo/go/go/scanner/errors.go
@@ -120,7 +120,7 @@ func PrintError(w io.Writer, err error) {
for _, e := range list {
fmt.Fprintf(w, "%s\n", e)
}
- } else {
+ } else if err != nil {
fmt.Fprintf(w, "%s\n", err)
}
}
diff --git a/libgo/go/go/scanner/scanner.go b/libgo/go/go/scanner/scanner.go
index da508747a..6ef3e14d0 100644
--- a/libgo/go/go/scanner/scanner.go
+++ b/libgo/go/go/scanner/scanner.go
@@ -81,7 +81,7 @@ func (s *Scanner) next() {
}
}
-// A mode value is set of flags (or 0).
+// A mode value is a set of flags (or 0).
// They control scanner behavior.
//
type Mode uint
diff --git a/libgo/go/html/template/content.go b/libgo/go/html/template/content.go
index c1bd2e494..42ea7930f 100644
--- a/libgo/go/html/template/content.go
+++ b/libgo/go/html/template/content.go
@@ -47,7 +47,7 @@ type (
// JSStr("foo\\nbar") is fine, but JSStr("foo\\\nbar") is not.
JSStr string
- // URL encapsulates a known safe URL as defined in RFC 3896.
+ // URL encapsulates a known safe URL or URL substring (see RFC 3986).
// A URL like `javascript:checkThatFormNotEditedBeforeLeavingPage()`
// from a trusted source should go in the page, but by default dynamic
// `javascript:` URLs are filtered out since they are a frequently
diff --git a/libgo/go/html/template/url.go b/libgo/go/html/template/url.go
index 454c791ec..2ca76bf38 100644
--- a/libgo/go/html/template/url.go
+++ b/libgo/go/html/template/url.go
@@ -60,7 +60,7 @@ func urlProcessor(norm bool, args ...interface{}) string {
c := s[i]
switch c {
// Single quote and parens are sub-delims in RFC 3986, but we
- // escape them so the output can be embedded in in single
+ // escape them so the output can be embedded in single
// quoted attributes and unquoted CSS url(...) constructs.
// Single quotes are reserved in URLs, but are only used in
// the obsolete "mark" rule in an appendix in RFC 3986
diff --git a/libgo/go/image/jpeg/reader.go b/libgo/go/image/jpeg/reader.go
index d9adf6e58..8da361191 100644
--- a/libgo/go/image/jpeg/reader.go
+++ b/libgo/go/image/jpeg/reader.go
@@ -74,7 +74,9 @@ const (
comMarker = 0xfe // COMment.
)
-// Maps from the zig-zag ordering to the natural ordering.
+// unzig maps from the zig-zag ordering to the natural ordering. For example,
+// unzig[3] is the column and row of the fourth element in zig-zag order. The
+// value is 16, which means first column (16%8 == 0) and third row (16/8 == 2).
var unzig = [blockSize]int{
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
@@ -101,7 +103,7 @@ type decoder struct {
nComp int
comp [nColorComponent]component
huff [maxTc + 1][maxTh + 1]huffman
- quant [maxTq + 1]block
+ quant [maxTq + 1]block // Quantization tables, in zig-zag order.
b bits
tmp [1024]byte
}
@@ -264,6 +266,7 @@ func (d *decoder) processSOS(n int) error {
for j := 0; j < d.comp[i].h*d.comp[i].v; j++ {
// TODO(nigeltao): make this a "var b block" once the compiler's escape
// analysis is good enough to allocate it on the stack, not the heap.
+ // b is in natural (not zig-zag) order.
b = block{}
// Decode the DC coefficient, as specified in section F.2.2.1.
@@ -282,7 +285,7 @@ func (d *decoder) processSOS(n int) error {
b[0] = dc[i] * qt[0]
// Decode the AC coefficients, as specified in section F.2.2.2.
- for k := 1; k < blockSize; k++ {
+ for zig := 1; zig < blockSize; zig++ {
value, err := d.decodeHuffman(&d.huff[acTable][scan[i].ta])
if err != nil {
return err
@@ -290,20 +293,20 @@ func (d *decoder) processSOS(n int) error {
val0 := value >> 4
val1 := value & 0x0f
if val1 != 0 {
- k += int(val0)
- if k > blockSize {
+ zig += int(val0)
+ if zig > blockSize {
return FormatError("bad DCT index")
}
ac, err := d.receiveExtend(val1)
if err != nil {
return err
}
- b[unzig[k]] = ac * qt[k]
+ b[unzig[zig]] = ac * qt[zig]
} else {
if val0 != 0x0f {
break
}
- k += 0x0f
+ zig += 0x0f
}
}
@@ -393,6 +396,15 @@ func (d *decoder) decode(r io.Reader, configOnly bool) (image.Image, error) {
if marker == eoiMarker { // End Of Image.
break
}
+ if rst0Marker <= marker && marker <= rst7Marker {
+ // Figures B.2 and B.16 of the specification suggest that restart markers should
+ // only occur between Entropy Coded Segments and not after the final ECS.
+ // However, some encoders may generate incorrect JPEGs with a final restart
+ // marker. That restart marker will be seen here instead of inside the processSOS
+ // method, and is ignored as a harmless error. Restart markers have no extra data,
+ // so we check for this before we read the 16-bit length of the segment.
+ continue
+ }
// Read the 16-bit length of the segment. The value includes the 2 bytes for the
// length itself, so we subtract 2 to get the number of remaining bytes.
@@ -421,7 +433,7 @@ func (d *decoder) decode(r io.Reader, configOnly bool) (image.Image, error) {
err = d.processSOS(n)
case marker == driMarker: // Define Restart Interval.
err = d.processDRI(n)
- case marker >= app0Marker && marker <= app15Marker || marker == comMarker: // APPlication specific, or COMment.
+ case app0Marker <= marker && marker <= app15Marker || marker == comMarker: // APPlication specific, or COMment.
err = d.ignore(n)
default:
err = UnsupportedError("unknown marker")
diff --git a/libgo/go/image/jpeg/writer.go b/libgo/go/image/jpeg/writer.go
index 3322c09fe..099298e46 100644
--- a/libgo/go/image/jpeg/writer.go
+++ b/libgo/go/image/jpeg/writer.go
@@ -56,26 +56,28 @@ const (
nQuantIndex
)
-// unscaledQuant are the unscaled quantization tables. Each encoder copies and
-// scales the tables according to its quality parameter.
+// unscaledQuant are the unscaled quantization tables in zig-zag order. Each
+// encoder copies and scales the tables according to its quality parameter.
+// The values are derived from section K.1 after converting from natural to
+// zig-zag order.
var unscaledQuant = [nQuantIndex][blockSize]byte{
// Luminance.
{
- 16, 11, 10, 16, 24, 40, 51, 61,
- 12, 12, 14, 19, 26, 58, 60, 55,
- 14, 13, 16, 24, 40, 57, 69, 56,
- 14, 17, 22, 29, 51, 87, 80, 62,
- 18, 22, 37, 56, 68, 109, 103, 77,
- 24, 35, 55, 64, 81, 104, 113, 92,
- 49, 64, 78, 87, 103, 121, 120, 101,
- 72, 92, 95, 98, 112, 100, 103, 99,
+ 16, 11, 12, 14, 12, 10, 16, 14,
+ 13, 14, 18, 17, 16, 19, 24, 40,
+ 26, 24, 22, 22, 24, 49, 35, 37,
+ 29, 40, 58, 51, 61, 60, 57, 51,
+ 56, 55, 64, 72, 92, 78, 64, 68,
+ 87, 69, 55, 56, 80, 109, 81, 87,
+ 95, 98, 103, 104, 103, 62, 77, 113,
+ 121, 112, 100, 120, 92, 101, 103, 99,
},
// Chrominance.
{
- 17, 18, 24, 47, 99, 99, 99, 99,
- 18, 21, 26, 66, 99, 99, 99, 99,
- 24, 26, 56, 99, 99, 99, 99, 99,
- 47, 66, 99, 99, 99, 99, 99, 99,
+ 17, 18, 18, 24, 21, 24, 47, 26,
+ 26, 47, 99, 66, 56, 66, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
99, 99, 99, 99, 99, 99, 99, 99,
@@ -222,7 +224,7 @@ type encoder struct {
buf [16]byte
// bits and nBits are accumulated bits to write to w.
bits, nBits uint32
- // quant is the scaled quantization tables.
+ // quant is the scaled quantization tables, in zig-zag order.
quant [nQuantIndex][blockSize]byte
}
@@ -301,7 +303,7 @@ func (e *encoder) writeMarkerHeader(marker uint8, markerlen int) {
// writeDQT writes the Define Quantization Table marker.
func (e *encoder) writeDQT() {
- markerlen := 2 + int(nQuantIndex)*(1+blockSize)
+ const markerlen = 2 + int(nQuantIndex)*(1+blockSize)
e.writeMarkerHeader(dqtMarker, markerlen)
for i := range e.quant {
e.writeByte(uint8(i))
@@ -311,7 +313,7 @@ func (e *encoder) writeDQT() {
// writeSOF0 writes the Start Of Frame (Baseline) marker.
func (e *encoder) writeSOF0(size image.Point) {
- markerlen := 8 + 3*nColorComponent
+ const markerlen = 8 + 3*nColorComponent
e.writeMarkerHeader(sof0Marker, markerlen)
e.buf[0] = 8 // 8-bit color.
e.buf[1] = uint8(size.Y >> 8)
@@ -344,6 +346,7 @@ func (e *encoder) writeDHT() {
// writeBlock writes a block of pixel data using the given quantization table,
// returning the post-quantized DC value of the DCT-transformed block.
+// b is in natural (not zig-zag) order.
func (e *encoder) writeBlock(b *block, q quantIndex, prevDC int) int {
fdct(b)
// Emit the DC delta.
@@ -351,8 +354,8 @@ func (e *encoder) writeBlock(b *block, q quantIndex, prevDC int) int {
e.emitHuffRLE(huffIndex(2*q+0), 0, dc-prevDC)
// Emit the AC components.
h, runLength := huffIndex(2*q+1), 0
- for k := 1; k < blockSize; k++ {
- ac := div(b[unzig[k]], (8 * int(e.quant[q][k])))
+ for zig := 1; zig < blockSize; zig++ {
+ ac := div(b[unzig[zig]], (8 * int(e.quant[q][zig])))
if ac == 0 {
runLength++
} else {
@@ -433,10 +436,12 @@ func scale(dst *block, src *[4]block) {
// - component 1 uses DC table 0 and AC table 0 "\x01\x00",
// - component 2 uses DC table 1 and AC table 1 "\x02\x11",
// - component 3 uses DC table 1 and AC table 1 "\x03\x11",
-// - padding "\x00\x00\x00".
+// - the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for
+// sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al)
+// should be 0x00, 0x3f, 0x00<<4 | 0x00.
var sosHeader = []byte{
0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
- 0x11, 0x03, 0x11, 0x00, 0x00, 0x00,
+ 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,
}
// writeSOS writes the StartOfScan marker.
@@ -444,6 +449,7 @@ func (e *encoder) writeSOS(m image.Image) {
e.write(sosHeader)
var (
// Scratch buffers to hold the YCbCr values.
+ // The blocks are in natural (not zig-zag) order.
yBlock block
cbBlock [4]block
crBlock [4]block
diff --git a/libgo/go/image/jpeg/writer_test.go b/libgo/go/image/jpeg/writer_test.go
index b8e8fa34e..8732df845 100644
--- a/libgo/go/image/jpeg/writer_test.go
+++ b/libgo/go/image/jpeg/writer_test.go
@@ -6,6 +6,7 @@ package jpeg
import (
"bytes"
+ "fmt"
"image"
"image/color"
"image/png"
@@ -15,6 +16,87 @@ import (
"testing"
)
+// zigzag maps from the natural ordering to the zig-zag ordering. For example,
+// zigzag[0*8 + 3] is the zig-zag sequence number of the element in the fourth
+// column and first row.
+var zigzag = [blockSize]int{
+ 0, 1, 5, 6, 14, 15, 27, 28,
+ 2, 4, 7, 13, 16, 26, 29, 42,
+ 3, 8, 12, 17, 25, 30, 41, 43,
+ 9, 11, 18, 24, 31, 40, 44, 53,
+ 10, 19, 23, 32, 39, 45, 52, 54,
+ 20, 22, 33, 38, 46, 51, 55, 60,
+ 21, 34, 37, 47, 50, 56, 59, 61,
+ 35, 36, 48, 49, 57, 58, 62, 63,
+}
+
+func TestZigUnzig(t *testing.T) {
+ for i := 0; i < blockSize; i++ {
+ if unzig[zigzag[i]] != i {
+ t.Errorf("unzig[zigzag[%d]] == %d", i, unzig[zigzag[i]])
+ }
+ if zigzag[unzig[i]] != i {
+ t.Errorf("zigzag[unzig[%d]] == %d", i, zigzag[unzig[i]])
+ }
+ }
+}
+
+// unscaledQuantInNaturalOrder are the unscaled quantization tables in
+// natural (not zig-zag) order, as specified in section K.1.
+var unscaledQuantInNaturalOrder = [nQuantIndex][blockSize]byte{
+ // Luminance.
+ {
+ 16, 11, 10, 16, 24, 40, 51, 61,
+ 12, 12, 14, 19, 26, 58, 60, 55,
+ 14, 13, 16, 24, 40, 57, 69, 56,
+ 14, 17, 22, 29, 51, 87, 80, 62,
+ 18, 22, 37, 56, 68, 109, 103, 77,
+ 24, 35, 55, 64, 81, 104, 113, 92,
+ 49, 64, 78, 87, 103, 121, 120, 101,
+ 72, 92, 95, 98, 112, 100, 103, 99,
+ },
+ // Chrominance.
+ {
+ 17, 18, 24, 47, 99, 99, 99, 99,
+ 18, 21, 26, 66, 99, 99, 99, 99,
+ 24, 26, 56, 99, 99, 99, 99, 99,
+ 47, 66, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 99,
+ },
+}
+
+func TestUnscaledQuant(t *testing.T) {
+ bad := false
+ for i := quantIndex(0); i < nQuantIndex; i++ {
+ for zig := 0; zig < blockSize; zig++ {
+ got := unscaledQuant[i][zig]
+ want := unscaledQuantInNaturalOrder[i][unzig[zig]]
+ if got != want {
+ t.Errorf("i=%d, zig=%d: got %d, want %d", i, zig, got, want)
+ bad = true
+ }
+ }
+ }
+ if bad {
+ names := [nQuantIndex]string{"Luminance", "Chrominance"}
+ buf := &bytes.Buffer{}
+ for i, name := range names {
+ fmt.Fprintf(buf, "// %s.\n{\n", name)
+ for zig := 0; zig < blockSize; zig++ {
+ fmt.Fprintf(buf, "%d, ", unscaledQuantInNaturalOrder[i][unzig[zig]])
+ if zig%8 == 7 {
+ buf.WriteString("\n")
+ }
+ }
+ buf.WriteString("},\n")
+ }
+ t.Logf("expected unscaledQuant values:\n%s", buf.String())
+ }
+}
+
var testCase = []struct {
filename string
quality int
diff --git a/libgo/go/image/names.go b/libgo/go/image/names.go
index 55f634c17..04ee2cfb4 100644
--- a/libgo/go/image/names.go
+++ b/libgo/go/image/names.go
@@ -20,7 +20,7 @@ var (
)
// Uniform is an infinite-sized Image of uniform color.
-// It implements the color.Color, color.ColorModel, and Image interfaces.
+// It implements the color.Color, color.Model, and Image interfaces.
type Uniform struct {
C color.Color
}
diff --git a/libgo/go/io/io.go b/libgo/go/io/io.go
index 54bf159eb..5187eff70 100644
--- a/libgo/go/io/io.go
+++ b/libgo/go/io/io.go
@@ -130,11 +130,23 @@ type ReadWriteSeeker interface {
}
// ReaderFrom is the interface that wraps the ReadFrom method.
+//
+// ReadFrom reads data from r until EOF or error.
+// The return value n is the number of bytes read.
+// Any error except io.EOF encountered during the read is also returned.
+//
+// The Copy function uses ReaderFrom if available.
type ReaderFrom interface {
ReadFrom(r Reader) (n int64, err error)
}
// WriterTo is the interface that wraps the WriteTo method.
+//
+// WriteTo writes data to w until there's no more data to write or
+// when an error occurs. The return value n is the number of bytes
+// written. Any error encountered during the write is also returned.
+//
+// The Copy function uses WriterTo if available.
type WriterTo interface {
WriteTo(w Writer) (n int64, err error)
}
diff --git a/libgo/go/log/syslog/syslog.go b/libgo/go/log/syslog/syslog.go
index f53310cb0..e5620e1aa 100644
--- a/libgo/go/log/syslog/syslog.go
+++ b/libgo/go/log/syslog/syslog.go
@@ -138,7 +138,11 @@ func (w *Writer) Debug(m string) (err error) {
}
func (n netConn) writeBytes(p Priority, prefix string, b []byte) (int, error) {
- _, err := fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, b)
+ nl := ""
+ if len(b) == 0 || b[len(b)-1] != '\n' {
+ nl = "\n"
+ }
+ _, err := fmt.Fprintf(n.conn, "<%d>%s: %s%s", p, prefix, b, nl)
if err != nil {
return 0, err
}
@@ -146,7 +150,11 @@ func (n netConn) writeBytes(p Priority, prefix string, b []byte) (int, error) {
}
func (n netConn) writeString(p Priority, prefix string, s string) (int, error) {
- _, err := fmt.Fprintf(n.conn, "<%d>%s: %s\n", p, prefix, s)
+ nl := ""
+ if len(s) == 0 || s[len(s)-1] != '\n' {
+ nl = "\n"
+ }
+ _, err := fmt.Fprintf(n.conn, "<%d>%s: %s%s", p, prefix, s, nl)
if err != nil {
return 0, err
}
diff --git a/libgo/go/log/syslog/syslog_test.go b/libgo/go/log/syslog/syslog_test.go
index 0fd623905..b7579c363 100644
--- a/libgo/go/log/syslog/syslog_test.go
+++ b/libgo/go/log/syslog/syslog_test.go
@@ -98,20 +98,32 @@ func TestUDPDial(t *testing.T) {
}
func TestWrite(t *testing.T) {
- done := make(chan string)
- startServer(done)
- l, err := Dial("udp", serverAddr, LOG_ERR, "syslog_test")
- if err != nil {
- t.Fatalf("syslog.Dial() failed: %s", err)
+ tests := []struct {
+ pri Priority
+ pre string
+ msg string
+ exp string
+ }{
+ {LOG_ERR, "syslog_test", "", "<3>syslog_test: \n"},
+ {LOG_ERR, "syslog_test", "write test", "<3>syslog_test: write test\n"},
+ // Write should not add \n if there already is one
+ {LOG_ERR, "syslog_test", "write test 2\n", "<3>syslog_test: write test 2\n"},
}
- msg := "write test"
- _, err = io.WriteString(l, msg)
- if err != nil {
- t.Fatalf("WriteString() failed: %s", err)
- }
- expected := "<3>syslog_test: write test\n"
- rcvd := <-done
- if rcvd != expected {
- t.Fatalf("s.Info() = '%q', but wanted '%q'", rcvd, expected)
+
+ for _, test := range tests {
+ done := make(chan string)
+ startServer(done)
+ l, err := Dial("udp", serverAddr, test.pri, test.pre)
+ if err != nil {
+ t.Fatalf("syslog.Dial() failed: %s", err)
+ }
+ _, err = io.WriteString(l, test.msg)
+ if err != nil {
+ t.Fatalf("WriteString() failed: %s", err)
+ }
+ rcvd := <-done
+ if rcvd != test.exp {
+ t.Fatalf("s.Info() = '%q', but wanted '%q'", rcvd, test.exp)
+ }
}
}
diff --git a/libgo/go/math/all_test.go b/libgo/go/math/all_test.go
index ed66a42fb..35c33ce38 100644
--- a/libgo/go/math/all_test.go
+++ b/libgo/go/math/all_test.go
@@ -1693,6 +1693,17 @@ func alike(a, b float64) bool {
return false
}
+func TestNaN(t *testing.T) {
+ f64 := NaN()
+ if f64 == f64 {
+ t.Fatalf("NaN() returns %g, expected NaN", f64)
+ }
+ f32 := float32(f64)
+ if f32 == f32 {
+ t.Fatalf("float32(NaN()) is %g, expected NaN", f32)
+ }
+}
+
func TestAcos(t *testing.T) {
for i := 0; i < len(vf); i++ {
a := vf[i] / 10
diff --git a/libgo/go/math/big/nat.go b/libgo/go/math/big/nat.go
index eaa6ff066..6d81823bb 100644
--- a/libgo/go/math/big/nat.go
+++ b/libgo/go/math/big/nat.go
@@ -396,7 +396,7 @@ func (z nat) mul(x, y nat) nat {
}
// use basic multiplication if the numbers are small
- if n < karatsubaThreshold || n < 2 {
+ if n < karatsubaThreshold {
z = z.make(m + n)
basicMul(z, x, y)
return z.norm()
diff --git a/libgo/go/math/bits.go b/libgo/go/math/bits.go
index 1cf60ce7d..0df0b1cc9 100644
--- a/libgo/go/math/bits.go
+++ b/libgo/go/math/bits.go
@@ -5,7 +5,7 @@
package math
const (
- uvnan = 0x7FF0000000000001
+ uvnan = 0x7FF8000000000001
uvinf = 0x7FF0000000000000
uvneginf = 0xFFF0000000000000
mask = 0x7FF
diff --git a/libgo/go/math/remainder.go b/libgo/go/math/remainder.go
index a233e8ef1..98bb04dc7 100644
--- a/libgo/go/math/remainder.go
+++ b/libgo/go/math/remainder.go
@@ -4,7 +4,7 @@
package math
-// The original C code and the the comment below are from
+// The original C code and the comment below are from
// FreeBSD's /usr/src/lib/msun/src/e_remainder.c and came
// with this notice. The go code is a simplified version of
// the original C.
diff --git a/libgo/go/mime/grammar.go b/libgo/go/mime/grammar.go
index 83cc41134..09e941e3e 100644
--- a/libgo/go/mime/grammar.go
+++ b/libgo/go/mime/grammar.go
@@ -22,7 +22,7 @@ func isTokenChar(r rune) bool {
return r > 0x20 && r < 0x7f && !isTSpecial(r)
}
-// isToken returns true if s is a 'token' as as defined by RFC 1521
+// isToken returns true if s is a 'token' as defined by RFC 1521
// and RFC 2045.
func isToken(s string) bool {
if s == "" {
diff --git a/libgo/go/mime/multipart/multipart.go b/libgo/go/mime/multipart/multipart.go
index e9e337b92..fb07e1a56 100644
--- a/libgo/go/mime/multipart/multipart.go
+++ b/libgo/go/mime/multipart/multipart.go
@@ -71,7 +71,7 @@ func (p *Part) parseContentDisposition() {
}
}
-// NewReader creates a new multipart Reader reading from r using the
+// NewReader creates a new multipart Reader reading from reader using the
// given MIME boundary.
func NewReader(reader io.Reader, boundary string) *Reader {
b := []byte("\r\n--" + boundary + "--")
diff --git a/libgo/go/net/dial.go b/libgo/go/net/dial.go
index 10ca5faf7..51912397a 100644
--- a/libgo/go/net/dial.go
+++ b/libgo/go/net/dial.go
@@ -173,7 +173,7 @@ func (a stringAddr) String() string { return a.addr }
// Listen announces on the local network address laddr.
// The network string net must be a stream-oriented network:
-// "tcp", "tcp4", "tcp6", or "unix", or "unixpacket".
+// "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
func Listen(net, laddr string) (Listener, error) {
afnet, a, err := resolveNetAddr("listen", net, laddr)
if err != nil {
diff --git a/libgo/go/net/fd.go b/libgo/go/net/fd.go
index 76c953b9b..ff4f4f899 100644
--- a/libgo/go/net/fd.go
+++ b/libgo/go/net/fd.go
@@ -645,10 +645,14 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (netfd *netFD, err e
}
func (fd *netFD) dup() (f *os.File, err error) {
+ syscall.ForkLock.RLock()
ns, err := syscall.Dup(fd.sysfd)
if err != nil {
+ syscall.ForkLock.RUnlock()
return nil, &OpError{"dup", fd.net, fd.laddr, err}
}
+ syscall.CloseOnExec(ns)
+ syscall.ForkLock.RUnlock()
// We want blocking mode for the new fd, hence the double negative.
if err = syscall.SetNonblock(ns, false); err != nil {
diff --git a/libgo/go/net/file.go b/libgo/go/net/file.go
index fc6c6fad8..837326e12 100644
--- a/libgo/go/net/file.go
+++ b/libgo/go/net/file.go
@@ -12,13 +12,18 @@ import (
)
func newFileFD(f *os.File) (*netFD, error) {
+ syscall.ForkLock.RLock()
fd, err := syscall.Dup(int(f.Fd()))
if err != nil {
+ syscall.ForkLock.RUnlock()
return nil, os.NewSyscallError("dup", err)
}
+ syscall.CloseOnExec(fd)
+ syscall.ForkLock.RUnlock()
- proto, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
+ sotype, err := syscall.GetsockoptInt(fd, syscall.SOL_SOCKET, syscall.SO_TYPE)
if err != nil {
+ closesocket(fd)
return nil, os.NewSyscallError("getsockopt", err)
}
@@ -31,24 +36,24 @@ func newFileFD(f *os.File) (*netFD, error) {
return nil, syscall.EINVAL
case *syscall.SockaddrInet4:
family = syscall.AF_INET
- if proto == syscall.SOCK_DGRAM {
+ if sotype == syscall.SOCK_DGRAM {
toAddr = sockaddrToUDP
- } else if proto == syscall.SOCK_RAW {
+ } else if sotype == syscall.SOCK_RAW {
toAddr = sockaddrToIP
}
case *syscall.SockaddrInet6:
family = syscall.AF_INET6
- if proto == syscall.SOCK_DGRAM {
+ if sotype == syscall.SOCK_DGRAM {
toAddr = sockaddrToUDP
- } else if proto == syscall.SOCK_RAW {
+ } else if sotype == syscall.SOCK_RAW {
toAddr = sockaddrToIP
}
case *syscall.SockaddrUnix:
family = syscall.AF_UNIX
toAddr = sockaddrToUnix
- if proto == syscall.SOCK_DGRAM {
+ if sotype == syscall.SOCK_DGRAM {
toAddr = sockaddrToUnixgram
- } else if proto == syscall.SOCK_SEQPACKET {
+ } else if sotype == syscall.SOCK_SEQPACKET {
toAddr = sockaddrToUnixpacket
}
}
@@ -56,8 +61,9 @@ func newFileFD(f *os.File) (*netFD, error) {
sa, _ = syscall.Getpeername(fd)
raddr := toAddr(sa)
- netfd, err := newFD(fd, family, proto, laddr.Network())
+ netfd, err := newFD(fd, family, sotype, laddr.Network())
if err != nil {
+ closesocket(fd)
return nil, err
}
netfd.setAddr(laddr, raddr)
diff --git a/libgo/go/net/http/client.go b/libgo/go/net/http/client.go
index 54564e098..89441424e 100644
--- a/libgo/go/net/http/client.go
+++ b/libgo/go/net/http/client.go
@@ -14,6 +14,7 @@ import (
"errors"
"fmt"
"io"
+ "log"
"net/url"
"strings"
)
@@ -35,7 +36,8 @@ type Client struct {
// following an HTTP redirect. The arguments req and via
// are the upcoming request and the requests made already,
// oldest first. If CheckRedirect returns an error, the client
- // returns that error instead of issue the Request req.
+ // returns that error (wrapped in a url.Error) instead of
+ // issuing the Request req.
//
// If CheckRedirect is nil, the Client uses its default policy,
// which is to stop after 10 consecutive requests.
@@ -87,9 +89,13 @@ type readClose struct {
// Do sends an HTTP request and returns an HTTP response, following
// policy (e.g. redirects, cookies, auth) as configured on the client.
//
-// A non-nil response always contains a non-nil resp.Body.
+// An error is returned if caused by client policy (such as
+// CheckRedirect), or if there was an HTTP protocol error.
+// A non-2xx response doesn't cause an error.
//
-// Callers should close resp.Body when done reading from it. If
+// When err is nil, resp always contains a non-nil resp.Body.
+//
+// Callers should close res.Body when done reading from it. If
// resp.Body is not closed, the Client's underlying RoundTripper
// (typically Transport) may not be able to re-use a persistent TCP
// connection to the server for a subsequent "keep-alive" request.
@@ -102,7 +108,8 @@ func (c *Client) Do(req *Request) (resp *Response, err error) {
return send(req, c.Transport)
}
-// send issues an HTTP request. Caller should close resp.Body when done reading from it.
+// send issues an HTTP request.
+// Caller should close resp.Body when done reading from it.
func send(req *Request, t RoundTripper) (resp *Response, err error) {
if t == nil {
t = DefaultTransport
@@ -130,7 +137,14 @@ func send(req *Request, t RoundTripper) (resp *Response, err error) {
if u := req.URL.User; u != nil {
req.Header.Set("Authorization", "Basic "+base64.URLEncoding.EncodeToString([]byte(u.String())))
}
- return t.RoundTrip(req)
+ resp, err = t.RoundTrip(req)
+ if err != nil {
+ if resp != nil {
+ log.Printf("RoundTripper returned a response & error; ignoring response")
+ }
+ return nil, err
+ }
+ return resp, nil
}
// True if the specified HTTP status code is one for which the Get utility should
@@ -151,10 +165,15 @@ func shouldRedirect(statusCode int) bool {
// 303 (See Other)
// 307 (Temporary Redirect)
//
-// Caller should close r.Body when done reading from it.
+// An error is returned if there were too many redirects or if there
+// was an HTTP protocol error. A non-2xx response doesn't cause an
+// error.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
//
// Get is a wrapper around DefaultClient.Get.
-func Get(url string) (r *Response, err error) {
+func Get(url string) (resp *Response, err error) {
return DefaultClient.Get(url)
}
@@ -167,8 +186,13 @@ func Get(url string) (r *Response, err error) {
// 303 (See Other)
// 307 (Temporary Redirect)
//
-// Caller should close r.Body when done reading from it.
-func (c *Client) Get(url string) (r *Response, err error) {
+// An error is returned if the Client's CheckRedirect function fails
+// or if there was an HTTP protocol error. A non-2xx response doesn't
+// cause an error.
+//
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+func (c *Client) Get(url string) (resp *Response, err error) {
req, err := NewRequest("GET", url, nil)
if err != nil {
return nil, err
@@ -176,7 +200,7 @@ func (c *Client) Get(url string) (r *Response, err error) {
return c.doFollowingRedirects(req)
}
-func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
+func (c *Client) doFollowingRedirects(ireq *Request) (resp *Response, err error) {
// TODO: if/when we add cookie support, the redirected request shouldn't
// necessarily supply the same cookies as the original.
var base *url.URL
@@ -224,17 +248,17 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
req.AddCookie(cookie)
}
urlStr = req.URL.String()
- if r, err = send(req, c.Transport); err != nil {
+ if resp, err = send(req, c.Transport); err != nil {
break
}
- if c := r.Cookies(); len(c) > 0 {
+ if c := resp.Cookies(); len(c) > 0 {
jar.SetCookies(req.URL, c)
}
- if shouldRedirect(r.StatusCode) {
- r.Body.Close()
- if urlStr = r.Header.Get("Location"); urlStr == "" {
- err = errors.New(fmt.Sprintf("%d response missing Location header", r.StatusCode))
+ if shouldRedirect(resp.StatusCode) {
+ resp.Body.Close()
+ if urlStr = resp.Header.Get("Location"); urlStr == "" {
+ err = errors.New(fmt.Sprintf("%d response missing Location header", resp.StatusCode))
break
}
base = req.URL
@@ -244,13 +268,16 @@ func (c *Client) doFollowingRedirects(ireq *Request) (r *Response, err error) {
return
}
+ if resp != nil {
+ resp.Body.Close()
+ }
+
method := ireq.Method
- err = &url.Error{
+ return nil, &url.Error{
Op: method[0:1] + strings.ToLower(method[1:]),
URL: urlStr,
Err: err,
}
- return
}
func defaultCheckRedirect(req *Request, via []*Request) error {
@@ -262,17 +289,17 @@ func defaultCheckRedirect(req *Request, via []*Request) error {
// Post issues a POST to the specified URL.
//
-// Caller should close r.Body when done reading from it.
+// Caller should close resp.Body when done reading from it.
//
// Post is a wrapper around DefaultClient.Post
-func Post(url string, bodyType string, body io.Reader) (r *Response, err error) {
+func Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
return DefaultClient.Post(url, bodyType, body)
}
// Post issues a POST to the specified URL.
//
-// Caller should close r.Body when done reading from it.
-func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response, err error) {
+// Caller should close resp.Body when done reading from it.
+func (c *Client) Post(url string, bodyType string, body io.Reader) (resp *Response, err error) {
req, err := NewRequest("POST", url, body)
if err != nil {
return nil, err
@@ -283,28 +310,30 @@ func (c *Client) Post(url string, bodyType string, body io.Reader) (r *Response,
req.AddCookie(cookie)
}
}
- r, err = send(req, c.Transport)
+ resp, err = send(req, c.Transport)
if err == nil && c.Jar != nil {
- c.Jar.SetCookies(req.URL, r.Cookies())
+ c.Jar.SetCookies(req.URL, resp.Cookies())
}
- return r, err
+ return
}
-// PostForm issues a POST to the specified URL,
-// with data's keys and values urlencoded as the request body.
+// PostForm issues a POST to the specified URL, with data's keys and
+// values URL-encoded as the request body.
//
-// Caller should close r.Body when done reading from it.
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
//
// PostForm is a wrapper around DefaultClient.PostForm
-func PostForm(url string, data url.Values) (r *Response, err error) {
+func PostForm(url string, data url.Values) (resp *Response, err error) {
return DefaultClient.PostForm(url, data)
}
// PostForm issues a POST to the specified URL,
// with data's keys and values urlencoded as the request body.
//
-// Caller should close r.Body when done reading from it.
-func (c *Client) PostForm(url string, data url.Values) (r *Response, err error) {
+// When err is nil, resp always contains a non-nil resp.Body.
+// Caller should close resp.Body when done reading from it.
+func (c *Client) PostForm(url string, data url.Values) (resp *Response, err error) {
return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
}
@@ -318,7 +347,7 @@ func (c *Client) PostForm(url string, data url.Values) (r *Response, err error)
// 307 (Temporary Redirect)
//
// Head is a wrapper around DefaultClient.Head
-func Head(url string) (r *Response, err error) {
+func Head(url string) (resp *Response, err error) {
return DefaultClient.Head(url)
}
@@ -330,7 +359,7 @@ func Head(url string) (r *Response, err error) {
// 302 (Found)
// 303 (See Other)
// 307 (Temporary Redirect)
-func (c *Client) Head(url string) (r *Response, err error) {
+func (c *Client) Head(url string) (resp *Response, err error) {
req, err := NewRequest("HEAD", url, nil)
if err != nil {
return nil, err
diff --git a/libgo/go/net/http/client_test.go b/libgo/go/net/http/client_test.go
index 9b4261b9f..09fcc1c0b 100644
--- a/libgo/go/net/http/client_test.go
+++ b/libgo/go/net/http/client_test.go
@@ -8,6 +8,7 @@ package http_test
import (
"crypto/tls"
+ "crypto/x509"
"errors"
"fmt"
"io"
@@ -231,9 +232,8 @@ func TestRedirects(t *testing.T) {
checkErr = errors.New("no redirects allowed")
res, err = c.Get(ts.URL)
- finalUrl = res.Request.URL.String()
- if e, g := "Get /?n=1: no redirects allowed", fmt.Sprintf("%v", err); e != g {
- t.Errorf("with redirects forbidden, expected error %q, got %q", e, g)
+ if urlError, ok := err.(*url.Error); !ok || urlError.Err != checkErr {
+ t.Errorf("with redirects forbidden, expected a *url.Error with our 'no redirects allowed' error inside; got %#v (%q)", err, err)
}
}
@@ -465,3 +465,49 @@ func TestClientErrorWithRequestURI(t *testing.T) {
t.Errorf("wanted error mentioning RequestURI; got error: %v", err)
}
}
+
+func newTLSTransport(t *testing.T, ts *httptest.Server) *Transport {
+ certs := x509.NewCertPool()
+ for _, c := range ts.TLS.Certificates {
+ roots, err := x509.ParseCertificates(c.Certificate[len(c.Certificate)-1])
+ if err != nil {
+ t.Fatalf("error parsing server's root cert: %v", err)
+ }
+ for _, root := range roots {
+ certs.AddCert(root)
+ }
+ }
+ return &Transport{
+ TLSClientConfig: &tls.Config{RootCAs: certs},
+ }
+}
+
+func TestClientWithCorrectTLSServerName(t *testing.T) {
+ ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ if r.TLS.ServerName != "127.0.0.1" {
+ t.Errorf("expected client to set ServerName 127.0.0.1, got: %q", r.TLS.ServerName)
+ }
+ }))
+ defer ts.Close()
+
+ c := &Client{Transport: newTLSTransport(t, ts)}
+ if _, err := c.Get(ts.URL); err != nil {
+ t.Fatalf("expected successful TLS connection, got error: %v", err)
+ }
+}
+
+func TestClientWithIncorrectTLSServerName(t *testing.T) {
+ ts := httptest.NewTLSServer(HandlerFunc(func(w ResponseWriter, r *Request) {}))
+ defer ts.Close()
+
+ trans := newTLSTransport(t, ts)
+ trans.TLSClientConfig.ServerName = "badserver"
+ c := &Client{Transport: trans}
+ _, err := c.Get(ts.URL)
+ if err == nil {
+ t.Fatalf("expected an error")
+ }
+ if !strings.Contains(err.Error(), "127.0.0.1") || !strings.Contains(err.Error(), "badserver") {
+ t.Errorf("wanted error mentioning 127.0.0.1 and badserver; got error: %v", err)
+ }
+}
diff --git a/libgo/go/net/http/example_test.go b/libgo/go/net/http/example_test.go
index ec814407d..22073eaf7 100644
--- a/libgo/go/net/http/example_test.go
+++ b/libgo/go/net/http/example_test.go
@@ -43,10 +43,10 @@ func ExampleGet() {
log.Fatal(err)
}
robots, err := ioutil.ReadAll(res.Body)
+ res.Body.Close()
if err != nil {
log.Fatal(err)
}
- res.Body.Close()
fmt.Printf("%s", robots)
}
diff --git a/libgo/go/net/http/export_test.go b/libgo/go/net/http/export_test.go
index 13640ca85..313c6af7a 100644
--- a/libgo/go/net/http/export_test.go
+++ b/libgo/go/net/http/export_test.go
@@ -11,8 +11,8 @@ import "time"
func (t *Transport) IdleConnKeysForTesting() (keys []string) {
keys = make([]string, 0)
- t.lk.Lock()
- defer t.lk.Unlock()
+ t.idleLk.Lock()
+ defer t.idleLk.Unlock()
if t.idleConn == nil {
return
}
@@ -23,8 +23,8 @@ func (t *Transport) IdleConnKeysForTesting() (keys []string) {
}
func (t *Transport) IdleConnCountForTesting(cacheKey string) int {
- t.lk.Lock()
- defer t.lk.Unlock()
+ t.idleLk.Lock()
+ defer t.idleLk.Unlock()
if t.idleConn == nil {
return 0
}
diff --git a/libgo/go/net/http/fs.go b/libgo/go/net/http/fs.go
index f35dd32c3..208d6cabb 100644
--- a/libgo/go/net/http/fs.go
+++ b/libgo/go/net/http/fs.go
@@ -11,6 +11,8 @@ import (
"fmt"
"io"
"mime"
+ "mime/multipart"
+ "net/textproto"
"os"
"path"
"path/filepath"
@@ -26,7 +28,8 @@ import (
type Dir string
func (d Dir) Open(name string) (File, error) {
- if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 {
+ if filepath.Separator != '/' && strings.IndexRune(name, filepath.Separator) >= 0 ||
+ strings.Contains(name, "\x00") {
return nil, errors.New("http: invalid character in file path")
}
dir := string(d)
@@ -123,8 +126,9 @@ func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time,
code := StatusOK
// If Content-Type isn't set, use the file's extension to find it.
- if w.Header().Get("Content-Type") == "" {
- ctype := mime.TypeByExtension(filepath.Ext(name))
+ ctype := w.Header().Get("Content-Type")
+ if ctype == "" {
+ ctype = mime.TypeByExtension(filepath.Ext(name))
if ctype == "" {
// read a chunk to decide between utf-8 text and binary
var buf [1024]byte
@@ -141,18 +145,34 @@ func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time,
}
// handle Content-Range header.
- // TODO(adg): handle multiple ranges
sendSize := size
+ var sendContent io.Reader = content
if size >= 0 {
ranges, err := parseRange(r.Header.Get("Range"), size)
- if err == nil && len(ranges) > 1 {
- err = errors.New("multiple ranges not supported")
- }
if err != nil {
Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
return
}
- if len(ranges) == 1 {
+ if sumRangesSize(ranges) >= size {
+ // The total number of bytes in all the ranges
+ // is larger than the size of the file by
+ // itself, so this is probably an attack, or a
+ // dumb client. Ignore the range request.
+ ranges = nil
+ }
+ switch {
+ case len(ranges) == 1:
+ // RFC 2616, Section 14.16:
+ // "When an HTTP message includes the content of a single
+ // range (for example, a response to a request for a
+ // single range, or to a request for a set of ranges
+ // that overlap without any holes), this content is
+ // transmitted with a Content-Range header, and a
+ // Content-Length header showing the number of bytes
+ // actually transferred.
+ // ...
+ // A response to a request for a single range MUST NOT
+ // be sent using the multipart/byteranges media type."
ra := ranges[0]
if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil {
Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
@@ -160,7 +180,41 @@ func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time,
}
sendSize = ra.length
code = StatusPartialContent
- w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", ra.start, ra.start+ra.length-1, size))
+ w.Header().Set("Content-Range", ra.contentRange(size))
+ case len(ranges) > 1:
+ for _, ra := range ranges {
+ if ra.start > size {
+ Error(w, err.Error(), StatusRequestedRangeNotSatisfiable)
+ return
+ }
+ }
+ sendSize = rangesMIMESize(ranges, ctype, size)
+ code = StatusPartialContent
+
+ pr, pw := io.Pipe()
+ mw := multipart.NewWriter(pw)
+ w.Header().Set("Content-Type", "multipart/byteranges; boundary="+mw.Boundary())
+ sendContent = pr
+ defer pr.Close() // cause writing goroutine to fail and exit if CopyN doesn't finish.
+ go func() {
+ for _, ra := range ranges {
+ part, err := mw.CreatePart(ra.mimeHeader(ctype, size))
+ if err != nil {
+ pw.CloseWithError(err)
+ return
+ }
+ if _, err := content.Seek(ra.start, os.SEEK_SET); err != nil {
+ pw.CloseWithError(err)
+ return
+ }
+ if _, err := io.CopyN(part, content, ra.length); err != nil {
+ pw.CloseWithError(err)
+ return
+ }
+ }
+ mw.Close()
+ pw.Close()
+ }()
}
w.Header().Set("Accept-Ranges", "bytes")
@@ -172,11 +226,7 @@ func serveContent(w ResponseWriter, r *Request, name string, modtime time.Time,
w.WriteHeader(code)
if r.Method != "HEAD" {
- if sendSize == -1 {
- io.Copy(w, content)
- } else {
- io.CopyN(w, content, sendSize)
- }
+ io.CopyN(w, sendContent, sendSize)
}
}
@@ -243,9 +293,6 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
// use contents of index.html for directory, if present
if d.IsDir() {
- if checkLastModified(w, r, d.ModTime()) {
- return
- }
index := name + indexPage
ff, err := fs.Open(index)
if err == nil {
@@ -259,11 +306,16 @@ func serveFile(w ResponseWriter, r *Request, fs FileSystem, name string, redirec
}
}
+ // Still a directory? (we didn't find an index.html file)
if d.IsDir() {
+ if checkLastModified(w, r, d.ModTime()) {
+ return
+ }
dirList(w, f)
return
}
+ // serverContent will check modification time
serveContent(w, r, d.Name(), d.ModTime(), d.Size(), f)
}
@@ -312,6 +364,17 @@ type httpRange struct {
start, length int64
}
+func (r httpRange) contentRange(size int64) string {
+ return fmt.Sprintf("bytes %d-%d/%d", r.start, r.start+r.length-1, size)
+}
+
+func (r httpRange) mimeHeader(contentType string, size int64) textproto.MIMEHeader {
+ return textproto.MIMEHeader{
+ "Content-Range": {r.contentRange(size)},
+ "Content-Type": {contentType},
+ }
+}
+
// parseRange parses a Range header string as per RFC 2616.
func parseRange(s string, size int64) ([]httpRange, error) {
if s == "" {
@@ -323,11 +386,15 @@ func parseRange(s string, size int64) ([]httpRange, error) {
}
var ranges []httpRange
for _, ra := range strings.Split(s[len(b):], ",") {
+ ra = strings.TrimSpace(ra)
+ if ra == "" {
+ continue
+ }
i := strings.Index(ra, "-")
if i < 0 {
return nil, errors.New("invalid range")
}
- start, end := ra[:i], ra[i+1:]
+ start, end := strings.TrimSpace(ra[:i]), strings.TrimSpace(ra[i+1:])
var r httpRange
if start == "" {
// If no start is specified, end specifies the
@@ -365,3 +432,32 @@ func parseRange(s string, size int64) ([]httpRange, error) {
}
return ranges, nil
}
+
+// countingWriter counts how many bytes have been written to it.
+type countingWriter int64
+
+func (w *countingWriter) Write(p []byte) (n int, err error) {
+ *w += countingWriter(len(p))
+ return len(p), nil
+}
+
+// rangesMIMESize returns the nunber of bytes it takes to encode the
+// provided ranges as a multipart response.
+func rangesMIMESize(ranges []httpRange, contentType string, contentSize int64) (encSize int64) {
+ var w countingWriter
+ mw := multipart.NewWriter(&w)
+ for _, ra := range ranges {
+ mw.CreatePart(ra.mimeHeader(contentType, contentSize))
+ encSize += ra.length
+ }
+ mw.Close()
+ encSize += int64(w)
+ return
+}
+
+func sumRangesSize(ranges []httpRange) (size int64) {
+ for _, ra := range ranges {
+ size += ra.length
+ }
+ return
+}
diff --git a/libgo/go/net/http/fs_test.go b/libgo/go/net/http/fs_test.go
index ffba6a7bc..17329fbd5 100644
--- a/libgo/go/net/http/fs_test.go
+++ b/libgo/go/net/http/fs_test.go
@@ -10,12 +10,15 @@ import (
"fmt"
"io"
"io/ioutil"
+ "mime"
+ "mime/multipart"
"net"
. "net/http"
"net/http/httptest"
"net/url"
"os"
"os/exec"
+ "path"
"path/filepath"
"regexp"
"runtime"
@@ -25,21 +28,29 @@ import (
)
const (
- testFile = "testdata/file"
- testFileLength = 11
+ testFile = "testdata/file"
+ testFileLen = 11
)
+type wantRange struct {
+ start, end int64 // range [start,end)
+}
+
var ServeFileRangeTests = []struct {
- start, end int
- r string
- code int
+ r string
+ code int
+ ranges []wantRange
}{
- {0, testFileLength, "", StatusOK},
- {0, 5, "0-4", StatusPartialContent},
- {2, testFileLength, "2-", StatusPartialContent},
- {testFileLength - 5, testFileLength, "-5", StatusPartialContent},
- {3, 8, "3-7", StatusPartialContent},
- {0, 0, "20-", StatusRequestedRangeNotSatisfiable},
+ {r: "", code: StatusOK},
+ {r: "bytes=0-4", code: StatusPartialContent, ranges: []wantRange{{0, 5}}},
+ {r: "bytes=2-", code: StatusPartialContent, ranges: []wantRange{{2, testFileLen}}},
+ {r: "bytes=-5", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 5, testFileLen}}},
+ {r: "bytes=3-7", code: StatusPartialContent, ranges: []wantRange{{3, 8}}},
+ {r: "bytes=20-", code: StatusRequestedRangeNotSatisfiable},
+ {r: "bytes=0-0,-2", code: StatusPartialContent, ranges: []wantRange{{0, 1}, {testFileLen - 2, testFileLen}}},
+ {r: "bytes=0-1,5-8", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, 9}}},
+ {r: "bytes=0-1,5-", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, testFileLen}}},
+ {r: "bytes=0-,1-,2-,3-,4-", code: StatusOK}, // ignore wasteful range request
}
func TestServeFile(t *testing.T) {
@@ -65,33 +76,81 @@ func TestServeFile(t *testing.T) {
// straight GET
_, body := getBody(t, "straight get", req)
- if !equal(body, file) {
+ if !bytes.Equal(body, file) {
t.Fatalf("body mismatch: got %q, want %q", body, file)
}
// Range tests
- for i, rt := range ServeFileRangeTests {
- req.Header.Set("Range", "bytes="+rt.r)
- if rt.r == "" {
- req.Header["Range"] = nil
+ for _, rt := range ServeFileRangeTests {
+ if rt.r != "" {
+ req.Header.Set("Range", rt.r)
}
- r, body := getBody(t, fmt.Sprintf("test %d", i), req)
- if r.StatusCode != rt.code {
- t.Errorf("range=%q: StatusCode=%d, want %d", rt.r, r.StatusCode, rt.code)
+ resp, body := getBody(t, fmt.Sprintf("range test %q", rt.r), req)
+ if resp.StatusCode != rt.code {
+ t.Errorf("range=%q: StatusCode=%d, want %d", rt.r, resp.StatusCode, rt.code)
}
if rt.code == StatusRequestedRangeNotSatisfiable {
continue
}
- h := fmt.Sprintf("bytes %d-%d/%d", rt.start, rt.end-1, testFileLength)
- if rt.r == "" {
- h = ""
+ wantContentRange := ""
+ if len(rt.ranges) == 1 {
+ rng := rt.ranges[0]
+ wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen)
+ }
+ cr := resp.Header.Get("Content-Range")
+ if cr != wantContentRange {
+ t.Errorf("range=%q: Content-Range = %q, want %q", rt.r, cr, wantContentRange)
}
- cr := r.Header.Get("Content-Range")
- if cr != h {
- t.Errorf("header mismatch: range=%q: got %q, want %q", rt.r, cr, h)
+ ct := resp.Header.Get("Content-Type")
+ if len(rt.ranges) == 1 {
+ rng := rt.ranges[0]
+ wantBody := file[rng.start:rng.end]
+ if !bytes.Equal(body, wantBody) {
+ t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody)
+ }
+ if strings.HasPrefix(ct, "multipart/byteranges") {
+ t.Errorf("range=%q content-type = %q; unexpected multipart/byteranges", rt.r)
+ }
}
- if !equal(body, file[rt.start:rt.end]) {
- t.Errorf("body mismatch: range=%q: got %q, want %q", rt.r, body, file[rt.start:rt.end])
+ if len(rt.ranges) > 1 {
+ typ, params, err := mime.ParseMediaType(ct)
+ if err != nil {
+ t.Errorf("range=%q content-type = %q; %v", rt.r, ct, err)
+ continue
+ }
+ if typ != "multipart/byteranges" {
+ t.Errorf("range=%q content-type = %q; want multipart/byteranges", rt.r)
+ continue
+ }
+ if params["boundary"] == "" {
+ t.Errorf("range=%q content-type = %q; lacks boundary", rt.r, ct)
+ }
+ if g, w := resp.ContentLength, int64(len(body)); g != w {
+ t.Errorf("range=%q Content-Length = %d; want %d", rt.r, g, w)
+ }
+ mr := multipart.NewReader(bytes.NewReader(body), params["boundary"])
+ for ri, rng := range rt.ranges {
+ part, err := mr.NextPart()
+ if err != nil {
+ t.Fatalf("range=%q, reading part index %d: %v", rt.r, ri, err)
+ }
+ body, err := ioutil.ReadAll(part)
+ if err != nil {
+ t.Fatalf("range=%q, reading part index %d body: %v", rt.r, ri, err)
+ }
+ wantContentRange = fmt.Sprintf("bytes %d-%d/%d", rng.start, rng.end-1, testFileLen)
+ wantBody := file[rng.start:rng.end]
+ if !bytes.Equal(body, wantBody) {
+ t.Errorf("range=%q: body = %q, want %q", rt.r, body, wantBody)
+ }
+ if g, w := part.Header.Get("Content-Range"), wantContentRange; g != w {
+ t.Errorf("range=%q: part Content-Range = %q; want %q", rt.r, g, w)
+ }
+ }
+ _, err = mr.NextPart()
+ if err != io.EOF {
+ t.Errorf("range=%q; expected final error io.EOF; got %v", err)
+ }
}
}
}
@@ -276,6 +335,11 @@ func TestServeFileMimeType(t *testing.T) {
}
func TestServeFileFromCWD(t *testing.T) {
+ if runtime.GOOS == "windows" {
+ // TODO(brainman): find out why this test is broken
+ t.Logf("Temporarily skipping test on Windows; see http://golang.org/issue/3917")
+ return
+ }
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
ServeFile(w, r, "fs_test.go")
}))
@@ -325,6 +389,139 @@ func TestServeIndexHtml(t *testing.T) {
}
}
+func TestFileServerZeroByte(t *testing.T) {
+ ts := httptest.NewServer(FileServer(Dir(".")))
+ defer ts.Close()
+
+ res, err := Get(ts.URL + "/..\x00")
+ if err != nil {
+ t.Fatal(err)
+ }
+ b, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ t.Fatal("reading Body:", err)
+ }
+ if res.StatusCode == 200 {
+ t.Errorf("got status 200; want an error. Body is:\n%s", string(b))
+ }
+}
+
+type fakeFileInfo struct {
+ dir bool
+ basename string
+ modtime time.Time
+ ents []*fakeFileInfo
+ contents string
+}
+
+func (f *fakeFileInfo) Name() string { return f.basename }
+func (f *fakeFileInfo) Sys() interface{} { return nil }
+func (f *fakeFileInfo) ModTime() time.Time { return f.modtime }
+func (f *fakeFileInfo) IsDir() bool { return f.dir }
+func (f *fakeFileInfo) Size() int64 { return int64(len(f.contents)) }
+func (f *fakeFileInfo) Mode() os.FileMode {
+ if f.dir {
+ return 0755 | os.ModeDir
+ }
+ return 0644
+}
+
+type fakeFile struct {
+ io.ReadSeeker
+ fi *fakeFileInfo
+ path string // as opened
+}
+
+func (f *fakeFile) Close() error { return nil }
+func (f *fakeFile) Stat() (os.FileInfo, error) { return f.fi, nil }
+func (f *fakeFile) Readdir(count int) ([]os.FileInfo, error) {
+ if !f.fi.dir {
+ return nil, os.ErrInvalid
+ }
+ var fis []os.FileInfo
+ for _, fi := range f.fi.ents {
+ fis = append(fis, fi)
+ }
+ return fis, nil
+}
+
+type fakeFS map[string]*fakeFileInfo
+
+func (fs fakeFS) Open(name string) (File, error) {
+ name = path.Clean(name)
+ f, ok := fs[name]
+ if !ok {
+ println("fake filesystem didn't find file", name)
+ return nil, os.ErrNotExist
+ }
+ return &fakeFile{ReadSeeker: strings.NewReader(f.contents), fi: f, path: name}, nil
+}
+
+func TestDirectoryIfNotModified(t *testing.T) {
+ const indexContents = "I am a fake index.html file"
+ fileMod := time.Unix(1000000000, 0).UTC()
+ fileModStr := fileMod.Format(TimeFormat)
+ dirMod := time.Unix(123, 0).UTC()
+ indexFile := &fakeFileInfo{
+ basename: "index.html",
+ modtime: fileMod,
+ contents: indexContents,
+ }
+ fs := fakeFS{
+ "/": &fakeFileInfo{
+ dir: true,
+ modtime: dirMod,
+ ents: []*fakeFileInfo{indexFile},
+ },
+ "/index.html": indexFile,
+ }
+
+ ts := httptest.NewServer(FileServer(fs))
+ defer ts.Close()
+
+ res, err := Get(ts.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ b, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if string(b) != indexContents {
+ t.Fatalf("Got body %q; want %q", b, indexContents)
+ }
+ res.Body.Close()
+
+ lastMod := res.Header.Get("Last-Modified")
+ if lastMod != fileModStr {
+ t.Fatalf("initial Last-Modified = %q; want %q", lastMod, fileModStr)
+ }
+
+ req, _ := NewRequest("GET", ts.URL, nil)
+ req.Header.Set("If-Modified-Since", lastMod)
+
+ res, err = DefaultClient.Do(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if res.StatusCode != 304 {
+ t.Fatalf("Code after If-Modified-Since request = %v; want 304", res.StatusCode)
+ }
+ res.Body.Close()
+
+ // Advance the index.html file's modtime, but not the directory's.
+ indexFile.modtime = indexFile.modtime.Add(1 * time.Hour)
+
+ res, err = DefaultClient.Do(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if res.StatusCode != 200 {
+ t.Fatalf("Code after second If-Modified-Since request = %v; want 200; res is %#v", res.StatusCode, res)
+ }
+ res.Body.Close()
+}
+
func TestServeContent(t *testing.T) {
type req struct {
name string
@@ -464,15 +661,3 @@ func TestLinuxSendfileChild(*testing.T) {
panic(err)
}
}
-
-func equal(a, b []byte) bool {
- if len(a) != len(b) {
- return false
- }
- for i := range a {
- if a[i] != b[i] {
- return false
- }
- }
- return true
-}
diff --git a/libgo/go/net/http/header.go b/libgo/go/net/http/header.go
index b107c312d..6be94f98e 100644
--- a/libgo/go/net/http/header.go
+++ b/libgo/go/net/http/header.go
@@ -76,3 +76,43 @@ func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error {
// the rest are converted to lowercase. For example, the
// canonical key for "accept-encoding" is "Accept-Encoding".
func CanonicalHeaderKey(s string) string { return textproto.CanonicalMIMEHeaderKey(s) }
+
+// hasToken returns whether token appears with v, ASCII
+// case-insensitive, with space or comma boundaries.
+// token must be all lowercase.
+// v may contain mixed cased.
+func hasToken(v, token string) bool {
+ if len(token) > len(v) || token == "" {
+ return false
+ }
+ if v == token {
+ return true
+ }
+ for sp := 0; sp <= len(v)-len(token); sp++ {
+ // Check that first character is good.
+ // The token is ASCII, so checking only a single byte
+ // is sufficient. We skip this potential starting
+ // position if both the first byte and its potential
+ // ASCII uppercase equivalent (b|0x20) don't match.
+ // False positives ('^' => '~') are caught by EqualFold.
+ if b := v[sp]; b != token[0] && b|0x20 != token[0] {
+ continue
+ }
+ // Check that start pos is on a valid token boundary.
+ if sp > 0 && !isTokenBoundary(v[sp-1]) {
+ continue
+ }
+ // Check that end pos is on a valid token boundary.
+ if endPos := sp + len(token); endPos != len(v) && !isTokenBoundary(v[endPos]) {
+ continue
+ }
+ if strings.EqualFold(v[sp:sp+len(token)], token) {
+ return true
+ }
+ }
+ return false
+}
+
+func isTokenBoundary(b byte) bool {
+ return b == ' ' || b == ',' || b == '\t'
+}
diff --git a/libgo/go/net/http/httptest/server.go b/libgo/go/net/http/httptest/server.go
index 57cf0c941..165600e52 100644
--- a/libgo/go/net/http/httptest/server.go
+++ b/libgo/go/net/http/httptest/server.go
@@ -184,15 +184,15 @@ func (h *waitGroupHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// "127.0.0.1" and "[::1]", expiring at the last second of 2049 (the end
// of ASN.1 time).
var localhostCert = []byte(`-----BEGIN CERTIFICATE-----
-MIIBOTCB5qADAgECAgEAMAsGCSqGSIb3DQEBBTAAMB4XDTcwMDEwMTAwMDAwMFoX
+MIIBTTCB+qADAgECAgEAMAsGCSqGSIb3DQEBBTAAMB4XDTcwMDEwMTAwMDAwMFoX
DTQ5MTIzMTIzNTk1OVowADBaMAsGCSqGSIb3DQEBAQNLADBIAkEAsuA5mAFMj6Q7
qoBzcvKzIq4kzuT5epSp2AkcQfyBHm7K13Ws7u+0b5Vb9gqTf5cAiIKcrtrXVqkL
-8i1UQF6AzwIDAQABo08wTTAOBgNVHQ8BAf8EBAMCACQwDQYDVR0OBAYEBAECAwQw
-DwYDVR0jBAgwBoAEAQIDBDAbBgNVHREEFDASggkxMjcuMC4wLjGCBVs6OjFdMAsG
-CSqGSIb3DQEBBQNBAJH30zjLWRztrWpOCgJL8RQWLaKzhK79pVhAx6q/3NrF16C7
-+l1BRZstTwIGdoGId8BRpErK1TXkniFb95ZMynM=
------END CERTIFICATE-----
-`)
+8i1UQF6AzwIDAQABo2MwYTAOBgNVHQ8BAf8EBAMCACQwEgYDVR0TAQH/BAgwBgEB
+/wIBATANBgNVHQ4EBgQEAQIDBDAPBgNVHSMECDAGgAQBAgMEMBsGA1UdEQQUMBKC
+CTEyNy4wLjAuMYIFWzo6MV0wCwYJKoZIhvcNAQEFA0EAj1Jsn/h2KHy7dgqutZNB
+nCGlNN+8vw263Bax9MklR85Ti6a0VWSvp/fDQZUADvmFTDkcXeA24pqmdUxeQDWw
+Pg==
+-----END CERTIFICATE-----`)
// localhostKey is the private key for localhostCert.
var localhostKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
diff --git a/libgo/go/net/http/httputil/dump.go b/libgo/go/net/http/httputil/dump.go
index 892ef4ede..0fb2eeb8c 100644
--- a/libgo/go/net/http/httputil/dump.go
+++ b/libgo/go/net/http/httputil/dump.go
@@ -89,7 +89,7 @@ func DumpRequestOut(req *http.Request, body bool) ([]byte, error) {
t := &http.Transport{
Dial: func(net, addr string) (net.Conn, error) {
- return &dumpConn{io.MultiWriter(pw, &buf), dr}, nil
+ return &dumpConn{io.MultiWriter(&buf, pw), dr}, nil
},
}
diff --git a/libgo/go/net/http/pprof/pprof.go b/libgo/go/net/http/pprof/pprof.go
index 06fcde144..7a9f465c4 100644
--- a/libgo/go/net/http/pprof/pprof.go
+++ b/libgo/go/net/http/pprof/pprof.go
@@ -14,6 +14,14 @@
// To use pprof, link this package into your program:
// import _ "net/http/pprof"
//
+// If your application is not already running an http server, you
+// need to start one. Add "net/http" and "log" to your imports and
+// the following code to your main function:
+//
+// go func() {
+// log.Println(http.ListenAndServe("localhost:6060", nil))
+// }()
+//
// Then use the pprof tool to look at the heap profile:
//
// go tool pprof http://localhost:6060/debug/pprof/heap
diff --git a/libgo/go/net/http/range_test.go b/libgo/go/net/http/range_test.go
index 5274a81fa..ef911af7b 100644
--- a/libgo/go/net/http/range_test.go
+++ b/libgo/go/net/http/range_test.go
@@ -14,15 +14,34 @@ var ParseRangeTests = []struct {
r []httpRange
}{
{"", 0, nil},
+ {"", 1000, nil},
{"foo", 0, nil},
{"bytes=", 0, nil},
+ {"bytes=7", 10, nil},
+ {"bytes= 7 ", 10, nil},
+ {"bytes=1-", 0, nil},
{"bytes=5-4", 10, nil},
{"bytes=0-2,5-4", 10, nil},
+ {"bytes=2-5,4-3", 10, nil},
+ {"bytes=--5,4--3", 10, nil},
+ {"bytes=A-", 10, nil},
+ {"bytes=A- ", 10, nil},
+ {"bytes=A-Z", 10, nil},
+ {"bytes= -Z", 10, nil},
+ {"bytes=5-Z", 10, nil},
+ {"bytes=Ran-dom, garbage", 10, nil},
+ {"bytes=0x01-0x02", 10, nil},
+ {"bytes= ", 10, nil},
+ {"bytes= , , , ", 10, nil},
+
{"bytes=0-9", 10, []httpRange{{0, 10}}},
{"bytes=0-", 10, []httpRange{{0, 10}}},
{"bytes=5-", 10, []httpRange{{5, 5}}},
{"bytes=0-20", 10, []httpRange{{0, 10}}},
{"bytes=15-,0-5", 10, nil},
+ {"bytes=1-2,5-", 10, []httpRange{{1, 2}, {5, 5}}},
+ {"bytes=-2 , 7-", 11, []httpRange{{9, 2}, {7, 4}}},
+ {"bytes=0-0 ,2-2, 7-", 11, []httpRange{{0, 1}, {2, 1}, {7, 4}}},
{"bytes=-5", 10, []httpRange{{5, 5}}},
{"bytes=-15", 10, []httpRange{{0, 10}}},
{"bytes=0-499", 10000, []httpRange{{0, 500}}},
@@ -32,6 +51,9 @@ var ParseRangeTests = []struct {
{"bytes=0-0,-1", 10000, []httpRange{{0, 1}, {9999, 1}}},
{"bytes=500-600,601-999", 10000, []httpRange{{500, 101}, {601, 399}}},
{"bytes=500-700,601-999", 10000, []httpRange{{500, 201}, {601, 399}}},
+
+ // Match Apache laxity:
+ {"bytes= 1 -2 , 4- 5, 7 - 8 , ,,", 11, []httpRange{{1, 2}, {4, 2}, {7, 2}}},
}
func TestParseRange(t *testing.T) {
diff --git a/libgo/go/net/http/serve_test.go b/libgo/go/net/http/serve_test.go
index b6a6b4c77..c9d73932b 100644
--- a/libgo/go/net/http/serve_test.go
+++ b/libgo/go/net/http/serve_test.go
@@ -386,17 +386,18 @@ func testTcpConnectionCloses(t *testing.T, req string, h Handler) {
}
r := bufio.NewReader(conn)
- _, err = ReadResponse(r, &Request{Method: "GET"})
+ res, err := ReadResponse(r, &Request{Method: "GET"})
if err != nil {
t.Fatal("ReadResponse error:", err)
}
- success := make(chan bool)
+ didReadAll := make(chan bool, 1)
go func() {
select {
case <-time.After(5 * time.Second):
- t.Fatal("body not closed after 5s")
- case <-success:
+ t.Error("body not closed after 5s")
+ return
+ case <-didReadAll:
}
}()
@@ -404,8 +405,11 @@ func testTcpConnectionCloses(t *testing.T, req string, h Handler) {
if err != nil {
t.Fatal("read error:", err)
}
+ didReadAll <- true
- success <- true
+ if !res.Close {
+ t.Errorf("Response.Close = false; want true")
+ }
}
// TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive.
@@ -1108,6 +1112,38 @@ func TestServerBufferedChunking(t *testing.T) {
}
}
+// TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1
+// request (both keep-alive), when a Handler never writes any
+// response, the net/http package adds a "Content-Length: 0" response
+// header.
+func TestContentLengthZero(t *testing.T) {
+ ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {}))
+ defer ts.Close()
+
+ for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} {
+ conn, err := net.Dial("tcp", ts.Listener.Addr().String())
+ if err != nil {
+ t.Fatalf("error dialing: %v", err)
+ }
+ _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version)
+ if err != nil {
+ t.Fatalf("error writing: %v", err)
+ }
+ req, _ := NewRequest("GET", "/", nil)
+ res, err := ReadResponse(bufio.NewReader(conn), req)
+ if err != nil {
+ t.Fatalf("error reading response: %v", err)
+ }
+ if te := res.TransferEncoding; len(te) > 0 {
+ t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te)
+ }
+ if cl := res.ContentLength; cl != 0 {
+ t.Errorf("For version %q, Content-Length = %v; want 0", version, cl)
+ }
+ conn.Close()
+ }
+}
+
// goTimeout runs f, failing t if f takes more than ns to complete.
func goTimeout(t *testing.T, d time.Duration, f func()) {
ch := make(chan bool, 2)
diff --git a/libgo/go/net/http/server.go b/libgo/go/net/http/server.go
index 0572b4ae3..b74b76298 100644
--- a/libgo/go/net/http/server.go
+++ b/libgo/go/net/http/server.go
@@ -390,6 +390,11 @@ func (w *response) WriteHeader(code int) {
if !w.req.ProtoAtLeast(1, 0) {
return
}
+
+ if w.closeAfterReply && !hasToken(w.header.Get("Connection"), "close") {
+ w.header.Set("Connection", "close")
+ }
+
proto := "HTTP/1.0"
if w.req.ProtoAtLeast(1, 1) {
proto = "HTTP/1.1"
@@ -508,8 +513,16 @@ func (w *response) Write(data []byte) (n int, err error) {
}
func (w *response) finishRequest() {
- // If this was an HTTP/1.0 request with keep-alive and we sent a Content-Length
- // back, we can make this a keep-alive response ...
+ // If the handler never wrote any bytes and never sent a Content-Length
+ // response header, set the length explicitly to zero. This helps
+ // HTTP/1.0 clients keep their "keep-alive" connections alive, and for
+ // HTTP/1.1 clients is just as good as the alternative: sending a
+ // chunked response and immediately sending the zero-length EOF chunk.
+ if w.written == 0 && w.header.Get("Content-Length") == "" {
+ w.header.Set("Content-Length", "0")
+ }
+ // If this was an HTTP/1.0 request with keep-alive and we sent a
+ // Content-Length back, we can make this a keep-alive response ...
if w.req.wantsHttp10KeepAlive() {
sentLength := w.header.Get("Content-Length") != ""
if sentLength && w.header.Get("Connection") == "keep-alive" {
@@ -817,13 +830,13 @@ func RedirectHandler(url string, code int) Handler {
// patterns and calls the handler for the pattern that
// most closely matches the URL.
//
-// Patterns named fixed, rooted paths, like "/favicon.ico",
+// Patterns name fixed, rooted paths, like "/favicon.ico",
// or rooted subtrees, like "/images/" (note the trailing slash).
// Longer patterns take precedence over shorter ones, so that
// if there are handlers registered for both "/images/"
// and "/images/thumbnails/", the latter handler will be
// called for paths beginning "/images/thumbnails/" and the
-// former will receiver requests for any other paths in the
+// former will receive requests for any other paths in the
// "/images/" subtree.
//
// Patterns may optionally begin with a host name, restricting matches to
@@ -917,11 +930,13 @@ func (mux *ServeMux) handler(r *Request) Handler {
// ServeHTTP dispatches the request to the handler whose
// pattern most closely matches the request URL.
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
- // Clean path to canonical form and redirect.
- if p := cleanPath(r.URL.Path); p != r.URL.Path {
- w.Header().Set("Location", p)
- w.WriteHeader(StatusMovedPermanently)
- return
+ if r.Method != "CONNECT" {
+ // Clean path to canonical form and redirect.
+ if p := cleanPath(r.URL.Path); p != r.URL.Path {
+ w.Header().Set("Location", p)
+ w.WriteHeader(StatusMovedPermanently)
+ return
+ }
}
mux.handler(r).ServeHTTP(w, r)
}
diff --git a/libgo/go/net/http/transport.go b/libgo/go/net/http/transport.go
index 6efe191eb..6131d0d1e 100644
--- a/libgo/go/net/http/transport.go
+++ b/libgo/go/net/http/transport.go
@@ -41,8 +41,9 @@ const DefaultMaxIdleConnsPerHost = 2
// https, and http proxies (for either http or https with CONNECT).
// Transport can also cache connections for future re-use.
type Transport struct {
- lk sync.Mutex
+ idleLk sync.Mutex
idleConn map[string][]*persistConn
+ altLk sync.RWMutex
altProto map[string]RoundTripper // nil or map of URI scheme => RoundTripper
// TODO: tunable on global max cached connections
@@ -131,12 +132,12 @@ func (t *Transport) RoundTrip(req *Request) (resp *Response, err error) {
return nil, errors.New("http: nil Request.Header")
}
if req.URL.Scheme != "http" && req.URL.Scheme != "https" {
- t.lk.Lock()
+ t.altLk.RLock()
var rt RoundTripper
if t.altProto != nil {
rt = t.altProto[req.URL.Scheme]
}
- t.lk.Unlock()
+ t.altLk.RUnlock()
if rt == nil {
return nil, &badStringError{"unsupported protocol scheme", req.URL.Scheme}
}
@@ -170,8 +171,8 @@ func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
if scheme == "http" || scheme == "https" {
panic("protocol " + scheme + " already registered")
}
- t.lk.Lock()
- defer t.lk.Unlock()
+ t.altLk.Lock()
+ defer t.altLk.Unlock()
if t.altProto == nil {
t.altProto = make(map[string]RoundTripper)
}
@@ -186,17 +187,18 @@ func (t *Transport) RegisterProtocol(scheme string, rt RoundTripper) {
// a "keep-alive" state. It does not interrupt any connections currently
// in use.
func (t *Transport) CloseIdleConnections() {
- t.lk.Lock()
- defer t.lk.Unlock()
- if t.idleConn == nil {
+ t.idleLk.Lock()
+ m := t.idleConn
+ t.idleConn = nil
+ t.idleLk.Unlock()
+ if m == nil {
return
}
- for _, conns := range t.idleConn {
+ for _, conns := range m {
for _, pconn := range conns {
pconn.close()
}
}
- t.idleConn = make(map[string][]*persistConn)
}
//
@@ -242,8 +244,6 @@ func (cm *connectMethod) proxyAuth() string {
// If pconn is no longer needed or not in a good state, putIdleConn
// returns false.
func (t *Transport) putIdleConn(pconn *persistConn) bool {
- t.lk.Lock()
- defer t.lk.Unlock()
if t.DisableKeepAlives || t.MaxIdleConnsPerHost < 0 {
pconn.close()
return false
@@ -256,21 +256,27 @@ func (t *Transport) putIdleConn(pconn *persistConn) bool {
if max == 0 {
max = DefaultMaxIdleConnsPerHost
}
+ t.idleLk.Lock()
+ if t.idleConn == nil {
+ t.idleConn = make(map[string][]*persistConn)
+ }
if len(t.idleConn[key]) >= max {
+ t.idleLk.Unlock()
pconn.close()
return false
}
t.idleConn[key] = append(t.idleConn[key], pconn)
+ t.idleLk.Unlock()
return true
}
func (t *Transport) getIdleConn(cm *connectMethod) (pconn *persistConn) {
- t.lk.Lock()
- defer t.lk.Unlock()
+ key := cm.String()
+ t.idleLk.Lock()
+ defer t.idleLk.Unlock()
if t.idleConn == nil {
- t.idleConn = make(map[string][]*persistConn)
+ return nil
}
- key := cm.String()
for {
pconns, ok := t.idleConn[key]
if !ok {
@@ -365,7 +371,18 @@ func (t *Transport) getConn(cm *connectMethod) (*persistConn, error) {
if cm.targetScheme == "https" {
// Initiate TLS and check remote host name against certificate.
- conn = tls.Client(conn, t.TLSClientConfig)
+ cfg := t.TLSClientConfig
+ if cfg == nil || cfg.ServerName == "" {
+ host, _, _ := net.SplitHostPort(cm.addr())
+ if cfg == nil {
+ cfg = &tls.Config{ServerName: host}
+ } else {
+ clone := *cfg // shallow clone
+ clone.ServerName = host
+ cfg = &clone
+ }
+ }
+ conn = tls.Client(conn, cfg)
if err = conn.(*tls.Conn).Handshake(); err != nil {
return nil, err
}
@@ -484,6 +501,7 @@ type persistConn struct {
t *Transport
cacheKey string // its connectMethod.String()
conn net.Conn
+ closed bool // whether conn has been closed
br *bufio.Reader // from conn
bw *bufio.Writer // to conn
reqch chan requestAndChan // written by roundTrip(); read by readLoop()
@@ -501,8 +519,9 @@ type persistConn struct {
func (pc *persistConn) isBroken() bool {
pc.lk.Lock()
- defer pc.lk.Unlock()
- return pc.broken
+ b := pc.broken
+ pc.lk.Unlock()
+ return b
}
var remoteSideClosedFunc func(error) bool // or nil to use default
@@ -571,29 +590,32 @@ func (pc *persistConn) readLoop() {
hasBody := resp != nil && resp.ContentLength != 0
var waitForBodyRead chan bool
- if alive {
- if hasBody {
- lastbody = resp.Body
- waitForBodyRead = make(chan bool)
- resp.Body.(*bodyEOFSignal).fn = func() {
- if !pc.t.putIdleConn(pc) {
- alive = false
- }
- waitForBodyRead <- true
- }
- } else {
- // When there's no response body, we immediately
- // reuse the TCP connection (putIdleConn), but
- // we need to prevent ClientConn.Read from
- // closing the Response.Body on the next
- // loop, otherwise it might close the body
- // before the client code has had a chance to
- // read it (even though it'll just be 0, EOF).
- lastbody = nil
-
- if !pc.t.putIdleConn(pc) {
+ if hasBody {
+ lastbody = resp.Body
+ waitForBodyRead = make(chan bool)
+ resp.Body.(*bodyEOFSignal).fn = func() {
+ if alive && !pc.t.putIdleConn(pc) {
alive = false
}
+ if !alive {
+ pc.close()
+ }
+ waitForBodyRead <- true
+ }
+ }
+
+ if alive && !hasBody {
+ // When there's no response body, we immediately
+ // reuse the TCP connection (putIdleConn), but
+ // we need to prevent ClientConn.Read from
+ // closing the Response.Body on the next
+ // loop, otherwise it might close the body
+ // before the client code has had a chance to
+ // read it (even though it'll just be 0, EOF).
+ lastbody = nil
+
+ if !pc.t.putIdleConn(pc) {
+ alive = false
}
}
@@ -604,6 +626,10 @@ func (pc *persistConn) readLoop() {
if waitForBodyRead != nil {
<-waitForBodyRead
}
+
+ if !alive {
+ pc.close()
+ }
}
}
@@ -669,7 +695,10 @@ func (pc *persistConn) close() {
func (pc *persistConn) closeLocked() {
pc.broken = true
- pc.conn.Close()
+ if !pc.closed {
+ pc.conn.Close()
+ pc.closed = true
+ }
pc.mutateHeaderFunc = nil
}
diff --git a/libgo/go/net/http/transport_test.go b/libgo/go/net/http/transport_test.go
index a9e401de5..e676bf6db 100644
--- a/libgo/go/net/http/transport_test.go
+++ b/libgo/go/net/http/transport_test.go
@@ -13,6 +13,7 @@ import (
"fmt"
"io"
"io/ioutil"
+ "net"
. "net/http"
"net/http/httptest"
"net/url"
@@ -20,6 +21,7 @@ import (
"runtime"
"strconv"
"strings"
+ "sync"
"testing"
"time"
)
@@ -35,6 +37,68 @@ var hostPortHandler = HandlerFunc(func(w ResponseWriter, r *Request) {
w.Write([]byte(r.RemoteAddr))
})
+// testCloseConn is a net.Conn tracked by a testConnSet.
+type testCloseConn struct {
+ net.Conn
+ set *testConnSet
+}
+
+func (c *testCloseConn) Close() error {
+ c.set.remove(c)
+ return c.Conn.Close()
+}
+
+// testConnSet tracks a set of TCP connections and whether they've
+// been closed.
+type testConnSet struct {
+ t *testing.T
+ closed map[net.Conn]bool
+ list []net.Conn // in order created
+ mutex sync.Mutex
+}
+
+func (tcs *testConnSet) insert(c net.Conn) {
+ tcs.mutex.Lock()
+ defer tcs.mutex.Unlock()
+ tcs.closed[c] = false
+ tcs.list = append(tcs.list, c)
+}
+
+func (tcs *testConnSet) remove(c net.Conn) {
+ tcs.mutex.Lock()
+ defer tcs.mutex.Unlock()
+ tcs.closed[c] = true
+}
+
+// some tests use this to manage raw tcp connections for later inspection
+func makeTestDial(t *testing.T) (*testConnSet, func(n, addr string) (net.Conn, error)) {
+ connSet := &testConnSet{
+ t: t,
+ closed: make(map[net.Conn]bool),
+ }
+ dial := func(n, addr string) (net.Conn, error) {
+ c, err := net.Dial(n, addr)
+ if err != nil {
+ return nil, err
+ }
+ tc := &testCloseConn{c, connSet}
+ connSet.insert(tc)
+ return tc, nil
+ }
+ return connSet, dial
+}
+
+func (tcs *testConnSet) check(t *testing.T) {
+ tcs.mutex.Lock()
+ defer tcs.mutex.Unlock()
+
+ for i, c := range tcs.list {
+ if !tcs.closed[c] {
+ t.Errorf("TCP connection #%d, %p (of %d total) was not closed", i+1, c, len(tcs.list))
+ }
+ }
+}
+
// Two subsequent requests and verify their response is the same.
// The response from the server is our own IP:port
func TestTransportKeepAlives(t *testing.T) {
@@ -72,8 +136,12 @@ func TestTransportConnectionCloseOnResponse(t *testing.T) {
ts := httptest.NewServer(hostPortHandler)
defer ts.Close()
+ connSet, testDial := makeTestDial(t)
+
for _, connectionClose := range []bool{false, true} {
- tr := &Transport{}
+ tr := &Transport{
+ Dial: testDial,
+ }
c := &Client{Transport: tr}
fetch := func(n int) string {
@@ -92,8 +160,8 @@ func TestTransportConnectionCloseOnResponse(t *testing.T) {
if err != nil {
t.Fatalf("error in connectionClose=%v, req #%d, Do: %v", connectionClose, n, err)
}
- body, err := ioutil.ReadAll(res.Body)
defer res.Body.Close()
+ body, err := ioutil.ReadAll(res.Body)
if err != nil {
t.Fatalf("error in connectionClose=%v, req #%d, ReadAll: %v", connectionClose, n, err)
}
@@ -107,15 +175,23 @@ func TestTransportConnectionCloseOnResponse(t *testing.T) {
t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
connectionClose, bodiesDiffer, body1, body2)
}
+
+ tr.CloseIdleConnections()
}
+
+ connSet.check(t)
}
func TestTransportConnectionCloseOnRequest(t *testing.T) {
ts := httptest.NewServer(hostPortHandler)
defer ts.Close()
+ connSet, testDial := makeTestDial(t)
+
for _, connectionClose := range []bool{false, true} {
- tr := &Transport{}
+ tr := &Transport{
+ Dial: testDial,
+ }
c := &Client{Transport: tr}
fetch := func(n int) string {
@@ -149,7 +225,11 @@ func TestTransportConnectionCloseOnRequest(t *testing.T) {
t.Errorf("error in connectionClose=%v. unexpected bodiesDiffer=%v; body1=%q; body2=%q",
connectionClose, bodiesDiffer, body1, body2)
}
+
+ tr.CloseIdleConnections()
}
+
+ connSet.check(t)
}
func TestTransportIdleCacheKeys(t *testing.T) {
@@ -724,6 +804,35 @@ func TestTransportIdleConnCrash(t *testing.T) {
<-didreq
}
+// Test that the transport doesn't close the TCP connection early,
+// before the response body has been read. This was a regression
+// which sadly lacked a triggering test. The large response body made
+// the old race easier to trigger.
+func TestIssue3644(t *testing.T) {
+ const numFoos = 5000
+ ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ w.Header().Set("Connection", "close")
+ for i := 0; i < numFoos; i++ {
+ w.Write([]byte("foo "))
+ }
+ }))
+ defer ts.Close()
+ tr := &Transport{}
+ c := &Client{Transport: tr}
+ res, err := c.Get(ts.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer res.Body.Close()
+ bs, err := ioutil.ReadAll(res.Body)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(bs) != numFoos*len("foo ") {
+ t.Errorf("unexpected response length")
+ }
+}
+
type fooProto struct{}
func (fooProto) RoundTrip(req *Request) (*Response, error) {
diff --git a/libgo/go/net/iprawsock.go b/libgo/go/net/iprawsock.go
index b23213ee1..ae21b3c3d 100644
--- a/libgo/go/net/iprawsock.go
+++ b/libgo/go/net/iprawsock.go
@@ -6,7 +6,7 @@
package net
-// IPAddr represents the address of a IP end point.
+// IPAddr represents the address of an IP end point.
type IPAddr struct {
IP IP
}
@@ -21,7 +21,7 @@ func (a *IPAddr) String() string {
return a.IP.String()
}
-// ResolveIPAddr parses addr as a IP address and resolves domain
+// ResolveIPAddr parses addr as an IP address and resolves domain
// names to numeric addresses on the network net, which must be
// "ip", "ip4" or "ip6". A literal IPv6 host address must be
// enclosed in square brackets, as in "[::]".
diff --git a/libgo/go/net/iprawsock_plan9.go b/libgo/go/net/iprawsock_plan9.go
index 43719fc99..ea3321b7e 100644
--- a/libgo/go/net/iprawsock_plan9.go
+++ b/libgo/go/net/iprawsock_plan9.go
@@ -59,7 +59,7 @@ func (c *IPConn) RemoteAddr() Addr {
// IP-specific methods.
-// ReadFromIP reads a IP packet from c, copying the payload into b.
+// ReadFromIP reads an IP packet from c, copying the payload into b.
// It returns the number of bytes copied into b and the return address
// that was on the packet.
//
@@ -75,7 +75,7 @@ func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
return 0, nil, syscall.EPLAN9
}
-// WriteToIP writes a IP packet to addr via c, copying the payload from b.
+// WriteToIP writes an IP packet to addr via c, copying the payload from b.
//
// WriteToIP can be made to time out and return
// an error with Timeout() == true after a fixed time limit;
diff --git a/libgo/go/net/iprawsock_posix.go b/libgo/go/net/iprawsock_posix.go
index 9fc7ecdb9..dda81ddf8 100644
--- a/libgo/go/net/iprawsock_posix.go
+++ b/libgo/go/net/iprawsock_posix.go
@@ -146,7 +146,7 @@ func (c *IPConn) SetWriteBuffer(bytes int) error {
// IP-specific methods.
-// ReadFromIP reads a IP packet from c, copying the payload into b.
+// ReadFromIP reads an IP packet from c, copying the payload into b.
// It returns the number of bytes copied into b and the return address
// that was on the packet.
//
@@ -184,7 +184,7 @@ func (c *IPConn) ReadFrom(b []byte) (int, Addr, error) {
return n, uaddr.toAddr(), err
}
-// WriteToIP writes a IP packet to addr via c, copying the payload from b.
+// WriteToIP writes an IP packet to addr via c, copying the payload from b.
//
// WriteToIP can be made to time out and return
// an error with Timeout() == true after a fixed time limit;
diff --git a/libgo/go/net/mail/message.go b/libgo/go/net/mail/message.go
index b610ccf3f..93cc4d1ed 100644
--- a/libgo/go/net/mail/message.go
+++ b/libgo/go/net/mail/message.go
@@ -47,7 +47,8 @@ type Message struct {
}
// ReadMessage reads a message from r.
-// The headers are parsed, and the body of the message will be reading from r.
+// The headers are parsed, and the body of the message will be available
+// for reading from r.
func ReadMessage(r io.Reader) (msg *Message, err error) {
tp := textproto.NewReader(bufio.NewReader(r))
diff --git a/libgo/go/net/net_posix.go b/libgo/go/net/net_posix.go
new file mode 100644
index 000000000..3bcc54fe5
--- /dev/null
+++ b/libgo/go/net/net_posix.go
@@ -0,0 +1,110 @@
+// Copyright 2012 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build darwin freebsd linux netbsd openbsd windows
+
+// Base posix socket functions.
+
+package net
+
+import (
+ "os"
+ "syscall"
+ "time"
+)
+
+type conn struct {
+ fd *netFD
+}
+
+func (c *conn) ok() bool { return c != nil && c.fd != nil }
+
+// Implementation of the Conn interface - see Conn for documentation.
+
+// Read implements the Conn Read method.
+func (c *conn) Read(b []byte) (int, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ return c.fd.Read(b)
+}
+
+// Write implements the Conn Write method.
+func (c *conn) Write(b []byte) (int, error) {
+ if !c.ok() {
+ return 0, syscall.EINVAL
+ }
+ return c.fd.Write(b)
+}
+
+// LocalAddr returns the local network address.
+func (c *conn) LocalAddr() Addr {
+ if !c.ok() {
+ return nil
+ }
+ return c.fd.laddr
+}
+
+// RemoteAddr returns the remote network address.
+func (c *conn) RemoteAddr() Addr {
+ if !c.ok() {
+ return nil
+ }
+ return c.fd.raddr
+}
+
+// SetDeadline implements the Conn SetDeadline method.
+func (c *conn) SetDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return setDeadline(c.fd, t)
+}
+
+// SetReadDeadline implements the Conn SetReadDeadline method.
+func (c *conn) SetReadDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return setReadDeadline(c.fd, t)
+}
+
+// SetWriteDeadline implements the Conn SetWriteDeadline method.
+func (c *conn) SetWriteDeadline(t time.Time) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return setWriteDeadline(c.fd, t)
+}
+
+// SetReadBuffer sets the size of the operating system's
+// receive buffer associated with the connection.
+func (c *conn) SetReadBuffer(bytes int) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return setReadBuffer(c.fd, bytes)
+}
+
+// SetWriteBuffer sets the size of the operating system's
+// transmit buffer associated with the connection.
+func (c *conn) SetWriteBuffer(bytes int) error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return setWriteBuffer(c.fd, bytes)
+}
+
+// File returns a copy of the underlying os.File, set to blocking mode.
+// It is the caller's responsibility to close f when finished.
+// Closing c does not affect f, and closing f does not affect c.
+func (c *conn) File() (f *os.File, err error) { return c.fd.dup() }
+
+// Close closes the connection.
+func (c *conn) Close() error {
+ if !c.ok() {
+ return syscall.EINVAL
+ }
+ return c.fd.Close()
+}
diff --git a/libgo/go/net/rpc/jsonrpc/all_test.go b/libgo/go/net/rpc/jsonrpc/all_test.go
index e6c7441f0..adc29d5a1 100644
--- a/libgo/go/net/rpc/jsonrpc/all_test.go
+++ b/libgo/go/net/rpc/jsonrpc/all_test.go
@@ -108,7 +108,7 @@ func TestClient(t *testing.T) {
t.Errorf("Add: expected no error but got string %q", err.Error())
}
if reply.C != args.A+args.B {
- t.Errorf("Add: expected %d got %d", reply.C, args.A+args.B)
+ t.Errorf("Add: got %d expected %d", reply.C, args.A+args.B)
}
args = &Args{7, 8}
@@ -118,7 +118,7 @@ func TestClient(t *testing.T) {
t.Errorf("Mul: expected no error but got string %q", err.Error())
}
if reply.C != args.A*args.B {
- t.Errorf("Mul: expected %d got %d", reply.C, args.A*args.B)
+ t.Errorf("Mul: got %d expected %d", reply.C, args.A*args.B)
}
// Out of order.
@@ -133,7 +133,7 @@ func TestClient(t *testing.T) {
t.Errorf("Add: expected no error but got string %q", addCall.Error.Error())
}
if addReply.C != args.A+args.B {
- t.Errorf("Add: expected %d got %d", addReply.C, args.A+args.B)
+ t.Errorf("Add: got %d expected %d", addReply.C, args.A+args.B)
}
mulCall = <-mulCall.Done
@@ -141,7 +141,7 @@ func TestClient(t *testing.T) {
t.Errorf("Mul: expected no error but got string %q", mulCall.Error.Error())
}
if mulReply.C != args.A*args.B {
- t.Errorf("Mul: expected %d got %d", mulReply.C, args.A*args.B)
+ t.Errorf("Mul: got %d expected %d", mulReply.C, args.A*args.B)
}
// Error test
diff --git a/libgo/go/net/rpc/server.go b/libgo/go/net/rpc/server.go
index 1680e2f0d..e5282202c 100644
--- a/libgo/go/net/rpc/server.go
+++ b/libgo/go/net/rpc/server.go
@@ -24,12 +24,13 @@
where T, T1 and T2 can be marshaled by encoding/gob.
These requirements apply even if a different codec is used.
- (In future, these requirements may soften for custom codecs.)
+ (In the future, these requirements may soften for custom codecs.)
The method's first argument represents the arguments provided by the caller; the
second argument represents the result parameters to be returned to the caller.
The method's return value, if non-nil, is passed back as a string that the client
- sees as if created by errors.New.
+ sees as if created by errors.New. If an error is returned, the reply parameter
+ will not be sent back to the client.
The server may handle requests on a single connection by calling ServeConn. More
typically it will create a network listener and call Accept or, for an HTTP
@@ -181,7 +182,7 @@ type Response struct {
// Server represents an RPC Server.
type Server struct {
- mu sync.Mutex // protects the serviceMap
+ mu sync.RWMutex // protects the serviceMap
serviceMap map[string]*service
reqLock sync.Mutex // protects freeReq
freeReq *Request
@@ -538,9 +539,9 @@ func (server *Server) readRequestHeader(codec ServerCodec) (service *service, mt
return
}
// Look up the request.
- server.mu.Lock()
+ server.mu.RLock()
service = server.serviceMap[serviceMethod[0]]
- server.mu.Unlock()
+ server.mu.RUnlock()
if service == nil {
err = errors.New("rpc: can't find service " + req.ServiceMethod)
return
diff --git a/libgo/go/net/sockopt.go b/libgo/go/net/sockopt.go
index 0cd19266f..b139c4276 100644
--- a/libgo/go/net/sockopt.go
+++ b/libgo/go/net/sockopt.go
@@ -144,22 +144,6 @@ func setDeadline(fd *netFD, t time.Time) error {
return setWriteDeadline(fd, t)
}
-func setReuseAddr(fd *netFD, reuse bool) error {
- if err := fd.incref(false); err != nil {
- return err
- }
- defer fd.decref()
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_REUSEADDR, boolint(reuse)))
-}
-
-func setDontRoute(fd *netFD, dontroute bool) error {
- if err := fd.incref(false); err != nil {
- return err
- }
- defer fd.decref()
- return os.NewSyscallError("setsockopt", syscall.SetsockoptInt(fd.sysfd, syscall.SOL_SOCKET, syscall.SO_DONTROUTE, boolint(dontroute)))
-}
-
func setKeepAlive(fd *netFD, keepalive bool) error {
if err := fd.incref(false); err != nil {
return err
diff --git a/libgo/go/os/error_plan9.go b/libgo/go/os/error_plan9.go
index 3c9dfb0b1..85260c82a 100644
--- a/libgo/go/os/error_plan9.go
+++ b/libgo/go/os/error_plan9.go
@@ -5,21 +5,36 @@
package os
func isExist(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return contains(err.Error(), " exists")
}
func isNotExist(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return contains(err.Error(), "does not exist")
}
func isPermission(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return contains(err.Error(), "permission denied")
diff --git a/libgo/go/os/error_posix.go b/libgo/go/os/error_posix.go
index 1685c1f21..81b626aec 100644
--- a/libgo/go/os/error_posix.go
+++ b/libgo/go/os/error_posix.go
@@ -9,21 +9,36 @@ package os
import "syscall"
func isExist(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return err == syscall.EEXIST || err == ErrExist
}
func isNotExist(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return err == syscall.ENOENT || err == ErrNotExist
}
func isPermission(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return err == syscall.EACCES || err == syscall.EPERM || err == ErrPermission
diff --git a/libgo/go/os/error_test.go b/libgo/go/os/error_test.go
index 42f846fa3..054bb3fcb 100644
--- a/libgo/go/os/error_test.go
+++ b/libgo/go/os/error_test.go
@@ -79,3 +79,30 @@ func checkErrorPredicate(predName string, pred func(error) bool, err error) stri
}
return ""
}
+
+var isExistTests = []struct {
+ err error
+ is bool
+ isnot bool
+}{
+ {&os.PathError{Err: os.ErrInvalid}, false, false},
+ {&os.PathError{Err: os.ErrPermission}, false, false},
+ {&os.PathError{Err: os.ErrExist}, true, false},
+ {&os.PathError{Err: os.ErrNotExist}, false, true},
+ {&os.LinkError{Err: os.ErrInvalid}, false, false},
+ {&os.LinkError{Err: os.ErrPermission}, false, false},
+ {&os.LinkError{Err: os.ErrExist}, true, false},
+ {&os.LinkError{Err: os.ErrNotExist}, false, true},
+ {nil, false, false},
+}
+
+func TestIsExist(t *testing.T) {
+ for _, tt := range isExistTests {
+ if is := os.IsExist(tt.err); is != tt.is {
+ t.Errorf("os.IsExist(%T %v) = %v, want %v", tt.err, tt.err, is, tt.is)
+ }
+ if isnot := os.IsNotExist(tt.err); isnot != tt.isnot {
+ t.Errorf("os.IsNotExist(%T %v) = %v, want %v", tt.err, tt.err, isnot, tt.isnot)
+ }
+ }
+}
diff --git a/libgo/go/os/error_windows.go b/libgo/go/os/error_windows.go
index fbb0d4f3f..83db6c078 100644
--- a/libgo/go/os/error_windows.go
+++ b/libgo/go/os/error_windows.go
@@ -7,7 +7,12 @@ package os
import "syscall"
func isExist(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return err == syscall.ERROR_ALREADY_EXISTS ||
@@ -15,7 +20,12 @@ func isExist(err error) bool {
}
func isNotExist(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return err == syscall.ERROR_FILE_NOT_FOUND ||
@@ -23,7 +33,12 @@ func isNotExist(err error) bool {
}
func isPermission(err error) bool {
- if pe, ok := err.(*PathError); ok {
+ switch pe := err.(type) {
+ case nil:
+ return false
+ case *PathError:
+ err = pe.Err
+ case *LinkError:
err = pe.Err
}
return err == syscall.ERROR_ACCESS_DENIED || err == ErrPermission
diff --git a/libgo/go/os/exec.go b/libgo/go/os/exec.go
index 531b87ca5..6681acfd4 100644
--- a/libgo/go/os/exec.go
+++ b/libgo/go/os/exec.go
@@ -6,6 +6,7 @@ package os
import (
"runtime"
+ "sync/atomic"
"syscall"
)
@@ -13,7 +14,7 @@ import (
type Process struct {
Pid int
handle uintptr
- done bool // process has been successfully waited on
+ isdone uint32 // process has been successfully waited on, non zero if true
}
func newProcess(pid int, handle uintptr) *Process {
@@ -22,6 +23,14 @@ func newProcess(pid int, handle uintptr) *Process {
return p
}
+func (p *Process) setDone() {
+ atomic.StoreUint32(&p.isdone, 1)
+}
+
+func (p *Process) done() bool {
+ return atomic.LoadUint32(&p.isdone) > 0
+}
+
// ProcAttr holds the attributes that will be applied to a new process
// started by StartProcess.
type ProcAttr struct {
diff --git a/libgo/go/os/exec/exec.go b/libgo/go/os/exec/exec.go
index 9a8e18170..c4907cd7d 100644
--- a/libgo/go/os/exec/exec.go
+++ b/libgo/go/os/exec/exec.go
@@ -16,7 +16,7 @@ import (
"syscall"
)
-// Error records the name of a binary that failed to be be executed
+// Error records the name of a binary that failed to be executed
// and the reason it failed.
type Error struct {
Name string
@@ -143,6 +143,9 @@ func (c *Cmd) argv() []string {
func (c *Cmd) stdin() (f *os.File, err error) {
if c.Stdin == nil {
f, err = os.Open(os.DevNull)
+ if err != nil {
+ return
+ }
c.closeAfterStart = append(c.closeAfterStart, f)
return
}
@@ -182,6 +185,9 @@ func (c *Cmd) stderr() (f *os.File, err error) {
func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
if w == nil {
f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
+ if err != nil {
+ return
+ }
c.closeAfterStart = append(c.closeAfterStart, f)
return
}
diff --git a/libgo/go/os/exec/exec_test.go b/libgo/go/os/exec/exec_test.go
index 52f4bce3a..27ebb60d3 100644
--- a/libgo/go/os/exec/exec_test.go
+++ b/libgo/go/os/exec/exec_test.go
@@ -167,6 +167,18 @@ func TestExtraFiles(t *testing.T) {
}
defer ln.Close()
+ // Make sure duplicated fds don't leak to the child.
+ f, err := ln.(*net.TCPListener).File()
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer f.Close()
+ ln2, err := net.FileListener(f)
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer ln2.Close()
+
// Force TLS root certs to be loaded (which might involve
// cgo), to make sure none of that potential C code leaks fds.
ts := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
@@ -203,6 +215,56 @@ func TestExtraFiles(t *testing.T) {
}
}
+func TestExtraFilesRace(t *testing.T) {
+ if runtime.GOOS == "windows" {
+ t.Logf("no operating system support; skipping")
+ return
+ }
+ listen := func() net.Listener {
+ ln, err := net.Listen("tcp", "127.0.0.1:0")
+ if err != nil {
+ t.Fatal(err)
+ }
+ return ln
+ }
+ listenerFile := func(ln net.Listener) *os.File {
+ f, err := ln.(*net.TCPListener).File()
+ if err != nil {
+ t.Fatal(err)
+ }
+ return f
+ }
+ runCommand := func(c *Cmd, out chan<- string) {
+ bout, err := c.CombinedOutput()
+ if err != nil {
+ out <- "ERROR:" + err.Error()
+ } else {
+ out <- string(bout)
+ }
+ }
+
+ for i := 0; i < 10; i++ {
+ la := listen()
+ ca := helperCommand("describefiles")
+ ca.ExtraFiles = []*os.File{listenerFile(la)}
+ lb := listen()
+ cb := helperCommand("describefiles")
+ cb.ExtraFiles = []*os.File{listenerFile(lb)}
+ ares := make(chan string)
+ bres := make(chan string)
+ go runCommand(ca, ares)
+ go runCommand(cb, bres)
+ if got, want := <-ares, fmt.Sprintf("fd3: listener %s\n", la.Addr()); got != want {
+ t.Errorf("iteration %d, process A got:\n%s\nwant:\n%s\n", i, got, want)
+ }
+ if got, want := <-bres, fmt.Sprintf("fd3: listener %s\n", lb.Addr()); got != want {
+ t.Errorf("iteration %d, process B got:\n%s\nwant:\n%s\n", i, got, want)
+ }
+ la.Close()
+ lb.Close()
+ }
+}
+
// TestHelperProcess isn't a real test. It's used as a helper process
// for TestParameterRun.
func TestHelperProcess(*testing.T) {
@@ -318,6 +380,16 @@ func TestHelperProcess(*testing.T) {
case "exit":
n, _ := strconv.Atoi(args[0])
os.Exit(n)
+ case "describefiles":
+ for fd := uintptr(3); fd < 25; fd++ {
+ f := os.NewFile(fd, fmt.Sprintf("fd-%d", fd))
+ ln, err := net.FileListener(f)
+ if err == nil {
+ fmt.Printf("fd%d: listener %s\n", fd, ln.Addr())
+ ln.Close()
+ }
+ }
+ os.Exit(0)
default:
fmt.Fprintf(os.Stderr, "Unknown command %q\n", cmd)
os.Exit(2)
diff --git a/libgo/go/os/exec_plan9.go b/libgo/go/os/exec_plan9.go
index 41cc8c26f..01f06e2cf 100644
--- a/libgo/go/os/exec_plan9.go
+++ b/libgo/go/os/exec_plan9.go
@@ -38,7 +38,7 @@ func (note Plan9Note) String() string {
}
func (p *Process) signal(sig Signal) error {
- if p.done {
+ if p.done() {
return errors.New("os: process already finished")
}
@@ -76,7 +76,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
}
if waitmsg.Pid == p.Pid {
- p.done = true
+ p.setDone()
break
}
}
diff --git a/libgo/go/os/exec_posix.go b/libgo/go/os/exec_posix.go
index 70351cfb3..40fd0fd0e 100644
--- a/libgo/go/os/exec_posix.go
+++ b/libgo/go/os/exec_posix.go
@@ -11,9 +11,10 @@ import (
)
func startProcess(name string, argv []string, attr *ProcAttr) (p *Process, err error) {
- // Double-check existence of the directory we want
+ // If there is no SysProcAttr (ie. no Chroot or changed
+ // UID/GID), double-check existence of the directory we want
// to chdir into. We can make the error clearer this way.
- if attr != nil && attr.Dir != "" {
+ if attr != nil && attr.Sys == nil && attr.Dir != "" {
if _, err := Stat(attr.Dir); err != nil {
pe := err.(*PathError)
pe.Op = "chdir"
diff --git a/libgo/go/os/exec_unix.go b/libgo/go/os/exec_unix.go
index ecfe5353b..fa3ba8a19 100644
--- a/libgo/go/os/exec_unix.go
+++ b/libgo/go/os/exec_unix.go
@@ -24,7 +24,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
return nil, NewSyscallError("wait", e)
}
if pid1 != 0 {
- p.done = true
+ p.setDone()
}
ps = &ProcessState{
pid: pid1,
@@ -35,7 +35,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
}
func (p *Process) signal(sig Signal) error {
- if p.done {
+ if p.done() {
return errors.New("os: process already finished")
}
s, ok := sig.(syscall.Signal)
diff --git a/libgo/go/os/exec_windows.go b/libgo/go/os/exec_windows.go
index 5beca4a65..4aa2ade63 100644
--- a/libgo/go/os/exec_windows.go
+++ b/libgo/go/os/exec_windows.go
@@ -32,7 +32,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
if e != nil {
return nil, NewSyscallError("GetProcessTimes", e)
}
- p.done = true
+ p.setDone()
// NOTE(brainman): It seems that sometimes process is not dead
// when WaitForSingleObject returns. But we do not know any
// other way to wait for it. Sleeping for a while seems to do
@@ -43,7 +43,7 @@ func (p *Process) wait() (ps *ProcessState, err error) {
}
func (p *Process) signal(sig Signal) error {
- if p.done {
+ if p.done() {
return errors.New("os: process already finished")
}
if sig == Kill {
diff --git a/libgo/go/os/file_posix.go b/libgo/go/os/file_posix.go
index 073bd56a4..1ba329315 100644
--- a/libgo/go/os/file_posix.go
+++ b/libgo/go/os/file_posix.go
@@ -13,17 +13,6 @@ import (
func sigpipe() // implemented in package runtime
-func epipecheck(file *File, e error) {
- if e == syscall.EPIPE {
- file.nepipe++
- if file.nepipe >= 10 {
- sigpipe()
- }
- } else {
- file.nepipe = 0
- }
-}
-
// Link creates newname as a hard link to the oldname file.
// If there is an error, it will be of type *LinkError.
func Link(oldname, newname string) error {
diff --git a/libgo/go/os/file_unix.go b/libgo/go/os/file_unix.go
index b8fb2e22c..f677dbb98 100644
--- a/libgo/go/os/file_unix.go
+++ b/libgo/go/os/file_unix.go
@@ -8,6 +8,7 @@ package os
import (
"runtime"
+ "sync/atomic"
"syscall"
)
@@ -24,7 +25,7 @@ type file struct {
fd int
name string
dirinfo *dirInfo // nil unless directory being read
- nepipe int // number of consecutive EPIPE in Write
+ nepipe int32 // number of consecutive EPIPE in Write
}
// Fd returns the integer Unix file descriptor referencing the open file.
@@ -52,6 +53,16 @@ type dirInfo struct {
dir *syscall.DIR // from opendir
}
+func epipecheck(file *File, e error) {
+ if e == syscall.EPIPE {
+ if atomic.AddInt32(&file.nepipe, 1) >= 10 {
+ sigpipe()
+ }
+ } else {
+ atomic.StoreInt32(&file.nepipe, 0)
+ }
+}
+
// DevNull is the name of the operating system's ``null device.''
// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
const DevNull = "/dev/null"
diff --git a/libgo/go/os/os_test.go b/libgo/go/os/os_test.go
index 8d3f677fd..5046e60af 100644
--- a/libgo/go/os/os_test.go
+++ b/libgo/go/os/os_test.go
@@ -67,10 +67,10 @@ var sysdir = func() (sd *sysDir) {
func size(name string, t *testing.T) int64 {
file, err := Open(name)
- defer file.Close()
if err != nil {
t.Fatal("open failed:", err)
}
+ defer file.Close()
var buf [100]byte
len := 0
for {
@@ -132,10 +132,10 @@ func TestStat(t *testing.T) {
func TestFstat(t *testing.T) {
path := sfdir + "/" + sfname
file, err1 := Open(path)
- defer file.Close()
if err1 != nil {
t.Fatal("open failed:", err1)
}
+ defer file.Close()
dir, err2 := file.Stat()
if err2 != nil {
t.Fatal("fstat failed:", err2)
@@ -187,10 +187,10 @@ func TestRead0(t *testing.T) {
func testReaddirnames(dir string, contents []string, t *testing.T) {
file, err := Open(dir)
- defer file.Close()
if err != nil {
t.Fatalf("open %q failed: %v", dir, err)
}
+ defer file.Close()
s, err2 := file.Readdirnames(-1)
if err2 != nil {
t.Fatalf("readdirnames %q failed: %v", dir, err2)
@@ -216,10 +216,10 @@ func testReaddirnames(dir string, contents []string, t *testing.T) {
func testReaddir(dir string, contents []string, t *testing.T) {
file, err := Open(dir)
- defer file.Close()
if err != nil {
t.Fatalf("open %q failed: %v", dir, err)
}
+ defer file.Close()
s, err2 := file.Readdir(-1)
if err2 != nil {
t.Fatalf("readdir %q failed: %v", dir, err2)
@@ -283,10 +283,10 @@ func TestReaddirnamesOneAtATime(t *testing.T) {
dir = "/bin"
}
file, err := Open(dir)
- defer file.Close()
if err != nil {
t.Fatalf("open %q failed: %v", dir, err)
}
+ defer file.Close()
all, err1 := file.Readdirnames(-1)
if err1 != nil {
t.Fatalf("readdirnames %q failed: %v", dir, err1)
diff --git a/libgo/go/os/types.go b/libgo/go/os/types.go
index 0c95c9cec..ecb57872d 100644
--- a/libgo/go/os/types.go
+++ b/libgo/go/os/types.go
@@ -12,7 +12,7 @@ import (
// Getpagesize returns the underlying system's memory page size.
func Getpagesize() int { return syscall.Getpagesize() }
-// A FileInfo describes a file and is returned by Stat and Lstat
+// A FileInfo describes a file and is returned by Stat and Lstat.
type FileInfo interface {
Name() string // base name of the file
Size() int64 // length in bytes for regular files; system-dependent for others
diff --git a/libgo/go/path/path.go b/libgo/go/path/path.go
index a7e041568..b07534b36 100644
--- a/libgo/go/path/path.go
+++ b/libgo/go/path/path.go
@@ -166,7 +166,8 @@ func IsAbs(path string) bool {
}
// Dir returns all but the last element of path, typically the path's directory.
-// The path is Cleaned and trailing slashes are removed before processing.
+// After dropping the final element using Split, the path is Cleaned and trailing
+// slashes are removed.
// If the path is empty, Dir returns ".".
// If the path consists entirely of slashes followed by non-slash bytes, Dir
// returns a single slash. In any other case, the returned path does not end in a
diff --git a/libgo/go/path/path_test.go b/libgo/go/path/path_test.go
index 77f080433..65be55060 100644
--- a/libgo/go/path/path_test.go
+++ b/libgo/go/path/path_test.go
@@ -181,6 +181,7 @@ var dirtests = []PathTest{
{"x/", "x"},
{"abc", "."},
{"abc/def", "abc"},
+ {"abc////def", "abc"},
{"a/b/.x", "a/b"},
{"a/b/c.", "a/b"},
{"a/b/c.x", "a/b"},
diff --git a/libgo/go/reflect/all_test.go b/libgo/go/reflect/all_test.go
index e946c0adf..56ba8a824 100644
--- a/libgo/go/reflect/all_test.go
+++ b/libgo/go/reflect/all_test.go
@@ -1384,7 +1384,30 @@ func TestImportPath(t *testing.T) {
path string
}{
{TypeOf(&base64.Encoding{}).Elem(), "encoding/base64"},
+ {TypeOf(int(0)), ""},
+ {TypeOf(int8(0)), ""},
+ {TypeOf(int16(0)), ""},
+ {TypeOf(int32(0)), ""},
+ {TypeOf(int64(0)), ""},
{TypeOf(uint(0)), ""},
+ {TypeOf(uint8(0)), ""},
+ {TypeOf(uint16(0)), ""},
+ {TypeOf(uint32(0)), ""},
+ {TypeOf(uint64(0)), ""},
+ {TypeOf(uintptr(0)), ""},
+ {TypeOf(float32(0)), ""},
+ {TypeOf(float64(0)), ""},
+ {TypeOf(complex64(0)), ""},
+ {TypeOf(complex128(0)), ""},
+ {TypeOf(byte(0)), ""},
+ {TypeOf(rune(0)), ""},
+ {TypeOf([]byte(nil)), ""},
+ {TypeOf([]rune(nil)), ""},
+ {TypeOf(string("")), ""},
+ {TypeOf((*interface{})(nil)).Elem(), ""},
+ {TypeOf((*byte)(nil)), ""},
+ {TypeOf((*rune)(nil)), ""},
+ {TypeOf((*int64)(nil)), ""},
{TypeOf(map[string]int{}), ""},
{TypeOf((*error)(nil)).Elem(), ""},
}
diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go
index a12fcb266..b25e5c73d 100644
--- a/libgo/go/reflect/value.go
+++ b/libgo/go/reflect/value.go
@@ -1705,10 +1705,11 @@ func ValueOf(i interface{}) Value {
return Value{typ, unsafe.Pointer(eface.word), fl}
}
-// Zero returns a Value representing a zero value for the specified type.
+// Zero returns a Value representing the zero value for the specified type.
// The result is different from the zero value of the Value struct,
// which represents no value at all.
// For example, Zero(TypeOf(42)) returns a Value with Kind Int and value 0.
+// The returned value is neither addressable nor settable.
func Zero(typ Type) Value {
if typ == nil {
panic("reflect: Zero(nil)")
diff --git a/libgo/go/regexp/regexp.go b/libgo/go/regexp/regexp.go
index 87e6b1c61..e4896a1c0 100644
--- a/libgo/go/regexp/regexp.go
+++ b/libgo/go/regexp/regexp.go
@@ -441,7 +441,7 @@ func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
}
// ReplaceAllStringFunc returns a copy of src in which all matches of the
-// Regexp have been replaced by the return value of of function repl applied
+// Regexp have been replaced by the return value of function repl applied
// to the matched substring. The replacement returned by repl is substituted
// directly, without using Expand.
func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
@@ -539,7 +539,7 @@ func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
}
// ReplaceAllFunc returns a copy of src in which all matches of the
-// Regexp have been replaced by the return value of of function repl applied
+// Regexp have been replaced by the return value of function repl applied
// to the matched byte slice. The replacement returned by repl is substituted
// directly, without using Expand.
func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
@@ -686,8 +686,9 @@ func (re *Regexp) FindStringIndex(s string) (loc []int) {
// FindReaderIndex returns a two-element slice of integers defining the
// location of the leftmost match of the regular expression in text read from
-// the RuneReader. The match itself is at s[loc[0]:loc[1]]. A return
-// value of nil indicates no match.
+// the RuneReader. The match text was found in the input stream at
+// byte offset loc[0] through loc[1]-1.
+// A return value of nil indicates no match.
func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) {
a := re.doExecute(r, nil, "", 0, 2)
if a == nil {
diff --git a/libgo/go/runtime/pprof/pprof.go b/libgo/go/runtime/pprof/pprof.go
index f67e8a8f9..8cc15390c 100644
--- a/libgo/go/runtime/pprof/pprof.go
+++ b/libgo/go/runtime/pprof/pprof.go
@@ -356,7 +356,7 @@ func countHeap() int {
return n
}
-// writeHeapProfile writes the current runtime heap profile to w.
+// writeHeap writes the current runtime heap profile to w.
func writeHeap(w io.Writer, debug int) error {
// Find out how many records there are (MemProfile(nil, false)),
// allocate that many records, and get the data.
diff --git a/libgo/go/runtime/pprof/pprof_test.go b/libgo/go/runtime/pprof/pprof_test.go
index e933058e5..474011523 100644
--- a/libgo/go/runtime/pprof/pprof_test.go
+++ b/libgo/go/runtime/pprof/pprof_test.go
@@ -6,6 +6,7 @@ package pprof_test
import (
"bytes"
+ "fmt"
"hash/crc32"
"os/exec"
"runtime"
@@ -49,19 +50,27 @@ func TestCPUProfile(t *testing.T) {
// Convert []byte to []uintptr.
bytes := prof.Bytes()
+ l := len(bytes) / int(unsafe.Sizeof(uintptr(0)))
val := *(*[]uintptr)(unsafe.Pointer(&bytes))
- val = val[:len(bytes)/int(unsafe.Sizeof(uintptr(0)))]
+ val = val[:l]
- if len(val) < 10 {
+ if l < 13 {
t.Fatalf("profile too short: %#x", val)
}
- if val[0] != 0 || val[1] != 3 || val[2] != 0 || val[3] != 1e6/100 || val[4] != 0 {
- t.Fatalf("unexpected header %#x", val[:5])
+
+ fmt.Println(val, l)
+ hd, val, tl := val[:5], val[5:l-3], val[l-3:]
+ fmt.Println(hd, val, tl)
+ if hd[0] != 0 || hd[1] != 3 || hd[2] != 0 || hd[3] != 1e6/100 || hd[4] != 0 {
+ t.Fatalf("unexpected header %#x", hd)
+ }
+
+ if tl[0] != 0 || tl[1] != 1 || tl[2] != 0 {
+ t.Fatalf("malformed end-of-data marker %#x", tl)
}
// Check that profile is well formed and contains ChecksumIEEE.
found := false
- val = val[5:]
for len(val) > 0 {
if len(val) < 2 || val[0] < 1 || val[1] < 1 || uintptr(len(val)) < 2+val[1] {
t.Fatalf("malformed profile. leftover: %#x", val)
diff --git a/libgo/go/strconv/atoi.go b/libgo/go/strconv/atoi.go
index 59ef264d1..bdd5d71f8 100644
--- a/libgo/go/strconv/atoi.go
+++ b/libgo/go/strconv/atoi.go
@@ -44,7 +44,7 @@ func cutoff64(base int) uint64 {
}
// ParseUint is like ParseInt but for unsigned numbers.
-func ParseUint(s string, b int, bitSize int) (n uint64, err error) {
+func ParseUint(s string, base int, bitSize int) (n uint64, err error) {
var cutoff, maxVal uint64
if bitSize == 0 {
@@ -57,32 +57,32 @@ func ParseUint(s string, b int, bitSize int) (n uint64, err error) {
err = ErrSyntax
goto Error
- case 2 <= b && b <= 36:
+ case 2 <= base && base <= 36:
// valid base; nothing to do
- case b == 0:
+ case base == 0:
// Look for octal, hex prefix.
switch {
case s[0] == '0' && len(s) > 1 && (s[1] == 'x' || s[1] == 'X'):
- b = 16
+ base = 16
s = s[2:]
if len(s) < 1 {
err = ErrSyntax
goto Error
}
case s[0] == '0':
- b = 8
+ base = 8
default:
- b = 10
+ base = 10
}
default:
- err = errors.New("invalid base " + Itoa(b))
+ err = errors.New("invalid base " + Itoa(base))
goto Error
}
n = 0
- cutoff = cutoff64(b)
+ cutoff = cutoff64(base)
maxVal = 1<<uint(bitSize) - 1
for i := 0; i < len(s); i++ {
@@ -100,19 +100,19 @@ func ParseUint(s string, b int, bitSize int) (n uint64, err error) {
err = ErrSyntax
goto Error
}
- if int(v) >= b {
+ if int(v) >= base {
n = 0
err = ErrSyntax
goto Error
}
if n >= cutoff {
- // n*b overflows
+ // n*base overflows
n = 1<<64 - 1
err = ErrRange
goto Error
}
- n *= uint64(b)
+ n *= uint64(base)
n1 := n + uint64(v)
if n1 < n || n1 > maxVal {
diff --git a/libgo/go/sync/waitgroup.go b/libgo/go/sync/waitgroup.go
index 0165b1ffb..bc9e738e7 100644
--- a/libgo/go/sync/waitgroup.go
+++ b/libgo/go/sync/waitgroup.go
@@ -32,10 +32,11 @@ type WaitGroup struct {
// Add adds delta, which may be negative, to the WaitGroup counter.
// If the counter becomes zero, all goroutines blocked on Wait() are released.
+// If the counter goes negative, Add panics.
func (wg *WaitGroup) Add(delta int) {
v := atomic.AddInt32(&wg.counter, int32(delta))
if v < 0 {
- panic("sync: negative WaitGroup count")
+ panic("sync: negative WaitGroup counter")
}
if v > 0 || atomic.LoadInt32(&wg.waiters) == 0 {
return
diff --git a/libgo/go/sync/waitgroup_test.go b/libgo/go/sync/waitgroup_test.go
index 34430fc21..84c4cfc37 100644
--- a/libgo/go/sync/waitgroup_test.go
+++ b/libgo/go/sync/waitgroup_test.go
@@ -50,7 +50,7 @@ func TestWaitGroup(t *testing.T) {
func TestWaitGroupMisuse(t *testing.T) {
defer func() {
err := recover()
- if err != "sync: negative WaitGroup count" {
+ if err != "sync: negative WaitGroup counter" {
t.Fatalf("Unexpected panic: %#v", err)
}
}()
diff --git a/libgo/go/syscall/env_windows.go b/libgo/go/syscall/env_windows.go
index 8308f10a2..3107ae5f4 100644
--- a/libgo/go/syscall/env_windows.go
+++ b/libgo/go/syscall/env_windows.go
@@ -12,14 +12,18 @@ import (
)
func Getenv(key string) (value string, found bool) {
+ keyp, err := utf16PtrFromString(key)
+ if err != nil {
+ return "", false
+ }
b := make([]uint16, 100)
- n, e := GetEnvironmentVariable(StringToUTF16Ptr(key), &b[0], uint32(len(b)))
+ n, e := GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
if n == 0 && e == ERROR_ENVVAR_NOT_FOUND {
return "", false
}
if n > uint32(len(b)) {
b = make([]uint16, n)
- n, e = GetEnvironmentVariable(StringToUTF16Ptr(key), &b[0], uint32(len(b)))
+ n, e = GetEnvironmentVariable(keyp, &b[0], uint32(len(b)))
if n > uint32(len(b)) {
n = 0
}
@@ -32,10 +36,18 @@ func Getenv(key string) (value string, found bool) {
func Setenv(key, value string) error {
var v *uint16
+ var err error
if len(value) > 0 {
- v = StringToUTF16Ptr(value)
+ v, err = utf16PtrFromString(value)
+ if err != nil {
+ return err
+ }
+ }
+ keyp, err := utf16PtrFromString(key)
+ if err != nil {
+ return err
}
- e := SetEnvironmentVariable(StringToUTF16Ptr(key), v)
+ e := SetEnvironmentVariable(keyp, v)
if e != nil {
return e
}
diff --git a/libgo/go/syscall/exec_unix.go b/libgo/go/syscall/exec_unix.go
index 664908d13..b34ee1bf8 100644
--- a/libgo/go/syscall/exec_unix.go
+++ b/libgo/go/syscall/exec_unix.go
@@ -103,8 +103,9 @@ import (
var ForkLock sync.RWMutex
-// Convert array of string to array
-// of NUL-terminated byte pointer.
+// Convert array of string to array of NUL-terminated byte pointer.
+// If any string contains a NUL byte this function panics instead
+// of returning an error.
func StringSlicePtr(ss []string) []*byte {
bb := make([]*byte, len(ss)+1)
for i := 0; i < len(ss); i++ {
@@ -114,6 +115,22 @@ func StringSlicePtr(ss []string) []*byte {
return bb
}
+// slicePtrFromStrings converts a slice of strings to a slice of
+// pointers to NUL-terminated byte slices. If any string contains
+// a NUL byte, it returns (nil, EINVAL).
+func slicePtrFromStrings(ss []string) ([]*byte, error) {
+ var err error
+ bb := make([]*byte, len(ss)+1)
+ for i := 0; i < len(ss); i++ {
+ bb[i], err = bytePtrFromString(ss[i])
+ if err != nil {
+ return nil, err
+ }
+ }
+ bb[len(ss)] = nil
+ return bb, nil
+}
+
func CloseOnExec(fd int) { fcntl(fd, F_SETFD, FD_CLOEXEC) }
func SetNonblock(fd int, nonblocking bool) (err error) {
@@ -168,9 +185,18 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
p[1] = -1
// Convert args to C form.
- argv0p := StringBytePtr(argv0)
- argvp := StringSlicePtr(argv)
- envvp := StringSlicePtr(attr.Env)
+ argv0p, err := bytePtrFromString(argv0)
+ if err != nil {
+ return 0, err
+ }
+ argvp, err := slicePtrFromStrings(argv)
+ if err != nil {
+ return 0, err
+ }
+ envvp, err := slicePtrFromStrings(attr.Env)
+ if err != nil {
+ return 0, err
+ }
if runtime.GOOS == "freebsd" && len(argv[0]) > len(argv0) {
argvp[0] = argv0p
@@ -178,11 +204,17 @@ func forkExec(argv0 string, argv []string, attr *ProcAttr) (pid int, err error)
var chroot *byte
if sys.Chroot != "" {
- chroot = StringBytePtr(sys.Chroot)
+ chroot, err = bytePtrFromString(sys.Chroot)
+ if err != nil {
+ return 0, err
+ }
}
var dir *byte
if attr.Dir != "" {
- dir = StringBytePtr(attr.Dir)
+ dir, err = bytePtrFromString(attr.Dir)
+ if err != nil {
+ return 0, err
+ }
}
// Acquire the fork lock so that no other threads
@@ -254,8 +286,18 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
// Ordinary exec.
func Exec(argv0 string, argv []string, envv []string) (err error) {
- err1 := raw_execve(StringBytePtr(argv0),
- &StringSlicePtr(argv)[0],
- &StringSlicePtr(envv)[0])
+ argv0p, err := bytePtrFromString(argv0)
+ if err != nil {
+ return err
+ }
+ argvp, err := slicePtrFromStrings(argv)
+ if err != nil {
+ return err
+ }
+ envvp, err := slicePtrFromStrings(envv)
+ if err != nil {
+ return err
+ }
+ err1 := raw_execve(argv0p, &argvp[0], &envvp[0])
return Errno(err1)
}
diff --git a/libgo/go/syscall/exec_windows.go b/libgo/go/syscall/exec_windows.go
index 4dc4d059d..68779c461 100644
--- a/libgo/go/syscall/exec_windows.go
+++ b/libgo/go/syscall/exec_windows.go
@@ -132,7 +132,10 @@ func SetNonblock(fd Handle, nonblocking bool) (err error) {
// getFullPath retrieves the full path of the specified file.
// Just a wrapper for Windows GetFullPathName api.
func getFullPath(name string) (path string, err error) {
- p := StringToUTF16Ptr(name)
+ p, err := utf16PtrFromString(name)
+ if err != nil {
+ return "", err
+ }
buf := make([]uint16, 100)
n, err := GetFullPathName(p, uint32(len(buf)), &buf[0], nil)
if err != nil {
@@ -261,7 +264,10 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
return 0, 0, err
}
}
- argv0p := StringToUTF16Ptr(argv0)
+ argv0p, err := utf16PtrFromString(argv0)
+ if err != nil {
+ return 0, 0, err
+ }
var cmdline string
// Windows CreateProcess takes the command line as a single string:
@@ -275,12 +281,18 @@ func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle
var argvp *uint16
if len(cmdline) != 0 {
- argvp = StringToUTF16Ptr(cmdline)
+ argvp, err = utf16PtrFromString(cmdline)
+ if err != nil {
+ return 0, 0, err
+ }
}
var dirp *uint16
if len(attr.Dir) != 0 {
- dirp = StringToUTF16Ptr(attr.Dir)
+ dirp, err = utf16PtrFromString(attr.Dir)
+ if err != nil {
+ return 0, 0, err
+ }
}
// Acquire the fork lock so that no other threads
diff --git a/libgo/go/syscall/security_windows.go b/libgo/go/syscall/security_windows.go
index bd40fe586..4353af4fb 100644
--- a/libgo/go/syscall/security_windows.go
+++ b/libgo/go/syscall/security_windows.go
@@ -37,10 +37,13 @@ const (
// TranslateAccountName converts a directory service
// object name from one format to another.
func TranslateAccountName(username string, from, to uint32, initSize int) (string, error) {
- u := StringToUTF16Ptr(username)
+ u, e := utf16PtrFromString(username)
+ if e != nil {
+ return "", e
+ }
b := make([]uint16, 50)
n := uint32(len(b))
- e := TranslateName(u, from, to, &b[0], &n)
+ e = TranslateName(u, from, to, &b[0], &n)
if e != nil {
if e != ERROR_INSUFFICIENT_BUFFER {
return "", e
@@ -94,7 +97,11 @@ type SID struct{}
// sid into a valid, functional sid.
func StringToSid(s string) (*SID, error) {
var sid *SID
- e := ConvertStringSidToSid(StringToUTF16Ptr(s), &sid)
+ p, e := utf16PtrFromString(s)
+ if e != nil {
+ return nil, e
+ }
+ e = ConvertStringSidToSid(p, &sid)
if e != nil {
return nil, e
}
@@ -109,17 +116,23 @@ func LookupSID(system, account string) (sid *SID, domain string, accType uint32,
if len(account) == 0 {
return nil, "", 0, EINVAL
}
- acc := StringToUTF16Ptr(account)
+ acc, e := utf16PtrFromString(account)
+ if e != nil {
+ return nil, "", 0, e
+ }
var sys *uint16
if len(system) > 0 {
- sys = StringToUTF16Ptr(system)
+ sys, e = utf16PtrFromString(system)
+ if e != nil {
+ return nil, "", 0, e
+ }
}
db := make([]uint16, 50)
dn := uint32(len(db))
b := make([]byte, 50)
n := uint32(len(b))
sid = (*SID)(unsafe.Pointer(&b[0]))
- e := LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
+ e = LookupAccountName(sys, acc, sid, &n, &db[0], &dn, &accType)
if e != nil {
if e != ERROR_INSUFFICIENT_BUFFER {
return nil, "", 0, e
@@ -170,7 +183,10 @@ func (sid *SID) Copy() (*SID, error) {
func (sid *SID) LookupAccount(system string) (account, domain string, accType uint32, err error) {
var sys *uint16
if len(system) > 0 {
- sys = StringToUTF16Ptr(system)
+ sys, err = utf16PtrFromString(system)
+ if err != nil {
+ return "", "", 0, err
+ }
}
b := make([]uint16, 50)
n := uint32(len(b))
diff --git a/libgo/go/syscall/syscall.go b/libgo/go/syscall/syscall.go
index 4efaaec3b..3090a5ec6 100644
--- a/libgo/go/syscall/syscall.go
+++ b/libgo/go/syscall/syscall.go
@@ -16,18 +16,47 @@ package syscall
import "unsafe"
-// StringByteSlice returns a NUL-terminated slice of bytes
-// containing the text of s.
+// StringByteSlice returns a NUL-terminated slice of bytes containing the text of s.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
func StringByteSlice(s string) []byte {
+ a, err := byteSliceFromString(s)
+ if err != nil {
+ panic("syscall: string with NUL passed to StringByteSlice")
+ }
+ return a
+}
+
+// byteSliceFromString returns a NUL-terminated slice of bytes
+// containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func byteSliceFromString(s string) ([]byte, error) {
+ for i := 0; i < len(s); i++ {
+ if s[i] == 0 {
+ return nil, EINVAL
+ }
+ }
a := make([]byte, len(s)+1)
copy(a, s)
- return a
+ return a, nil
}
-// StringBytePtr returns a pointer to a NUL-terminated array of bytes
-// containing the text of s.
+// StringBytePtr returns a pointer to a NUL-terminated array of bytes containing the text of s.
+// If s contains a NUL byte this function panics instead of
+// returning an error.
func StringBytePtr(s string) *byte { return &StringByteSlice(s)[0] }
+// bytePtrFromString returns a pointer to a NUL-terminated array of
+// bytes containing the text of s. If s contains a NUL byte at any
+// location, it returns (nil, EINVAL).
+func bytePtrFromString(s string) (*byte, error) {
+ a, err := byteSliceFromString(s)
+ if err != nil {
+ return nil, err
+ }
+ return &a[0], nil
+}
+
// Single-word zero for use when we need a valid pointer to 0 bytes.
// See mksyscall.pl.
var _zero uintptr
diff --git a/libgo/go/syscall/syscall_linux_386.go b/libgo/go/syscall/syscall_linux_386.go
index 9a988a5dc..08422def3 100644
--- a/libgo/go/syscall/syscall_linux_386.go
+++ b/libgo/go/syscall/syscall_linux_386.go
@@ -8,13 +8,9 @@ package syscall
import "unsafe"
-func (r *PtraceRegs) PC() uint64 {
- return uint64(uint32(r.Eip))
-}
+func (r *PtraceRegs) PC() uint64 { return uint64(uint32(r.Eip)) }
-func (r *PtraceRegs) SetPC(pc uint64) {
- r.Eip = int32(pc)
-}
+func (r *PtraceRegs) SetPC(pc uint64) { r.Eip = int32(pc) }
func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
return ptrace(PTRACE_GETREGS, pid, 0, uintptr(unsafe.Pointer(regsout)))
diff --git a/libgo/go/testing/testing.go b/libgo/go/testing/testing.go
index f59ce8ed6..e56b77c9c 100644
--- a/libgo/go/testing/testing.go
+++ b/libgo/go/testing/testing.go
@@ -79,6 +79,7 @@
package testing
import (
+ "bytes"
"flag"
"fmt"
"os"
@@ -86,6 +87,7 @@ import (
"runtime/pprof"
"strconv"
"strings"
+ "sync"
"time"
)
@@ -115,8 +117,10 @@ var (
// common holds the elements common between T and B and
// captures common methods such as Errorf.
type common struct {
- output []byte // Output generated by test or benchmark.
- failed bool // Test or benchmark has failed.
+ mu sync.RWMutex // guards output and failed
+ output []byte // Output generated by test or benchmark.
+ failed bool // Test or benchmark has failed.
+
start time.Time // Time test or benchmark started
duration time.Duration
self interface{} // To be sent on signal channel when done.
@@ -128,37 +132,42 @@ func Short() bool {
return *short
}
-// decorate inserts the final newline if needed and indentation tabs for formatting.
-// If addFileLine is true, it also prefixes the string with the file and line of the call site.
-func decorate(s string, addFileLine bool) string {
- if addFileLine {
- _, file, line, ok := runtime.Caller(3) // decorate + log + public function.
- if ok {
- // Truncate file name at last file name separator.
- if index := strings.LastIndex(file, "/"); index >= 0 {
- file = file[index+1:]
- } else if index = strings.LastIndex(file, "\\"); index >= 0 {
- file = file[index+1:]
- }
- } else {
- file = "???"
- line = 1
+// decorate prefixes the string with the file and line of the call site
+// and inserts the final newline if needed and indentation tabs for formatting.
+func decorate(s string) string {
+ _, file, line, ok := runtime.Caller(3) // decorate + log + public function.
+ if ok {
+ // Truncate file name at last file name separator.
+ if index := strings.LastIndex(file, "/"); index >= 0 {
+ file = file[index+1:]
+ } else if index = strings.LastIndex(file, "\\"); index >= 0 {
+ file = file[index+1:]
}
- s = fmt.Sprintf("%s:%d: %s", file, line, s)
- }
- s = "\t" + s // Every line is indented at least one tab.
- n := len(s)
- if n > 0 && s[n-1] != '\n' {
- s += "\n"
- n++
+ } else {
+ file = "???"
+ line = 1
}
- for i := 0; i < n-1; i++ { // -1 to avoid final newline
- if s[i] == '\n' {
+ buf := new(bytes.Buffer)
+ fmt.Fprintf(buf, "%s:%d: ", file, line)
+
+ lines := strings.Split(s, "\n")
+ for i, line := range lines {
+ if i > 0 {
+ buf.WriteByte('\n')
+ }
+ // Every line is indented at least one tab.
+ buf.WriteByte('\t')
+ if i > 0 {
// Second and subsequent lines are indented an extra tab.
- return s[0:i+1] + "\t" + decorate(s[i+1:n], false)
+ buf.WriteByte('\t')
}
+ buf.WriteString(line)
+ }
+ if l := len(s); l > 0 && s[len(s)-1] != '\n' {
+ // Add final new line if needed.
+ buf.WriteByte('\n')
}
- return s
+ return buf.String()
}
// T is a type passed to Test functions to manage test state and support formatted test logs.
@@ -170,10 +179,18 @@ type T struct {
}
// Fail marks the function as having failed but continues execution.
-func (c *common) Fail() { c.failed = true }
+func (c *common) Fail() {
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.failed = true
+}
// Failed returns whether the function has failed.
-func (c *common) Failed() bool { return c.failed }
+func (c *common) Failed() bool {
+ c.mu.RLock()
+ defer c.mu.RUnlock()
+ return c.failed
+}
// FailNow marks the function as having failed and stops its execution.
// Execution will continue at the next test or benchmark.
@@ -204,7 +221,9 @@ func (c *common) FailNow() {
// log generates the output. It's always at the same stack depth.
func (c *common) log(s string) {
- c.output = append(c.output, decorate(s, true)...)
+ c.mu.Lock()
+ defer c.mu.Unlock()
+ c.output = append(c.output, decorate(s)...)
}
// Log formats its arguments using default formatting, analogous to Println(),
@@ -297,7 +316,7 @@ func Main(matchString func(pat, str string) (bool, error), tests []InternalTest,
func (t *T) report() {
tstr := fmt.Sprintf("(%.2f seconds)", t.duration.Seconds())
format := "--- %s: %s %s\n%s"
- if t.failed {
+ if t.Failed() {
fmt.Printf(format, "FAIL", t.name, tstr, t.output)
} else if *chatty {
fmt.Printf(format, "PASS", t.name, tstr, t.output)
@@ -356,7 +375,7 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT
continue
}
t.report()
- ok = ok && !out.failed
+ ok = ok && !out.Failed()
}
running := 0
@@ -369,7 +388,7 @@ func RunTests(matchString func(pat, str string) (bool, error), tests []InternalT
}
t := (<-collector).(*T)
t.report()
- ok = ok && !t.failed
+ ok = ok && !t.Failed()
running--
}
}
diff --git a/libgo/go/text/tabwriter/tabwriter.go b/libgo/go/text/tabwriter/tabwriter.go
index ce84600d6..722ac8d87 100644
--- a/libgo/go/text/tabwriter/tabwriter.go
+++ b/libgo/go/text/tabwriter/tabwriter.go
@@ -547,7 +547,7 @@ func (b *Writer) Write(buf []byte) (n int, err error) {
}
// NewWriter allocates and initializes a new tabwriter.Writer.
-// The parameters are the same as for the the Init function.
+// The parameters are the same as for the Init function.
//
func NewWriter(output io.Writer, minwidth, tabwidth, padding int, padchar byte, flags uint) *Writer {
return new(Writer).Init(output, minwidth, tabwidth, padding, padchar, flags)
diff --git a/libgo/go/text/template/doc.go b/libgo/go/text/template/doc.go
index aa50ab97f..4a1682d97 100644
--- a/libgo/go/text/template/doc.go
+++ b/libgo/go/text/template/doc.go
@@ -198,7 +198,7 @@ If a "range" action initializes a variable, the variable is set to the
successive elements of the iteration. Also, a "range" may declare two
variables, separated by a comma:
- $index, $element := pipeline
+ range $index, $element := pipeline
in which case $index and $element are set to the successive values of the
array/slice index or map key and element, respectively. Note that if there is
diff --git a/libgo/go/text/template/exec_test.go b/libgo/go/text/template/exec_test.go
index f4ae50f0e..64149533b 100644
--- a/libgo/go/text/template/exec_test.go
+++ b/libgo/go/text/template/exec_test.go
@@ -387,7 +387,7 @@ var execTests = []execTest{
{"slice[WRONG]", "{{index .SI `hello`}}", "", tVal, false},
{"map[one]", "{{index .MSI `one`}}", "1", tVal, true},
{"map[two]", "{{index .MSI `two`}}", "2", tVal, true},
- {"map[NO]", "{{index .MSI `XXX`}}", "", tVal, true},
+ {"map[NO]", "{{index .MSI `XXX`}}", "0", tVal, true},
{"map[WRONG]", "{{index .MSI 10}}", "", tVal, false},
{"double index", "{{index .SMSI 1 `eleven`}}", "11", tVal, true},
diff --git a/libgo/go/text/template/funcs.go b/libgo/go/text/template/funcs.go
index 8fbf0ef50..e6fa0fb5f 100644
--- a/libgo/go/text/template/funcs.go
+++ b/libgo/go/text/template/funcs.go
@@ -128,7 +128,7 @@ func index(item interface{}, indices ...interface{}) (interface{}, error) {
if x := v.MapIndex(index); x.IsValid() {
v = x
} else {
- v = reflect.Zero(v.Type().Key())
+ v = reflect.Zero(v.Type().Elem())
}
default:
return nil, fmt.Errorf("can't index item of type %s", index.Type())
@@ -154,7 +154,7 @@ func length(item interface{}) (int, error) {
// Function invocation
-// call returns the result of evaluating the the first argument as a function.
+// call returns the result of evaluating the first argument as a function.
// The function must return 1 result, or 2 results, the second of which is an error.
func call(fn interface{}, args ...interface{}) (interface{}, error) {
v := reflect.ValueOf(fn)
diff --git a/libgo/go/text/template/parse/lex.go b/libgo/go/text/template/parse/lex.go
index 7705c0b88..c4e1a56a8 100644
--- a/libgo/go/text/template/parse/lex.go
+++ b/libgo/go/text/template/parse/lex.go
@@ -257,16 +257,17 @@ func lexText(l *lexer) stateFn {
// lexLeftDelim scans the left delimiter, which is known to be present.
func lexLeftDelim(l *lexer) stateFn {
- if strings.HasPrefix(l.input[l.pos:], l.leftDelim+leftComment) {
+ l.pos += len(l.leftDelim)
+ if strings.HasPrefix(l.input[l.pos:], leftComment) {
return lexComment
}
- l.pos += len(l.leftDelim)
l.emit(itemLeftDelim)
return lexInsideAction
}
// lexComment scans a comment. The left comment marker is known to be present.
func lexComment(l *lexer) stateFn {
+ l.pos += len(leftComment)
i := strings.Index(l.input[l.pos:], rightComment+l.rightDelim)
if i < 0 {
return l.errorf("unclosed comment")
diff --git a/libgo/go/text/template/parse/lex_test.go b/libgo/go/text/template/parse/lex_test.go
index 6ee1b4701..f3b23c91e 100644
--- a/libgo/go/text/template/parse/lex_test.go
+++ b/libgo/go/text/template/parse/lex_test.go
@@ -198,6 +198,10 @@ var lexTests = []lexTest{
tRight,
tEOF,
}},
+ {"text with bad comment", "hello-{{/*/}}-world", []item{
+ {itemText, "hello-"},
+ {itemError, `unclosed comment`},
+ }},
}
// collect gathers the emitted items into a slice.
diff --git a/libgo/go/time/time.go b/libgo/go/time/time.go
index 2461dac06..d48ca0c26 100644
--- a/libgo/go/time/time.go
+++ b/libgo/go/time/time.go
@@ -241,10 +241,10 @@ func (t Time) IsZero() bool {
// It is called when computing a presentation property like Month or Hour.
func (t Time) abs() uint64 {
l := t.loc
- if l == nil {
- l = &utcLoc
+ // Avoid function calls when possible.
+ if l == nil || l == &localLoc {
+ l = l.get()
}
- // Avoid function call if we hit the local time cache.
sec := t.sec + internalToUnix
if l != &utcLoc {
if l.cacheZone != nil && l.cacheStart <= sec && sec < l.cacheEnd {
diff --git a/libgo/runtime/chan.c b/libgo/runtime/chan.c
index d0a1612ad..1e389a218 100644
--- a/libgo/runtime/chan.c
+++ b/libgo/runtime/chan.c
@@ -87,7 +87,7 @@ runtime_makechan_c(ChanType *t, int64 hint)
Hchan *c;
int32 n;
const Type *elem;
-
+
elem = t->__element_type;
if(hint < 0 || (int32)hint != hint || (elem->__size > 0 && (uintptr)hint > MaxMem / elem->__size))
@@ -191,7 +191,7 @@ runtime_chansend(ChanType *t, Hchan *c, byte *ep, bool *pres)
sg = dequeue(&c->recvq);
if(sg != nil) {
runtime_unlock(c);
-
+
gp = sg->g;
gp->param = sg;
if(sg->elem != nil)
@@ -530,7 +530,7 @@ runtime_selectnbrecv(ChanType *t, byte *v, Hchan *c)
runtime_chanrecv(t, c, v, &selected, nil);
return selected;
-}
+}
// func selectnbrecv2(elem *any, ok *bool, c chan any) bool
//
@@ -562,7 +562,7 @@ runtime_selectnbrecv2(ChanType *t, byte *v, _Bool *received, Hchan *c)
if(received != nil)
*received = r;
return selected;
-}
+}
// For reflect:
// func chansend(c chan, val iword, nb bool) (selected bool)
@@ -578,7 +578,7 @@ reflect_chansend(ChanType *t, Hchan *c, uintptr val, _Bool nb)
bool selected;
bool *sp;
byte *vp;
-
+
if(nb) {
selected = false;
sp = (bool*)&selected;
@@ -697,7 +697,7 @@ runtime_selectsend(Select *sel, Hchan *c, void *elem, int index)
// nil cases do not compete
if(c == nil)
return;
-
+
selectsend(sel, c, index, elem);
}
@@ -706,7 +706,7 @@ selectsend(Select *sel, Hchan *c, int index, void *elem)
{
int32 i;
Scase *cas;
-
+
i = sel->ncase;
if(i >= sel->tcase)
runtime_throw("selectsend: too many cases");
@@ -977,7 +977,7 @@ loop:
case CaseRecv:
enqueue(&c->recvq, sg);
break;
-
+
case CaseSend:
enqueue(&c->sendq, sg);
break;
diff --git a/libgo/runtime/cpuprof.c b/libgo/runtime/cpuprof.c
index 252948d66..9bf5d11e6 100644
--- a/libgo/runtime/cpuprof.c
+++ b/libgo/runtime/cpuprof.c
@@ -105,6 +105,7 @@ struct Profile {
uint32 wtoggle;
bool wholding; // holding & need to release a log half
bool flushing; // flushing hash table - profile is over
+ bool eod_sent; // special end-of-data record sent; => flushing
};
static Lock lk;
@@ -115,6 +116,8 @@ static void add(Profile*, uintptr*, int32);
static bool evict(Profile*, Entry*);
static bool flushlog(Profile*);
+static uintptr eod[3] = {0, 1, 0};
+
// LostProfileData is a no-op function used in profiles
// to mark the number of profiling stack traces that were
// discarded due to slow data writers.
@@ -168,6 +171,7 @@ runtime_SetCPUProfileRate(int32 hz)
prof->wholding = false;
prof->wtoggle = 0;
prof->flushing = false;
+ prof->eod_sent = false;
runtime_noteclear(&prof->wait);
runtime_setcpuprofilerate(tick, hz);
@@ -414,6 +418,16 @@ breakflush:
}
// Made it through the table without finding anything to log.
+ if(!p->eod_sent) {
+ // We may not have space to append this to the partial log buf,
+ // so we always return a new slice for the end-of-data marker.
+ p->eod_sent = true;
+ ret.array = (byte*)eod;
+ ret.len = sizeof eod;
+ ret.cap = ret.len;
+ return ret;
+ }
+
// Finally done. Clean up and return nil.
p->flushing = false;
if(!runtime_cas(&p->handoff, p->handoff, 0))
diff --git a/libgo/runtime/go-caller.c b/libgo/runtime/go-caller.c
index 8d8fe4c87..843adf6f0 100644
--- a/libgo/runtime/go-caller.c
+++ b/libgo/runtime/go-caller.c
@@ -98,7 +98,12 @@ __go_get_backtrace_state ()
{
runtime_lock (&back_state_lock);
if (back_state == NULL)
- back_state = backtrace_create_state (NULL, 1, error_callback, NULL);
+ {
+ const char *filename;
+
+ filename = (const char *) runtime_progname ();
+ back_state = backtrace_create_state (filename, 1, error_callback, NULL);
+ }
runtime_unlock (&back_state_lock);
return back_state;
}
diff --git a/libgo/runtime/print.c b/libgo/runtime/print.c
index c24304e24..5a8e47e53 100644
--- a/libgo/runtime/print.c
+++ b/libgo/runtime/print.c
@@ -20,10 +20,10 @@ gwrite(const void *v, int32 n)
runtime_write(2, v, n);
return;
}
-
+
if(g->writenbuf == 0)
return;
-
+
if(n > g->writenbuf)
n = g->writenbuf;
runtime_memmove(g->writebuf, v, n);
diff --git a/libgo/runtime/runtime.c b/libgo/runtime/runtime.c
index 72875fd53..861159657 100644
--- a/libgo/runtime/runtime.c
+++ b/libgo/runtime/runtime.c
@@ -106,11 +106,21 @@ static byte** argv;
extern Slice os_Args asm ("os.Args");
extern Slice syscall_Envs asm ("syscall.Envs");
+void (*runtime_sysargs)(int32, uint8**);
+
void
runtime_args(int32 c, byte **v)
{
argc = c;
argv = v;
+ if(runtime_sysargs != nil)
+ runtime_sysargs(c, v);
+}
+
+byte*
+runtime_progname()
+{
+ return argc == 0 ? nil : argv[0];
}
void
@@ -234,7 +244,7 @@ runtime_showframe(const unsigned char *s)
if(traceback < 0)
traceback = runtime_gotraceback();
- return traceback > 1 || (__builtin_strchr((const char*)s, '.') != nil && __builtin_memcmp(s, "runtime.", 7) != 0);
+ return traceback > 1 || (s != nil && __builtin_strchr((const char*)s, '.') != nil && __builtin_memcmp(s, "runtime.", 7) != 0);
}
bool
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index f96d740fb..74050da9e 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -520,5 +520,6 @@ extern uintptr runtime_stacks_sys;
struct backtrace_state;
extern struct backtrace_state *__go_get_backtrace_state(void);
extern _Bool __go_file_line(uintptr, String*, String*, int *);
+extern byte* runtime_progname();
int32 getproccount(void);
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index ee148b5cd..d62247987 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,9 @@
+2012-10-02 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/x86/target.h (struct gtm_jmpbuf): Merge x86_64
+ and ia32 declarations some more.
+ * config/x86/sjlj.S (_ITM_beginTransaction): Move ret to common code.
+
2012-09-20 Jakub Jelinek <jakub@redhat.com>
PR other/43620
diff --git a/libitm/config/x86/sjlj.S b/libitm/config/x86/sjlj.S
index 884422882..4d733f4c2 100644
--- a/libitm/config/x86/sjlj.S
+++ b/libitm/config/x86/sjlj.S
@@ -74,7 +74,6 @@ SYM(_ITM_beginTransaction):
call SYM(GTM_begin_transaction)
addq $56, %rsp
cfi_def_cfa_offset(8)
- ret
#else
leal 4(%esp), %ecx
movl 4(%esp), %eax
@@ -99,8 +98,8 @@ SYM(_ITM_beginTransaction):
#endif
addl $28, %esp
cfi_def_cfa_offset(4)
- ret
#endif
+ ret
cfi_endproc
TYPE(_ITM_beginTransaction)
diff --git a/libitm/config/x86/target.h b/libitm/config/x86/target.h
index 73b6585ae..74f4f92cf 100644
--- a/libitm/config/x86/target.h
+++ b/libitm/config/x86/target.h
@@ -24,11 +24,11 @@
namespace GTM HIDDEN {
-#ifdef __x86_64__
/* ??? This doesn't work for Win64. */
typedef struct gtm_jmpbuf
{
void *cfa;
+#ifdef __x86_64__
unsigned long long rbx;
unsigned long long rbp;
unsigned long long r12;
@@ -36,18 +36,14 @@ typedef struct gtm_jmpbuf
unsigned long long r14;
unsigned long long r15;
unsigned long long rip;
-} gtm_jmpbuf;
#else
-typedef struct gtm_jmpbuf
-{
- void *cfa;
unsigned long ebx;
unsigned long esi;
unsigned long edi;
unsigned long ebp;
unsigned long eip;
-} gtm_jmpbuf;
#endif
+} gtm_jmpbuf;
/* x86 doesn't require strict alignment for the basic types. */
#define STRICT_ALIGNMENT 0
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 33a46cc3c..998e42924 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,111 @@
+2012-10-07 Matthias Klose <doko@ubuntu.com>
+
+ * testsuite/28_regex/algorithms/match/basic: Remove empty directory.
+ * testsuite/28_regex/algorithms/match/extended: Likewise.
+ * testsuite/28_regex/algorithms/match: Likewise.
+
+2012-10-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/52764
+ * include/c_global/cstdint: Remove __STDC_LIMIT_MACROS and
+ __STDC_CONSTANT_MACROS related macros.
+
+2012-10-06 Joe Seymour <jseymour@codesourcery.com>
+
+ * include/tr2/dynamic_bitset: Fix cxxabi_forced.h include path.
+
+2012-10-05 Benjamin Kosnik <bkoz@redhat.com>
+
+ * testsuite/28_regex/algorithms/match: Rename to...
+ * testsuite/28_regex/algorithms/regex_match: ...this.
+ * testsuite/28_regex/basic_regex/regex.cc: Rename to...
+ * testsuite/28_regex/basic_regex/ctors/basic/default.cc: ...this.
+ * testsuite/util/testsuite_regex.h: New.
+ * testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc: New.
+
+2012-10-05 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/20_util/shared_ptr/cons/43820_neg.cc: Adjust line
+ numbers.
+
+2012-10-05 Marc Glisse <marc.glisse@inria.fr>
+
+ PR libstdc++/54686
+ * include/c_global/cstdlib (abs(long long)): Define with
+ __builtin_llabs when we have long long.
+ (abs(long)): Use __builtin_labs.
+ (abs(__int128)): Define when we have __int128.
+
+2012-10-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/c_global/cstdlib: Remove redundant pasto code protected
+ by __GXX_EXPERIMENTAL_CXX0X__.
+ * include/c_global/cwctype: Likewise.
+ * include/c_global/ccomplex: Remove uses of obsolete macro
+ _GLIBCXX_INCLUDE_AS_TR1.
+ * include/c_global/cfloat: Likewise.
+
+2012-10-05 Marc Glisse <marc.glisse@inria.fr>
+
+ PR libstdc++/54686
+ * include/c_std/cstdlib (abs(long long)): Define with
+ __builtin_llabs when we have long long.
+ (abs(long)): Use __builtin_labs.
+ (abs(__int128)): Define when we have __int128.
+ * testsuite/26_numerics/headers/cstdlib/54686.c: New file.
+
+2012-10-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/53248
+ * include/std/array (__array_traits<>): Add.
+ (array<>): Allow for zero-size arrays of non default-constructible
+ elements.
+ * testsuite/23_containers/array/requirements/
+ non_default_constructible.cc: New.
+ * testsuite/23_containers/array/requirements/zero_sized_arrays.cc:
+ Adjust.
+ * testsuite/23_containers/array/tuple_interface/get_neg.cc: Adjust
+ dg-error line numbers.
+ * testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc:
+ Likewise.
+
+2012-10-02 Jonathan Wakely <jwakely.gcc@gmail.com>
+
+ PR other/53889
+ * include/std/mutex (__recursive_mutex_base::~__recursive_mutex_base):
+ Use __gthread_recursive_mutex_destroy.
+ (__recursive_mutex_base::_S_destroy): Remove.
+ (__recursive_mutex_base::_S_destroy_win32): Likewise.
+ * include/ext/concurrence.h (__recursive_mutex::~__recursive_mutex):
+ Use __gthread_recursive_mutex_destroy.
+ (__recursive_mutex::_S_destroy): Remove.
+ (__recursive_mutex::_S_destroy_win32): Likewise.
+
+2012-10-01 Benjamin Kosnik <bkoz@redhat.com>
+
+ * config/abi/pre/gnu-versioned-namespace.ver: Add more
+ typeinfo/vtable exports.
+
+2012-10-01 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/54757
+ * include/ext/random (rice_distribution<>::operator()): Use std::hypot
+ only if _GLIBCXX_USE_C99_MATH_TR1.
+ * include/ext/random.tcc (rice_distribution<>::__generate_impl):
+ Likewise.
+
+2012-10-01 Daniel Krugler <daniel.kruegler@googlemail.com>
+
+ * include/std/type_traits (result_of): Provide "SFINAE-friendly"
+ (see N3436) implementation.
+ * testsuite/20_util/result_of/sfinae_friendly_1.cc: New.
+ * testsuite/20_util/result_of/sfinae_friendly_2.cc: Likewise.
+ * testsuite/20_util/make_signed/requirements/typedefs_neg.cc: Tweak
+ dg-error line numbers.
+ * testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc:
+ Likewise.
+ * testsuite/20_util/declval/requirements/1_neg.cc: Likewise.
+
2012-09-30 Benjamin Kosnik <bkoz@redhat.com>
* doc/doxygen/user.cfg.in: Update to doxygen 1.8.2.
diff --git a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
index 5f253743c..84210e4ec 100644
--- a/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
+++ b/libstdc++-v3/config/abi/pre/gnu-versioned-namespace.ver
@@ -62,15 +62,18 @@ GLIBCXX_7.0 {
_ZTTNSt*;
# vtable
+ _ZTVSt*;
_ZTVNSt*;
# thunk
_ZTv0_n24_NS*;
# typeinfo structure
+ _ZTISt*;
_ZTINSt*;
# typeinfo name
+ _ZTSSt*;
_ZTSNSt*;
# locale
diff --git a/libstdc++-v3/include/c_global/ccomplex b/libstdc++-v3/include/c_global/ccomplex
index b1117e8d4..0109ec10e 100644
--- a/libstdc++-v3/include/c_global/ccomplex
+++ b/libstdc++-v3/include/c_global/ccomplex
@@ -1,6 +1,6 @@
// <ccomplex> -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2007-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -35,10 +35,6 @@
# include <bits/c++0x_warning.h>
#endif
-#if defined(_GLIBCXX_INCLUDE_AS_TR1)
-# error C++0x header cannot be included from TR1 header
-#endif
-
#include <complex>
#endif
diff --git a/libstdc++-v3/include/c_global/cfloat b/libstdc++-v3/include/c_global/cfloat
index 1be81d34d..2bc7883bf 100644
--- a/libstdc++-v3/include/c_global/cfloat
+++ b/libstdc++-v3/include/c_global/cfloat
@@ -1,8 +1,6 @@
// -*- C++ -*- forwarding header.
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 1997-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -46,9 +44,6 @@
#define _GLIBCXX_CFLOAT 1
#ifdef __GXX_EXPERIMENTAL_CXX0X__
-# if defined(_GLIBCXX_INCLUDE_AS_TR1)
-# error C++0x header cannot be included from TR1 header
-# endif
# ifndef DECIMAL_DIG
# define DECIMAL_DIG __DECIMAL_DIG__
# endif
diff --git a/libstdc++-v3/include/c_global/cstdint b/libstdc++-v3/include/c_global/cstdint
index ce8143ea2..5ebee3bd7 100644
--- a/libstdc++-v3/include/c_global/cstdint
+++ b/libstdc++-v3/include/c_global/cstdint
@@ -1,6 +1,6 @@
// <cstdint> -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright (C) 2007-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -37,25 +37,8 @@
#include <bits/c++config.h>
-// For 8.22.1/1 (see C99, Notes 219, 220, 222)
#if _GLIBCXX_HAVE_STDINT_H
-# ifndef __STDC_LIMIT_MACROS
-# define _UNDEF__STDC_LIMIT_MACROS
-# define __STDC_LIMIT_MACROS
-# endif
-# ifndef __STDC_CONSTANT_MACROS
-# define _UNDEF__STDC_CONSTANT_MACROS
-# define __STDC_CONSTANT_MACROS
-# endif
# include <stdint.h>
-# ifdef _UNDEF__STDC_LIMIT_MACROS
-# undef __STDC_LIMIT_MACROS
-# undef _UNDEF__STDC_LIMIT_MACROS
-# endif
-# ifdef _UNDEF__STDC_CONSTANT_MACROS
-# undef __STDC_CONSTANT_MACROS
-# undef _UNDEF__STDC_CONSTANT_MACROS
-# endif
#endif
#ifdef _GLIBCXX_USE_C99_STDINT_TR1
diff --git a/libstdc++-v3/include/c_global/cstdlib b/libstdc++-v3/include/c_global/cstdlib
index f4785b4ad..729a639c6 100644
--- a/libstdc++-v3/include/c_global/cstdlib
+++ b/libstdc++-v3/include/c_global/cstdlib
@@ -1,8 +1,6 @@
// -*- C++ -*- forwarding header.
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009, 2010, 2011
-// Free Software Foundation, Inc.
+// Copyright (C) 1997-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -137,12 +135,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#ifndef __CORRECT_ISO_CPP_STDLIB_H_PROTO
inline long
- abs(long __i) { return labs(__i); }
+ abs(long __i) { return __builtin_labs(__i); }
inline ldiv_t
div(long __i, long __j) { return ldiv(__i, __j); }
#endif
+#ifdef _GLIBCXX_USE_LONG_LONG
+ inline long long
+ abs(long long __x) { return __builtin_llabs (__x); }
+#endif
+
+#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
+ inline __int128
+ abs(__int128 __x) { return __x >= 0 ? __x : -__x; }
+#endif
+
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
@@ -171,9 +179,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using ::_Exit;
#endif
- inline long long
- abs(long long __x) { return __x >= 0 ? __x : -__x; }
-
#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
using ::llabs;
@@ -208,7 +213,6 @@ namespace std
using ::__gnu_cxx::lldiv_t;
#endif
using ::__gnu_cxx::_Exit;
- using ::__gnu_cxx::abs;
#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
using ::__gnu_cxx::llabs;
using ::__gnu_cxx::div;
@@ -221,35 +225,6 @@ namespace std
using ::__gnu_cxx::strtold;
} // namespace std
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
-
-namespace std
-{
-#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
- // types
- using std::lldiv_t;
-
- // functions
- using std::llabs;
- using std::lldiv;
-#endif
-
- using std::atoll;
- using std::strtoll;
- using std::strtoull;
-
- using std::strtof;
- using std::strtold;
-
- // overloads
- using std::abs;
-#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
- using std::div;
-#endif
-} // namespace std
-
-#endif // __GXX_EXPERIMENTAL_CXX0X__
-
#endif // _GLIBCXX_USE_C99
#endif // !_GLIBCXX_HOSTED
diff --git a/libstdc++-v3/include/c_global/cwctype b/libstdc++-v3/include/c_global/cwctype
index e417b6874..52fb440b2 100644
--- a/libstdc++-v3/include/c_global/cwctype
+++ b/libstdc++-v3/include/c_global/cwctype
@@ -1,8 +1,6 @@
// -*- C++ -*- forwarding header.
-// Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-// 2006, 2007, 2008, 2009, 2010
-// Free Software Foundation, Inc.
+// Copyright (C) 1997-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -109,19 +107,4 @@ namespace std
#endif //_GLIBCXX_USE_WCHAR_T
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
-
-#ifdef _GLIBCXX_USE_WCHAR_T
-
-namespace std
-{
-#if _GLIBCXX_HAVE_ISWBLANK
- using std::iswblank;
-#endif
-} // namespace
-
-#endif // _GLIBCXX_USE_WCHAR_T
-
-#endif // __GXX_EXPERIMENTAL_CXX0X__
-
#endif // _GLIBCXX_CWCTYPE
diff --git a/libstdc++-v3/include/c_std/cstdlib b/libstdc++-v3/include/c_std/cstdlib
index c3fe8aa45..345920b76 100644
--- a/libstdc++-v3/include/c_std/cstdlib
+++ b/libstdc++-v3/include/c_std/cstdlib
@@ -135,7 +135,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif // _GLIBCXX_USE_WCHAR_T
inline long
- abs(long __i) { return labs(__i); }
+ abs(long __i) { return __builtin_labs(__i); }
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+ inline long long
+ abs(long long __x) { return __builtin_llabs (__x); }
+#endif
+
+#if !defined(__STRICT_ANSI__) && defined(_GLIBCXX_USE_INT128)
+ inline __int128
+ abs(__int128 __x) { return __x >= 0 ? __x : -__x; }
+#endif
inline ldiv_t
div(long __i, long __j) { return ldiv(__i, __j); }
@@ -168,9 +178,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using ::_Exit;
#endif
- inline long long
- abs(long long __x) { return __x >= 0 ? __x : -__x; }
-
#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
using ::llabs;
@@ -205,7 +212,6 @@ namespace std
using ::__gnu_cxx::lldiv_t;
#endif
using ::__gnu_cxx::_Exit;
- using ::__gnu_cxx::abs;
#if !_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC
using ::__gnu_cxx::llabs;
using ::__gnu_cxx::div;
diff --git a/libstdc++-v3/include/ext/concurrence.h b/libstdc++-v3/include/ext/concurrence.h
index ad028398b..68c679c6b 100644
--- a/libstdc++-v3/include/ext/concurrence.h
+++ b/libstdc++-v3/include/ext/concurrence.h
@@ -219,7 +219,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
~__recursive_mutex()
{
if (__gthread_active_p())
- _S_destroy(&_M_mutex);
+ __gthread_recursive_mutex_destroy(&_M_mutex);
}
#endif
@@ -247,43 +247,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__gthread_recursive_mutex_t* gthread_recursive_mutex(void)
{ return &_M_mutex; }
-
-#if __GTHREADS && ! defined __GTHREAD_RECURSIVE_MUTEX_INIT
- // FIXME: gthreads doesn't define __gthread_recursive_mutex_destroy
- // so we need to obtain a __gthread_mutex_t to destroy
- private:
- template<typename _Mx, typename _Rm>
- static void
- _S_destroy_win32(_Mx* __mx, _Rm const* __rmx)
- {
- __mx->counter = __rmx->counter;
- __mx->sema = __rmx->sema;
- __gthread_mutex_destroy(__mx);
- }
-
- // matches a gthr-win32.h recursive mutex
- template<typename _Rm>
- static typename __enable_if<(bool)sizeof(&_Rm::sema), void>::__type
- _S_destroy(_Rm* __mx)
- {
- __gthread_mutex_t __tmp;
- _S_destroy_win32(&__tmp, __mx);
- }
-
- // matches a recursive mutex with a member 'actual'
- template<typename _Rm>
- static typename __enable_if<(bool)sizeof(&_Rm::actual), void>::__type
- _S_destroy(_Rm* __mx)
- { __gthread_mutex_destroy(&__mx->actual); }
-
- // matches when there's only one mutex type
- template<typename _Rm>
- static typename
- __enable_if<std::__are_same<_Rm, __gthread_mutex_t>::__value,
- void>::__type
- _S_destroy(_Rm* __mx)
- { __gthread_mutex_destroy(__mx); }
-#endif
};
/// Scoped lock idiom.
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
index 884e8a0ca..8c40d6d42 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -1042,7 +1042,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
result_type __x = this->_M_ndx(__urng);
result_type __y = this->_M_ndy(__urng);
+#if _GLIBCXX_USE_C99_MATH_TR1
return std::hypot(__x, __y);
+#else
+ return std::sqrt(__x * __x + __y * __y);
+#endif
}
template<typename _UniformRandomNumberGenerator>
@@ -1054,7 +1058,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma());
result_type __x = this->_M_ndx(__px, __urng);
result_type __y = this->_M_ndy(__py, __urng);
+#if _GLIBCXX_USE_C99_MATH_TR1
return std::hypot(__x, __y);
+#else
+ return std::sqrt(__x * __x + __y * __y);
+#endif
}
template<typename _ForwardIterator,
diff --git a/libstdc++-v3/include/ext/random.tcc b/libstdc++-v3/include/ext/random.tcc
index 86bb67fed..4151daff8 100644
--- a/libstdc++-v3/include/ext/random.tcc
+++ b/libstdc++-v3/include/ext/random.tcc
@@ -732,7 +732,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__px(__p.nu(), __p.sigma()), __py(result_type(0), __p.sigma());
result_type __x = this->_M_ndx(__px, __urng);
result_type __y = this->_M_ndy(__py, __urng);
+#if _GLIBCXX_USE_C99_MATH_TR1
*__f++ = std::hypot(__x, __y);
+#else
+ *__f++ = std::sqrt(__x * __x + __y * __y);
+#endif
}
}
diff --git a/libstdc++-v3/include/std/array b/libstdc++-v3/include/std/array
index 4ee21998b..c7c0a5ae8 100644
--- a/libstdc++-v3/include/std/array
+++ b/libstdc++-v3/include/std/array
@@ -1,7 +1,6 @@
// <array> -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
-// Free Software Foundation, Inc.
+// Copyright (C) 2007-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -44,6 +43,26 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ template<typename _Tp, std::size_t _Nm>
+ struct __array_traits
+ {
+ typedef _Tp _Type[_Nm];
+
+ static constexpr _Tp&
+ _S_ref(const _Type& __t, std::size_t __n) noexcept
+ { return const_cast<_Tp&>(__t[__n]); }
+ };
+
+ template<typename _Tp>
+ struct __array_traits<_Tp, 0>
+ {
+ struct _Type { };
+
+ static constexpr _Tp&
+ _S_ref(const _Type&, std::size_t) noexcept
+ { return *static_cast<_Tp*>(nullptr); }
+ };
+
/**
* @brief A standard container for storing a fixed size sequence of elements.
*
@@ -74,7 +93,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
// Support for zero-sized arrays mandatory.
- value_type _M_instance[_Nm ? _Nm : 1];
+ typedef std::__array_traits<_Tp, _Nm> _AT_Type;
+ typename _AT_Type::_Type _M_elems;
// No explicit construct/copy/destroy for aggregate type.
@@ -123,11 +143,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const_iterator
cbegin() const noexcept
- { return const_iterator(std::__addressof(_M_instance[0])); }
+ { return const_iterator(data()); }
const_iterator
cend() const noexcept
- { return const_iterator(std::__addressof(_M_instance[_Nm])); }
+ { return const_iterator(data() + _Nm); }
const_reverse_iterator
crbegin() const noexcept
@@ -150,18 +170,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Element access.
reference
operator[](size_type __n)
- { return _M_instance[__n]; }
+ { return _AT_Type::_S_ref(_M_elems, __n); }
constexpr const_reference
operator[](size_type __n) const noexcept
- { return _M_instance[__n]; }
+ { return _AT_Type::_S_ref(_M_elems, __n); }
reference
at(size_type __n)
{
if (__n >= _Nm)
std::__throw_out_of_range(__N("array::at"));
- return _M_instance[__n];
+ return _AT_Type::_S_ref(_M_elems, __n);
}
constexpr const_reference
@@ -169,8 +189,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
// Result of conditional expression must be an lvalue so use
// boolean ? lvalue : (throw-expr, lvalue)
- return __n < _Nm ? _M_instance[__n]
- : (std::__throw_out_of_range(__N("array::at")), _M_instance[0]);
+ return __n < _Nm ? _AT_Type::_S_ref(_M_elems, __n)
+ : (std::__throw_out_of_range(__N("array::at")),
+ _AT_Type::_S_ref(_M_elems, 0));
}
reference
@@ -191,11 +212,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
pointer
data() noexcept
- { return std::__addressof(_M_instance[0]); }
+ { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
const_pointer
data() const noexcept
- { return std::__addressof(_M_instance[0]); }
+ { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); }
};
// Array comparisons.
@@ -265,7 +286,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
get(array<_Tp, _Nm>& __arr) noexcept
{
static_assert(_Int < _Nm, "index is out of bounds");
- return __arr._M_instance[_Int];
+ return std::__array_traits<_Tp, _Nm>::_S_ref(__arr._M_elems, _Int);
}
template<std::size_t _Int, typename _Tp, std::size_t _Nm>
@@ -281,7 +302,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
get(const array<_Tp, _Nm>& __arr) noexcept
{
static_assert(_Int < _Nm, "index is out of bounds");
- return __arr._M_instance[_Int];
+ return std::__array_traits<_Tp, _Nm>::_S_ref(__arr._M_elems, _Int);
}
_GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index 34d64c5b6..77faf739c 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -1,7 +1,6 @@
// <mutex> -*- C++ -*-
-// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-// Free Software Foundation, Inc.
+// Copyright (C) 2003-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -101,42 +100,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
~__recursive_mutex_base()
- { _S_destroy(&_M_mutex); }
-
- private:
- // FIXME: gthreads doesn't define __gthread_recursive_mutex_destroy
- // so we need to obtain a __gthread_mutex_t to destroy
-
- // matches when there's only one mutex type
- template<typename _Rm>
- static
- typename enable_if<is_same<_Rm, __gthread_mutex_t>::value, void>::type
- _S_destroy(_Rm* __mx)
- { __gthread_mutex_destroy(__mx); }
-
- // matches a recursive mutex with a member 'actual'
- template<typename _Rm>
- static typename enable_if<(bool)sizeof(&_Rm::actual), void>::type
- _S_destroy(_Rm* __mx)
- { __gthread_mutex_destroy(&__mx->actual); }
-
- // matches a gthr-win32.h recursive mutex
- template<typename _Rm>
- static typename enable_if<(bool)sizeof(&_Rm::sema), void>::type
- _S_destroy(_Rm* __mx)
- {
- __gthread_mutex_t __tmp;
- _S_destroy_win32(&__tmp, __mx);
- }
-
- template<typename _Mx, typename _Rm>
- static void
- _S_destroy_win32(_Mx* __mx, _Rm const* __rmx)
- {
- __mx->counter = __rmx->counter;
- __mx->sema = __rmx->sema;
- __gthread_mutex_destroy(__mx);
- }
+ { __gthread_recursive_mutex_destroy(&_M_mutex); }
#endif
};
diff --git a/libstdc++-v3/include/std/type_traits b/libstdc++-v3/include/std/type_traits
index 9232af793..e8d432c45 100644
--- a/libstdc++-v3/include/std/type_traits
+++ b/libstdc++-v3/include/std/type_traits
@@ -1,7 +1,6 @@
// C++11 type_traits -*- C++ -*-
-// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
-// Free Software Foundation, Inc.
+// Copyright (C) 2007-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -1819,89 +1818,171 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Signature>
class result_of;
+ // sfinae-friendly result_of implementation. We use enable_if to transport
+ // both the result information (as the member type) and the failure
+ // information (no member type).
+
+ template<typename _Tp>
+ using __success_type = enable_if<true, _Tp>;
+
+ using __failure_type = enable_if<false>;
+
+ // [func.require] paragraph 1 bullet 1:
+ struct __result_of_memfun_ref_impl
+ {
+ template<typename _Fp, typename _Tp1, typename... _Args>
+ static __success_type<decltype(
+ (std::declval<_Tp1>().*std::declval<_Fp>())(std::declval<_Args>()...)
+ )> _S_test(int);
+
+ template<typename...>
+ static __failure_type _S_test(...);
+ };
+
+ template<typename _MemPtr, typename _Arg, typename... _Args>
+ struct __result_of_memfun_ref
+ : private __result_of_memfun_ref_impl
+ {
+ typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type;
+ };
+
+ // [func.require] paragraph 1 bullet 2:
+ struct __result_of_memfun_deref_impl
+ {
+ template<typename _Fp, typename _Tp1, typename... _Args>
+ static __success_type<decltype(
+ ((*std::declval<_Tp1>()).*std::declval<_Fp>())(std::declval<_Args>()...)
+ )> _S_test(int);
+
+ template<typename...>
+ static __failure_type _S_test(...);
+ };
+
+ template<typename _MemPtr, typename _Arg, typename... _Args>
+ struct __result_of_memfun_deref
+ : private __result_of_memfun_deref_impl
+ {
+ typedef decltype(_S_test<_MemPtr, _Arg, _Args...>(0)) type;
+ };
+
+ // [func.require] paragraph 1 bullet 3:
+ struct __result_of_memobj_ref_impl
+ {
+ template<typename _Fp, typename _Tp1>
+ static __success_type<decltype(
+ std::declval<_Tp1>().*std::declval<_Fp>()
+ )> _S_test(int);
+
+ template<typename, typename>
+ static __failure_type _S_test(...);
+ };
+
+ template<typename _MemPtr, typename _Arg>
+ struct __result_of_memobj_ref
+ : private __result_of_memobj_ref_impl
+ {
+ typedef decltype(_S_test<_MemPtr, _Arg>(0)) type;
+ };
+
+ // [func.require] paragraph 1 bullet 4:
+ struct __result_of_memobj_deref_impl
+ {
+ template<typename _Fp, typename _Tp1>
+ static __success_type<decltype(
+ (*std::declval<_Tp1>()).*std::declval<_Fp>()
+ )> _S_test(int);
+
+ template<typename, typename>
+ static __failure_type _S_test(...);
+ };
+
template<typename _MemPtr, typename _Arg>
- struct _Result_of_memobj;
+ struct __result_of_memobj_deref
+ : private __result_of_memobj_deref_impl
+ {
+ typedef decltype(_S_test<_MemPtr, _Arg>(0)) type;
+ };
+
+ template<typename _MemPtr, typename _Arg>
+ struct __result_of_memobj;
template<typename _Res, typename _Class, typename _Arg>
- struct _Result_of_memobj<_Res _Class::*, _Arg>
+ struct __result_of_memobj<_Res _Class::*, _Arg>
{
- private:
- typedef _Res _Class::* _Func;
-
- template<typename _Tp>
- static _Tp _S_get(const _Class&);
- template<typename _Tp>
- static _Tp _S_get(const volatile _Class&);
- template<typename _Tp>
- static decltype(*std::declval<_Tp>()) _S_get(...);
-
- public:
- typedef
- decltype(_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>())
- __type;
+ typedef typename remove_cv<typename remove_reference<
+ _Arg>::type>::type _Argval;
+ typedef _Res _Class::* _MemPtr;
+ typedef typename conditional<__or_<is_same<_Argval, _Class>,
+ is_base_of<_Class, _Argval>>::value,
+ __result_of_memobj_ref<_MemPtr, _Arg>,
+ __result_of_memobj_deref<_MemPtr, _Arg>
+ >::type::type type;
};
- template<typename _MemPtr, typename _Arg, typename... _ArgTypes>
- struct _Result_of_memfun;
+ template<typename _MemPtr, typename _Arg, typename... _Args>
+ struct __result_of_memfun;
template<typename _Res, typename _Class, typename _Arg, typename... _Args>
- struct _Result_of_memfun<_Res _Class::*, _Arg, _Args...>
+ struct __result_of_memfun<_Res _Class::*, _Arg, _Args...>
{
- private:
- typedef _Res _Class::* _Func;
-
- template<typename _Tp>
- static _Tp _S_get(const _Class&);
- template<typename _Tp>
- static _Tp _S_get(const volatile _Class&);
- template<typename _Tp>
- static decltype(*std::declval<_Tp>()) _S_get(...);
-
- public:
- typedef
- decltype((_S_get<_Arg>(std::declval<_Arg>()).*std::declval<_Func>())
- (std::declval<_Args>()...) )
- __type;
+ typedef typename remove_cv<typename remove_reference<
+ _Arg>::type>::type _Argval;
+ typedef _Res _Class::* _MemPtr;
+ typedef typename conditional<__or_<is_same<_Argval, _Class>,
+ is_base_of<_Class, _Argval>>::value,
+ __result_of_memfun_ref<_MemPtr, _Arg, _Args...>,
+ __result_of_memfun_deref<_MemPtr, _Arg, _Args...>
+ >::type::type type;
};
template<bool, bool, typename _Functor, typename... _ArgTypes>
- struct _Result_of_impl;
-
- template<typename _Functor, typename... _ArgTypes>
- struct _Result_of_impl<false, false, _Functor, _ArgTypes...>
+ struct __result_of_impl
{
- typedef
- decltype( std::declval<_Functor>()(std::declval<_ArgTypes>()...) )
- __type;
+ typedef __failure_type type;
};
template<typename _MemPtr, typename _Arg>
- struct _Result_of_impl<true, false, _MemPtr, _Arg>
- : _Result_of_memobj<typename decay<_MemPtr>::type, _Arg>
+ struct __result_of_impl<true, false, _MemPtr, _Arg>
+ : public __result_of_memobj<typename decay<_MemPtr>::type, _Arg>
{ };
- template<typename _MemPtr, typename _Arg, typename... _ArgTypes>
- struct _Result_of_impl<false, true, _MemPtr, _Arg, _ArgTypes...>
- : _Result_of_memfun<typename decay<_MemPtr>::type, _Arg, _ArgTypes...>
+ template<typename _MemPtr, typename _Arg, typename... _Args>
+ struct __result_of_impl<false, true, _MemPtr, _Arg, _Args...>
+ : public __result_of_memfun<typename decay<_MemPtr>::type, _Arg, _Args...>
{ };
+ // [func.require] paragraph 1 bullet 5:
+ struct __result_of_other_impl
+ {
+ template<typename _Fn, typename... _Args>
+ static __success_type<decltype(
+ std::declval<_Fn>()(std::declval<_Args>()...)
+ )> _S_test(int);
+
+ template<typename...>
+ static __failure_type _S_test(...);
+ };
+
template<typename _Functor, typename... _ArgTypes>
- struct result_of<_Functor(_ArgTypes...)>
- : _Result_of_impl<is_member_object_pointer<
- typename remove_reference<_Functor>::type >::value,
- is_member_function_pointer<
- typename remove_reference<_Functor>::type >::value,
- _Functor, _ArgTypes...>
+ struct __result_of_impl<false, false, _Functor, _ArgTypes...>
+ : private __result_of_other_impl
{
- typedef typename _Result_of_impl<
- is_member_object_pointer<
- typename remove_reference<_Functor>::type >::value,
- is_member_function_pointer<
- typename remove_reference<_Functor>::type >::value,
- _Functor, _ArgTypes...>::__type
- type;
+ typedef decltype(_S_test<_Functor, _ArgTypes...>(0)) type;
};
+ template<typename _Functor, typename... _ArgTypes>
+ struct result_of<_Functor(_ArgTypes...)>
+ : public __result_of_impl<
+ is_member_object_pointer<
+ typename remove_reference<_Functor>::type
+ >::value,
+ is_member_function_pointer<
+ typename remove_reference<_Functor>::type
+ >::value,
+ _Functor, _ArgTypes...
+ >::type
+ { };
+
/**
* Use SFINAE to determine if the type _Tp has a publicly-accessible
* member type _NTYPE.
diff --git a/libstdc++-v3/include/tr2/dynamic_bitset b/libstdc++-v3/include/tr2/dynamic_bitset
index 5ca56470b..53b696f0e 100644
--- a/libstdc++-v3/include/tr2/dynamic_bitset
+++ b/libstdc++-v3/include/tr2/dynamic_bitset
@@ -1,6 +1,6 @@
// TR2 <dynamic_bitset> -*- C++ -*-
-// Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -39,7 +39,7 @@
#include <bits/functexcept.h> // For invalid_argument, out_of_range,
// overflow_error
#include <iosfwd>
-#include <cxxabi_forced.h>
+#include <bits/cxxabi_forced.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
index 2b6757efd..6b9a4cb95 100644
--- a/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/declval/requirements/1_neg.cc
@@ -2,7 +2,7 @@
// { dg-do compile }
// 2009-11-12 Paolo Carlini <paolo.carlini@oracle.com>
//
-// Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
+// Copyright (C) 2009-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -19,7 +19,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "static assertion failed" "" { target *-*-* } 1813 }
+// { dg-error "static assertion failed" "" { target *-*-* } 1812 }
#include <utility>
diff --git a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
index 1c68fac6b..3f1d33ba9 100644
--- a/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/make_signed/requirements/typedefs_neg.cc
@@ -3,8 +3,7 @@
// 2007-05-03 Benjamin Kosnik <bkoz@redhat.com>
//
-// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
-// Free Software Foundation, Inc.
+// Copyright (C) 2007-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -43,11 +42,11 @@ void test01()
typedef make_signed<float>::type test5_type;
}
-// { dg-error "does not name a type" "" { target *-*-* } 34 }
-// { dg-error "required from here" "" { target *-*-* } 36 }
-// { dg-error "required from here" "" { target *-*-* } 38 }
-// { dg-error "required from here" "" { target *-*-* } 41 }
-// { dg-error "required from here" "" { target *-*-* } 43 }
+// { dg-error "does not name a type" "" { target *-*-* } 33 }
+// { dg-error "required from here" "" { target *-*-* } 35 }
+// { dg-error "required from here" "" { target *-*-* } 37 }
+// { dg-error "required from here" "" { target *-*-* } 40 }
+// { dg-error "required from here" "" { target *-*-* } 42 }
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1602 }
-// { dg-error "declaration of" "" { target *-*-* } 1566 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1601 }
+// { dg-error "declaration of" "" { target *-*-* } 1565 }
diff --git a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc
index a41e5e61a..b13200e06 100644
--- a/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/make_unsigned/requirements/typedefs_neg.cc
@@ -3,8 +3,7 @@
// 2007-05-03 Benjamin Kosnik <bkoz@redhat.com>
//
-// Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012
-// Free Software Foundation, Inc.
+// Copyright (C) 2007-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -43,11 +42,11 @@ void test01()
typedef make_unsigned<float>::type test5_type;
}
-// { dg-error "does not name a type" "" { target *-*-* } 34 }
-// { dg-error "required from here" "" { target *-*-* } 36 }
-// { dg-error "required from here" "" { target *-*-* } 38 }
-// { dg-error "required from here" "" { target *-*-* } 41 }
-// { dg-error "required from here" "" { target *-*-* } 43 }
+// { dg-error "does not name a type" "" { target *-*-* } 33 }
+// { dg-error "required from here" "" { target *-*-* } 35 }
+// { dg-error "required from here" "" { target *-*-* } 37 }
+// { dg-error "required from here" "" { target *-*-* } 40 }
+// { dg-error "required from here" "" { target *-*-* } 42 }
-// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1520 }
-// { dg-error "declaration of" "" { target *-*-* } 1484 }
+// { dg-error "invalid use of incomplete type" "" { target *-*-* } 1519 }
+// { dg-error "declaration of" "" { target *-*-* } 1483 }
diff --git a/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc b/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc
new file mode 100644
index 000000000..3ea9e6007
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_1.cc
@@ -0,0 +1,736 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <memory>
+#include <cstddef>
+#include <type_traits>
+
+// TODO: Uncomment the following define once gcc has fixed bug 52748
+// (incomplete types in function call expressions):
+//#define HAS_52748_FIXED
+
+// Helper types:
+struct has_type_impl
+{
+ template<class T, class = typename T::type>
+ static std::true_type test(int);
+
+ template<class>
+ static std::false_type test(...);
+};
+
+template<class T>
+struct has_type : decltype(has_type_impl::test<T>(0))
+{};
+
+template<class T, class Res>
+struct is_expected_type : std::is_same<typename T::type, Res>
+{};
+
+template<class T, class Res>
+struct is_type : std::__and_<has_type<T>, is_expected_type<T, Res>>
+{};
+
+// Types under inspection:
+
+typedef bool (&PF1)();
+typedef short (*PF2)(long);
+
+struct S {
+ operator PF2() const;
+ double operator()(char, int&);
+ void calc(long) const;
+};
+
+typedef void (S::*PMS)(long) const;
+typedef void (S::*PMSnonconst)(long);
+
+typedef int S::* PMI;
+
+struct B {
+ int i;
+ void f1() const;
+ bool f2(int) const volatile;
+};
+
+struct D : B {};
+
+typedef void (B::*base_func_void)() const;
+typedef bool (B::*base_func_bool_int)(int) const volatile;
+
+struct ident_functor {
+ template<class T>
+ T operator()(T&& x);
+};
+
+template<class Ret = void>
+struct variable_functor {
+ template<class... T>
+ Ret operator()(T&&...);
+};
+
+struct ident_functor_noref {
+ template<class T>
+ typename std::remove_reference<T>::type operator()(T&& x);
+};
+
+enum class ScEn;
+
+enum UnScEn : int;
+
+union U {
+ int i;
+ double d;
+};
+
+union U2 {
+ int i;
+ bool b;
+ void operator()() const;
+ int operator()(double) const;
+ bool operator()(double);
+ U operator()(int, int);
+};
+
+struct Ukn;
+
+typedef Ukn (S::*PMSIncomplete)(long) const;
+typedef Ukn (S::*PMSIncompletenonconst)(long);
+typedef Ukn (*FuncIncomplete)(long);
+
+struct Abstract {
+ virtual ~Abstract() = 0;
+};
+
+struct Private {
+private:
+ void operator()();
+ int operator()(int);
+public:
+ bool operator()(std::nullptr_t);
+};
+
+union PrivateUnion {
+ double d;
+private:
+ void operator()();
+ int operator()(int);
+public:
+ bool operator()(std::nullptr_t);
+};
+
+template<class T>
+struct ImplicitTo {
+ operator T();
+};
+
+template<class>
+struct never { static const bool value = false; };
+
+template<class T>
+struct BrokenTrait {
+ static_assert(never<T>::value, "Error!");
+ typedef T type;
+};
+
+template<class T>
+struct BadSmartPtr : T {
+ T& operator*() const noexcept(typename BrokenTrait<T>::type());
+};
+
+template<class Ret>
+using FuncEllipses = Ret(...);
+
+static_assert(is_type<std::result_of<S(int)>, short>::value, "Error!");
+static_assert(is_type<std::result_of<S&(unsigned char, int&)>,
+ double>::value, "Error!");
+static_assert(is_type<std::result_of<PF1()>, bool>::value, "Error!");
+static_assert(is_type<std::result_of<PF1&()>, bool>::value, "Error!");
+static_assert(is_type<std::result_of<PMS(std::unique_ptr<S>, int)>,
+ void>::value, "Error!");
+static_assert(is_type<std::result_of<PMS(std::unique_ptr<S>&, unsigned&)>,
+ void>::value, "Error!");
+static_assert(is_type<std::result_of<PMS&(std::unique_ptr<S>, int)>,
+ void>::value, "Error!");
+static_assert(is_type<std::result_of<PMS&(std::unique_ptr<S>&, unsigned&)>,
+ void>::value, "Error!");
+
+static_assert(is_type<std::result_of<ident_functor(int)>,
+ int>::value, "Error!");
+static_assert(is_type<std::result_of<ident_functor(const int)>,
+ int>::value, "Error!");
+static_assert(is_type<std::result_of<ident_functor(const int&&)>,
+ int>::value, "Error!");
+static_assert(is_type<std::result_of<ident_functor(int&&)>,
+ int>::value, "Error!");
+static_assert(is_type<std::result_of<ident_functor(int&)>,
+ int&>::value, "Error!");
+
+static_assert(is_type<std::result_of<ident_functor(const B)>,
+ B>::value, "Error!");
+static_assert(is_type<std::result_of<ident_functor(const B&&)>,
+ const B>::value, "Error!");
+static_assert(is_type<std::result_of<ident_functor(B&&)>, B>::value, "Error!");
+static_assert(is_type<std::result_of<ident_functor(B&)>, B&>::value, "Error!");
+
+static_assert(is_type<std::result_of<int B::*(B&)>, int&>::value, "Error!");
+
+// This is expected as of CWG 616 P/R:
+static_assert(is_type<std::result_of<int B::*(B)>, int&&>::value, "Error!");
+
+static_assert(is_type<std::result_of<volatile int B::*(const B&&)>,
+ const volatile int&&>::value, "Error!");
+static_assert(is_type<std::result_of<const int B::*(volatile B&&)>,
+ const volatile int&&>::value, "Error!");
+
+static_assert(is_type<std::result_of<int B::*(const B&)>,
+ const int&>::value, "Error!");
+static_assert(is_type<std::result_of<volatile int B::*(const B&)>,
+ const volatile int&>::value, "Error!");
+static_assert(is_type<std::result_of<const int B::*(volatile B&)>,
+ const volatile int&>::value, "Error!");
+
+static_assert(is_type<std::result_of<int B::*(B*)>, int&>::value, "Error!");
+static_assert(is_type<std::result_of<int B::*(B*&)>, int&>(), "Error!");
+static_assert(is_type<std::result_of<int B::*(const B*)>,
+ const int&>::value, "Error!");
+static_assert(is_type<std::result_of<int B::*(const B*&)>,
+ const int&>::value, "Error!");
+static_assert(is_type<std::result_of<volatile int B::*(const B*)>,
+ const volatile int&>::value, "Error!");
+static_assert(is_type<std::result_of<const int B::*(volatile B*)>,
+ const volatile int&>::value, "Error!");
+
+static_assert(is_type<std::result_of<base_func_void(const B&)>,
+ void>::value, "Error!");
+static_assert(is_type<std::result_of<base_func_void(const B*)>,
+ void>::value, "Error!");
+static_assert(is_type<std::result_of<base_func_void(B&)>,
+ void>::value, "Error!");
+static_assert(is_type<std::result_of<base_func_void(B*)>,
+ void>::value, "Error!");
+
+static_assert(!has_type<std::result_of<base_func_void(volatile B&)>>::value,
+ "Error!");
+static_assert(!has_type<std::result_of<base_func_void(volatile B*)>>::value,
+ "Error!");
+
+static_assert(is_type<std::result_of<base_func_bool_int(B&, long)>,
+ bool>::value, "Error!");
+static_assert(is_type<std::result_of<base_func_bool_int(B*, long)>,
+ bool>::value, "Error!");
+static_assert(is_type<std::result_of<base_func_bool_int(volatile B&, long)>,
+ bool>::value, "Error!");
+static_assert(is_type<std::result_of<base_func_bool_int(volatile B*, long)>,
+ bool>::value, "Error!");
+
+static_assert(!has_type<std::result_of<int()>>(), "Error!");
+static_assert(!has_type<std::result_of<void()>>(), "Error!");
+static_assert(!has_type<std::result_of<int(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<void(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<PF1(int)>>(), "Error!");
+static_assert(is_type<std::result_of<PF2(long)>, short>(), "Error!");
+static_assert(!has_type<std::result_of<PF2()>>(), "Error!");
+static_assert(!has_type<std::result_of<PF2(B)>>(), "Error!");
+static_assert(!has_type<std::result_of<PF2(ScEn)>>(), "Error!");
+static_assert(is_type<std::result_of<PF2(UnScEn)>, short>(), "Error!");
+static_assert(!has_type<std::result_of<PF2(long, int)>>(), "Error!");
+static_assert(is_type<std::result_of<PMS(std::unique_ptr<S>, int)>, void>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PMS(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMS(int, std::unique_ptr<S>)>>(), "Error!");
+
+// Argument number mismatch:
+static_assert(!has_type<std::result_of<PMS(std::unique_ptr<S>)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMS(std::unique_ptr<S>&)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMS(std::unique_ptr<S>, int, bool)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PMS(std::unique_ptr<S>&, int, bool)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PMS(S)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMS(S&)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMS(S, int, bool)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMS(S&, int, bool)>>(), "Error!");
+
+// Non-convertible arguments:
+static_assert(!has_type<std::result_of<PMS(std::unique_ptr<S>, S)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PMS(std::unique_ptr<S>&, S)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PMS(S, S)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMS(S&, S)>>(), "Error!");
+
+// cv-violations:
+static_assert(!has_type<std::result_of<PMSnonconst(const S&, long)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PMSnonconst(const S&&, long)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PMSnonconst(const S*, long)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PMSnonconst(const S*&, long)>>(),
+ "Error!");
+
+static_assert(is_type<std::result_of<PMI(S*)>, int&>(), "Error!");
+static_assert(is_type<std::result_of<PMI(S&)>, int&>(), "Error!");
+static_assert(is_type<std::result_of<PMI(S&&)>, int&&>(), "Error!");
+static_assert(is_type<std::result_of<PMI(S)>, int&&>(), "Error!");
+
+static_assert(!has_type<std::result_of<PMI()>>(), "Error!");
+
+static_assert(!has_type<std::result_of<PMI(S*, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMI(S&, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMI(S*, int, S, bool)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMI(S&, int, S, bool)>>(), "Error!");
+
+static_assert(!has_type<std::result_of<PMI(B*)>>(), "Error!");
+static_assert(!has_type<std::result_of<PMI(B&)>>(), "Error!");
+
+static_assert(is_type<std::result_of<int U::*(U)>, int&&>(), "Error!");
+static_assert(is_type<std::result_of<int U::*(U&)>, int&>(), "Error!");
+static_assert(is_type<std::result_of<int U::*(const U&)>, const int&>(),
+ "Error!");
+static_assert(is_type<std::result_of
+ <volatile int U::*(const U&)>, const volatile int&>(), "Error!");
+static_assert(is_type<std::result_of
+ <const int U::*(volatile U&)>, const volatile int&>(), "Error!");
+
+static_assert(is_type<std::result_of<int Ukn::*(Ukn*)>, int&>(), "Error!");
+static_assert(is_type<std::result_of<int Ukn::*(Ukn&)>, int&>(), "Error!");
+static_assert(is_type<std::result_of<int Ukn::*(Ukn&&)>, int&&>(), "Error!");
+static_assert(is_type<std::result_of<int Ukn::*(const Ukn*)>, const int&>(),
+ "Error!");
+static_assert(is_type<std::result_of<int Ukn::*(const Ukn&)>, const int&>(),
+ "Error!");
+static_assert(is_type<std::result_of<int Ukn::*(const Ukn&&)>, const int&&>(),
+ "Error!");
+
+typedef void (Ukn::* PUfnMF)();
+typedef void (Ukn::* PUfnConstMF)() const;
+
+static_assert(is_type<std::result_of<PUfnMF(Ukn*)>, void>(), "Error!");
+static_assert(is_type<std::result_of<PUfnMF(Ukn&)>, void>(), "Error!");
+static_assert(is_type<std::result_of<PUfnMF(Ukn&&)>, void>(), "Error!");
+static_assert(is_type<std::result_of<PUfnConstMF(Ukn*)>, void>(), "Error!");
+static_assert(is_type<std::result_of<PUfnConstMF(Ukn&)>, void>(), "Error!");
+static_assert(is_type<std::result_of<PUfnConstMF(Ukn&&)>, void>(), "Error!");
+static_assert(is_type<std::result_of<PUfnConstMF(const Ukn*)>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<PUfnConstMF(const Ukn&)>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<PUfnConstMF(const Ukn&&)>, void>(),
+ "Error!");
+
+static_assert(!has_type<std::result_of<S()>>(), "Error!");
+static_assert(!has_type<std::result_of<S(int, S)>>(), "Error!");
+static_assert(!has_type<std::result_of<S(S)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <S(double, bool, std::nullptr_t, Ukn&)>>(), "Error!");
+
+static_assert(is_type<std::result_of<U2()>, void>(), "Error!");
+static_assert(is_type<std::result_of<const U2&()>, void>(), "Error!");
+static_assert(is_type<std::result_of<U2&()>, void>(), "Error!");
+static_assert(is_type<std::result_of<U2(double)>, bool>(), "Error!");
+static_assert(is_type<std::result_of<const U2&(double)>, int>(), "Error!");
+static_assert(is_type<std::result_of<U2&(double)>, bool>(), "Error!");
+static_assert(is_type<std::result_of<U2(int)>, bool>(), "Error!");
+static_assert(is_type<std::result_of<U2&(int)>, bool>(), "Error!");
+static_assert(is_type<std::result_of<const U2&(int)>, int>(), "Error!");
+static_assert(is_type<std::result_of<U2(int, int)>, U>(), "Error!");
+static_assert(is_type<std::result_of<U2&(int, int)>, U>(), "Error!");
+
+static_assert(!has_type<std::result_of<const U2&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<U2(int, int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<U2&(int, int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const U2&(int, int, int)>>(), "Error!");
+
+static_assert(is_type<std::result_of<ident_functor(int)>, int>(), "Error!");
+static_assert(is_type<std::result_of<ident_functor(const volatile int)>,
+ int>(), "Error!");
+static_assert(is_type<std::result_of<ident_functor(int&)>, int&>(), "Error!");
+static_assert(is_type<std::result_of<ident_functor(const volatile int&)>,
+ const volatile int&>(), "Error!");
+static_assert(is_type<std::result_of<ident_functor(int&&)>, int>(), "Error!");
+static_assert(is_type<std::result_of<ident_functor(const volatile int&&)>,
+ int>(), "Error!");
+static_assert(is_type<std::result_of<ident_functor(Abstract&)>, Abstract&>(),
+ "Error!");
+static_assert(is_type<std::result_of<ident_functor(const volatile Abstract&)>,
+ const volatile Abstract&>(), "Error!");
+
+static_assert(!has_type<std::result_of<ident_functor(int(&&)[1])>>(), "Error!");
+static_assert(!has_type<std::result_of<ident_functor(Abstract&&)>>(), "Error!");
+static_assert(!has_type<std::result_of<ident_functor(const int(&&)[1])>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<ident_functor(const Abstract&&)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<ident_functor_noref(int(&)[1])>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<ident_functor_noref
+ (const int(&)[1])>>(), "Error!");
+static_assert(!has_type<std::result_of<ident_functor_noref(Abstract&)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <ident_functor_noref(const Abstract&)>>(), "Error!");
+static_assert(!has_type<std::result_of<ident_functor_noref(void(&)())>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<ident_functor_noref(void(&&)())>>(),
+ "Error!");
+
+static_assert(!has_type<std::result_of<ident_functor()>>(), "Error!");
+static_assert(!has_type<std::result_of<ident_functor(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const ident_functor&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const ident_functor&&(int)>>(),
+ "Error!");
+
+// Border-line case:
+static_assert(!has_type<std::result_of<int S::*(Ukn*)>>(), "Error!");
+static_assert(!has_type<std::result_of<void (S::*(Ukn*))()>>(), "Error!");
+
+// We want to allow this, it seems to be required by the order described
+// in [func.require] p1:
+static_assert(is_type<std::result_of<int S::*(BadSmartPtr<S>&)>, int&>(),
+ "Error!");
+
+static_assert(is_type<std::result_of<Private(std::nullptr_t)>, bool>(),
+ "Error!");
+static_assert(is_type<std::result_of<Private&(std::nullptr_t)>, bool>(),
+ "Error!");
+static_assert(is_type<std::result_of<Private&&(std::nullptr_t)>, bool>(),
+ "Error!");
+static_assert(is_type<std::result_of<Private(ImplicitTo<std::nullptr_t>)>,
+ bool>(), "Error!");
+static_assert(is_type<std::result_of<Private&(ImplicitTo<std::nullptr_t>)>,
+ bool>(), "Error!");
+static_assert(is_type<std::result_of<Private&&(ImplicitTo<std::nullptr_t>)>,
+ bool>(), "Error!");
+
+static_assert(!has_type<std::result_of<const Private&(std::nullptr_t)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const Private&&(std::nullptr_t)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<Private()>>(), "Error!");
+static_assert(!has_type<std::result_of<Private(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<Private(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<Private&()>>(), "Error!");
+static_assert(!has_type<std::result_of<Private&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<Private&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const Private&()>>(), "Error!");
+static_assert(!has_type<std::result_of<const Private&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const Private&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<Private&&()>>(), "Error!");
+static_assert(!has_type<std::result_of<Private&&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<Private&&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const Private&&()>>(), "Error!");
+static_assert(!has_type<std::result_of<const Private&&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const Private&&(int, int)>>(), "Error!");
+
+static_assert(!has_type<std::result_of<Private(ScEn)>>(), "Error!");
+static_assert(!has_type<std::result_of<Private(UnScEn)>>(), "Error!");
+static_assert(!has_type<std::result_of<const Private&(ScEn)>>(), "Error!");
+static_assert(!has_type<std::result_of<const Private&(UnScEn)>>(), "Error!");
+static_assert(!has_type<std::result_of<Private(ImplicitTo<ScEn>)>>(), "Error!");
+static_assert(!has_type<std::result_of<Private(ImplicitTo<UnScEn>)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const Private&(ImplicitTo<ScEn>)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const Private&(ImplicitTo<UnScEn>)>>(),
+ "Error!");
+
+static_assert(is_type<std::result_of<PrivateUnion(std::nullptr_t)>, bool>(),
+ "Error!");
+static_assert(is_type<std::result_of<PrivateUnion&(std::nullptr_t)>, bool>(),
+ "Error!");
+static_assert(is_type<std::result_of<PrivateUnion&&(std::nullptr_t)>, bool>(),
+ "Error!");
+static_assert(is_type<std::result_of<PrivateUnion(ImplicitTo<std::nullptr_t>)>,
+ bool>(), "Error!");
+static_assert(is_type<std::result_of
+ <PrivateUnion&(ImplicitTo<std::nullptr_t>)>, bool>(), "Error!");
+static_assert(is_type<std::result_of
+ <PrivateUnion&&(ImplicitTo<std::nullptr_t>)>, bool>(), "Error!");
+
+static_assert(!has_type<std::result_of<const PrivateUnion&(std::nullptr_t)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <const PrivateUnion&&(std::nullptr_t)>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion()>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion&()>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const PrivateUnion&()>>(), "Error!");
+static_assert(!has_type<std::result_of<const PrivateUnion&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const PrivateUnion&(int, int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion&&()>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion&&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion&&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const PrivateUnion&&()>>(), "Error!");
+static_assert(!has_type<std::result_of<const PrivateUnion&&(int)>>(), "Error!");
+static_assert(!has_type<std::result_of<const PrivateUnion&&(int, int)>>(),
+ "Error!");
+
+static_assert(!has_type<std::result_of<PrivateUnion(ScEn)>>(), "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion(UnScEn)>>(), "Error!");
+static_assert(!has_type<std::result_of<const PrivateUnion&(ScEn)>>(), "Error!");
+static_assert(!has_type<std::result_of<const PrivateUnion&(UnScEn)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion(ImplicitTo<ScEn>)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<PrivateUnion(ImplicitTo<UnScEn>)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <const PrivateUnion&(ImplicitTo<ScEn>)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <const PrivateUnion&(ImplicitTo<UnScEn>)>>(), "Error!");
+
+static_assert(is_type<std::result_of<void(*(bool))(int)>, void>(), "Error!");
+static_assert(is_type<std::result_of<void(*(UnScEn))(int)>, void>(), "Error!");
+static_assert(is_type<std::result_of<void(*(ImplicitTo<int>))(int)>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<void(*(ImplicitTo<int>&))(int)>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<void(*(ImplicitTo<int>&&))(int)>, void>(),
+ "Error!");
+
+static_assert(!has_type<std::result_of<void(*(ScEn))(int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <void(*(const ImplicitTo<int>&))(int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <void(*(const ImplicitTo<int>&&))(int)>>(), "Error!");
+
+static_assert(is_type<std::result_of<ImplicitTo<void(*)()>()>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<ImplicitTo<void(&)()>()>, void>(),
+ "Error!");
+
+static_assert(!has_type<std::result_of<ImplicitTo<void(*)()>(int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<ImplicitTo<void(*)(int)>()>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<ImplicitTo<void(&)()>(int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<ImplicitTo<void(&)(int)>()>>(),
+ "Error!");
+
+// Conversion operators of types are not considered in call expressions
+// (except for conversion to function pointer/reference):
+static_assert(!has_type<std::result_of<ImplicitTo<S>(char, int&)>>(), "Error!");
+static_assert(!has_type<std::result_of<ImplicitTo<ident_functor>(int)>>(),
+ "Error!");
+
+static_assert(is_type<std::result_of<variable_functor<>()>, void>(), "Error!");
+static_assert(is_type<std::result_of<variable_functor<>(int)>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<>(int, int)>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<>(int, int, int)>,
+ void>(), "Error!");
+
+static_assert(is_type<std::result_of<variable_functor<>&()>, void>(), "Error!");
+static_assert(is_type<std::result_of<variable_functor<>&(int)>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<>&(int, int)>, void>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<>&(int, int, int)>,
+ void>(), "Error!");
+
+static_assert(!has_type<std::result_of<const variable_functor<>()>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const variable_functor<>(int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const variable_functor<>(int, int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<>(int, int, int)>>(), "Error!");
+
+static_assert(!has_type<std::result_of<const variable_functor<>&()>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const variable_functor<>&(int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<>&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<>&(int, int, int)>>(), "Error!");
+
+static_assert(is_type<std::result_of<variable_functor<S>()>, S>(), "Error!");
+static_assert(is_type<std::result_of<variable_functor<S>(int)>, S>(), "Error!");
+static_assert(is_type<std::result_of<variable_functor<S>(int, int)>, S>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<S>(int, int, int)>, S>(),
+ "Error!");
+
+static_assert(is_type<std::result_of<variable_functor<S>&()>, S>(), "Error!");
+static_assert(is_type<std::result_of<variable_functor<S>&(int)>, S>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<S>&(int, int)>, S>(),
+ "Error!");
+static_assert(is_type<std::result_of
+ <variable_functor<S>&(int, int, int)>, S>(), "Error!");
+
+static_assert(!has_type<std::result_of
+ <const variable_functor<S>()>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<S>(int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<S>(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<S>(int, int, int)>>(), "Error!");
+
+static_assert(!has_type<std::result_of<const variable_functor<S>&()>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const variable_functor<S>&(int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<S>&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<S>&(int, int, int)>>(), "Error!");
+
+#if defined(HAS_52748_FIXED)
+static_assert(has_type<std::result_of<variable_functor<Ukn>()>>(), "Error!");
+static_assert(is_type<std::result_of<variable_functor<Ukn>()>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<Ukn>(int)>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<Ukn>(int, int)>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of
+ <variable_functor<Ukn>(int, int, int)>, Ukn>(), "Error!");
+
+static_assert(is_type<std::result_of<variable_functor<Ukn>&()>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of<variable_functor<Ukn>&(int)>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of
+ <variable_functor<Ukn>&(int, int)>, Ukn>(), "Error!");
+static_assert(is_type<std::result_of
+ <variable_functor<Ukn>&(int, int, int)>, Ukn>(), "Error!");
+
+static_assert(is_type<std::result_of<PMSIncomplete(int)>, Ukn>(), "Error!");
+static_assert(is_type<std::result_of<PMSIncomplete&(int)>, Ukn>(), "Error!");
+static_assert(is_type<std::result_of<PMSIncomplete&&(int)>, Ukn>(), "Error!");
+
+static_assert(is_type<std::result_of<FuncIncomplete(int)>, Ukn>(), "Error!");
+static_assert(is_type<std::result_of<FuncIncomplete&(int)>, Ukn>(), "Error!");
+static_assert(is_type<std::result_of<FuncIncomplete&&(int)>, Ukn>(), "Error!");
+
+static_assert(is_type<std::result_of<FuncEllipses<Ukn>*()>, Ukn>(), "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<Ukn>&()>, Ukn>(), "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<Ukn>&&()>, Ukn>(), "Error!");
+
+static_assert(is_type<std::result_of<FuncEllipses<Ukn>*(bool)>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<Ukn>&(bool)>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<Ukn>&&(bool)>, Ukn>(),
+ "Error!");
+
+static_assert(is_type<std::result_of<FuncEllipses<Ukn>*(bool, int, S)>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<Ukn>&(bool, int, S)>, Ukn>(),
+ "Error!");
+static_assert(is_type<std::result_of
+ <FuncEllipses<Ukn>&&(bool, int, S)>, Ukn>(), "Error!");
+
+static_assert(!has_type<std::result_of<PMSIncompletenonconst(const S*)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S*, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S*, int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S*, int, int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S*&)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S*&, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S*&, int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S*&, int, int, int)>>(), "Error!");
+
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S&)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S&, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S&, int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S&, int, int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S&&)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S&&, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S&&, int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <PMSIncompletenonconst(const S&&, int, int, int)>>(), "Error!");
+#endif
+
+static_assert(!has_type<std::result_of<const variable_functor<Ukn>()>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const variable_functor<Ukn>(int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<Ukn>(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<Ukn>(int, int, int)>>(), "Error!");
+
+static_assert(!has_type<std::result_of<const variable_functor<Ukn>&()>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<const variable_functor<Ukn>&(int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<Ukn>&(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of
+ <const variable_functor<Ukn>&(int, int, int)>>(), "Error!");
+
+static_assert(!has_type<std::result_of<FuncIncomplete()>>(), "Error!");
+static_assert(!has_type<std::result_of<FuncIncomplete(S)>>(), "Error!");
+static_assert(!has_type<std::result_of<FuncIncomplete(int, int)>>(), "Error!");
+static_assert(!has_type<std::result_of<FuncIncomplete(int, int, int)>>(),
+ "Error!");
+
+static_assert(!has_type<std::result_of<FuncIncomplete&&()>>(), "Error!");
+static_assert(!has_type<std::result_of<FuncIncomplete&&(S)>>(), "Error!");
+static_assert(!has_type<std::result_of<FuncIncomplete&&(int, int)>>(),
+ "Error!");
+static_assert(!has_type<std::result_of<FuncIncomplete&&(int, int, int)>>(),
+ "Error!");
+
+static_assert(is_type<std::result_of<FuncEllipses<int>*()>, int>(), "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<int>&()>, int>(), "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<int>&&()>, int>(), "Error!");
+
+static_assert(is_type<std::result_of<FuncEllipses<int>*(bool)>, int>(),
+ "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<int>&(bool)>, int>(),
+ "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<int>&&(bool)>, int>(),
+ "Error!");
+
+static_assert(is_type<std::result_of<FuncEllipses<int>*(bool, int, S)>, int>(),
+ "Error!");
+static_assert(is_type<std::result_of<FuncEllipses<int>&(bool, int, S)>, int>(),
+ "Error!");
+static_assert(is_type<std::result_of
+ <FuncEllipses<int>&&(bool, int, S)>, int>(), "Error!");
+
diff --git a/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_2.cc b/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_2.cc
new file mode 100644
index 000000000..57dcc5f66
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/result_of/sfinae_friendly_2.cc
@@ -0,0 +1,76 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// Taken from N3436:
+
+#include <type_traits>
+#include <string>
+
+struct eat { template<class T> eat(T const &) {} };
+struct not_incrementable {};
+
+struct inc {
+ template<class T>
+ auto operator()(T t) const -> decltype(t++)
+ { return t++; }
+};
+
+template<class A>
+typename std::result_of<inc(A)>::type // sfinae here
+try_inc(A a) {
+ return inc()(a);
+}
+
+not_incrementable
+try_inc(eat) {
+ return not_incrementable();
+}
+
+template<class>
+struct never { static const bool value = false; };
+
+template<class T>
+struct Fail
+{
+ static_assert(never<T>::value, "duh");
+ typedef int type;
+};
+
+struct Fun
+{
+ template<class T>
+ typename Fail<T>::type operator()(T)
+ { return 0; }
+};
+
+template<class T>
+typename std::result_of<Fun(T)>::type foo(T)
+{ return 0; }
+
+template<class>
+int foo(...)
+{ return 0; }
+
+void result_of_sfinae() {
+ int x = try_inc(1); // OK
+ not_incrementable y = try_inc(std::string("foo")); // OK, not_incrementable
+ (void) x;
+ (void) y;
+}
diff --git a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
index dc9d80383..a2ceeb5c2 100644
--- a/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
+++ b/libstdc++-v3/testsuite/20_util/shared_ptr/cons/43820_neg.cc
@@ -32,9 +32,9 @@ void test01()
{
X* px = 0;
std::shared_ptr<X> p1(px); // { dg-error "here" }
- // { dg-error "incomplete" "" { target *-*-* } 776 }
+ // { dg-error "incomplete" "" { target *-*-* } 775 }
std::shared_ptr<X> p9(ap()); // { dg-error "here" }
- // { dg-error "incomplete" "" { target *-*-* } 310 }
+ // { dg-error "incomplete" "" { target *-*-* } 307 }
}
diff --git a/libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc b/libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc
new file mode 100644
index 000000000..28cc9959b
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/array/requirements/non_default_constructible.cc
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <array>
+#include <typeindex>
+#include <typeinfo>
+
+template < typename ...Types >
+union super_union;
+
+template < >
+union super_union<>
+{
+ static auto optioned_types() -> std::array<std::type_index, 0>
+ { return std::array<std::type_index, 0>{ {} }; }
+};
+
+template < typename Head, typename ...Tail >
+union super_union<Head, Tail...>
+{
+ static
+ auto optioned_types() -> std::array<std::type_index, 1 + sizeof...(Tail)>
+ {
+ using std::type_index;
+
+ return { {type_index(typeid(Head)), type_index(typeid(Tail))...} };
+ }
+
+ Head data;
+ super_union<Tail...> rest;
+};
diff --git a/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc b/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc
index ed29e2a1e..86e237583 100644
--- a/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/requirements/zero_sized_arrays.cc
@@ -1,6 +1,6 @@
// { dg-options "-std=gnu++0x" }
//
-// Copyright (C) 2011 Free Software Foundation, Inc.
+// Copyright (C) 2011-2012 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -38,18 +38,6 @@ test01()
// begin() == end()
VERIFY( a.begin() == a.end() );
VERIFY( b.begin() == b.end() );
-
- // 4: ?
- // begin() == end() == unique value.
- {
- typedef std::array<long, len> array_type1;
- typedef std::array<char, len> array_type2;
- array_type1 one;
- array_type2 two;
- void* v1 = one.begin();
- void* v2 = two.begin();
- VERIFY( v1 != v2 );
- }
}
int main()
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
index 2fc443eda..e74af1b4f 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/get_neg.cc
@@ -27,6 +27,6 @@ int n1 = std::get<1>(a);
int n2 = std::get<1>(std::move(a));
int n3 = std::get<1>(ca);
-// { dg-error "static assertion failed" "" { target *-*-* } 275 }
-// { dg-error "static assertion failed" "" { target *-*-* } 283 }
-// { dg-error "static assertion failed" "" { target *-*-* } 267 }
+// { dg-error "static assertion failed" "" { target *-*-* } 288 }
+// { dg-error "static assertion failed" "" { target *-*-* } 296 }
+// { dg-error "static assertion failed" "" { target *-*-* } 304 }
diff --git a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
index 97938ba66..b9ce910f6 100644
--- a/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/array/tuple_interface/tuple_element_neg.cc
@@ -22,4 +22,4 @@
typedef std::tuple_element<1, std::array<int, 1>>::type type;
-// { dg-error "static assertion failed" "" { target *-*-* } 259 }
+// { dg-error "static assertion failed" "" { target *-*-* } 280 }
diff --git a/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/54686.c b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/54686.c
new file mode 100644
index 000000000..fd723c89e
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/headers/cstdlib/54686.c
@@ -0,0 +1,32 @@
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <cmath>
+#include <cstdlib>
+#include <type_traits>
+#include <utility>
+
+#ifdef _GLIBCXX_USE_LONG_LONG
+void test01()
+{
+ static_assert (std::is_same<decltype (std::abs (std::declval<long long> ())),
+ long long>::value, "Missing abs(long long)");
+}
+#endif
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc
index 4a7161a79..4a7161a79 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_01.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_01.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc
index 6c0fdd76f..6c0fdd76f 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_00_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_00_03.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_01_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc
index 3439b544b..3439b544b 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_01_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_01_03.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc
index dfd00a0f3..dfd00a0f3 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/basic/string_range_02_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/cstring_plus.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc
index ad0f57e22..ad0f57e22 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/cstring_plus.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/cstring_questionmark.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc
index 21abea456..21abea456 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/cstring_questionmark.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_any.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc
index 8d3716b1e..8d3716b1e 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_any.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_any.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc
index a0a2e1fa9..a0a2e1fa9 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_00_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_01_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc
index b50e07645..b50e07645 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_01_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_01_03.cc
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc
index ca322a8d4..ca322a8d4 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/match/extended/string_range_02_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/regex.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/default.cc
index 8a803ede8..8a803ede8 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/regex.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/default.cc
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc
new file mode 100644
index 000000000..0ab42ebac
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/ctors/basic/raw_string.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=c++0x" }
+// { dg-do run { xfail *-*-* } }
+
+// 2012-08-20 Benjamin Kosnik <bkoz@redhat.com>
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// basic_regex constructors + raw string literals
+
+#include <regex>
+#include <testsuite_regex.h>
+
+void
+test01()
+{
+ using namespace __gnu_test;
+
+ // raw string literals
+
+ //string_type sre0(R"(\d{3}-\d{3}-\d{4})"); // expected fail
+
+ string_type sre1(R"( this\n and new : forms\n )");
+
+ string_type sre2(R"([:num:]{3}-[:num:]{3}-[:num:]{4})");
+
+ // 1
+ regex_type re(R"( this\n and new : forms\n )", std::regex::basic);
+
+ // 2
+ regex_sanity_check(sre1);
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_regex.h b/libstdc++-v3/testsuite/util/testsuite_regex.h
new file mode 100644
index 000000000..dbf4b3455
--- /dev/null
+++ b/libstdc++-v3/testsuite/util/testsuite_regex.h
@@ -0,0 +1,130 @@
+// -*- C++ -*-
+// regex utils for the C++ library testsuite.
+//
+// Copyright (C) 2012 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+
+#include <regex>
+#include <stdexcept>
+#include <iostream>
+
+#ifndef _TESTSUITE_REGEX_H
+#define _TESTSUITE_REGEX_H 1
+
+namespace __gnu_test
+{
+ // Test on a compilation of simple expressions, throw regex_error on error.
+ typedef std::regex regex_type;
+ typedef regex_type::flag_type flag_type;
+ typedef std::regex_constants::error_type error_type;
+ typedef std::size_t size_type;
+ typedef std::string string_type;
+
+ // Utilities
+ struct regex_expected_fail { };
+
+ const error_type regex_error_internal(static_cast<error_type>(-1));
+
+ // Stringify error codes for text logging.
+ const char* regex_error_codes[] =
+ {
+ "error_collate",
+ "error_ctype",
+ "error_escape",
+ "error_backref",
+ "error_brack",
+ "error_paren",
+ "error_brace",
+ "error_badbrace",
+ "error_range",
+ "error_space",
+ "error_badrepeat",
+ "error_complexity",
+ "error_stack"
+ };
+
+ void
+ show_regex_error_codes()
+ {
+ using namespace std;
+ using namespace std::regex_constants;
+ const char tab('\t');
+ cout << "error_collate = " << tab << error_collate << endl;
+ cout << "error_ctype = " << tab << error_ctype << endl;
+ cout << "error_escape = " << tab << error_escape << endl;
+ cout << "error_backref = " << tab << error_backref << endl;
+ cout << "error_brack = " << tab << error_brack << endl;
+ cout << "error_paren = " << tab << error_paren << endl;
+ cout << "error_brace = " << tab << error_brace << endl;
+ cout << "error_badbrace = " << tab << error_badbrace << endl;
+ cout << "error_range = " << tab << error_range << endl;
+ cout << "error_space = " << tab << error_space << endl;
+ cout << "error_badrepeat = " << tab << error_badrepeat << endl;
+ cout << "error_complexity =" << tab << error_complexity << endl;
+ cout << "error_stack = " << tab << error_stack << endl;
+ }
+
+ // Arguments
+ // string __res: the regular expression string
+ // flag_type __f: flag
+ // __error: expected error, if any
+ void
+ regex_sanity_check(const string_type& __res,
+ flag_type __f = regex_type::basic,
+ error_type __error = regex_error_internal)
+ {
+ using namespace std;
+
+ try
+ {
+ regex_type reo(__res, __f);
+ auto n = reo.mark_count();
+ cout << "regex_type::mark_count " << n << endl;
+ }
+ catch (const regex_error& e)
+ {
+ cout << "regex_sanity_check: " << __res << endl;
+ cout << "regex_error::what " << e.what() << endl;
+
+ show_regex_error_codes();
+ cout << "regex_error::code " << regex_error_codes[e.code()] << endl;
+
+ if (__error != regex_error_internal)
+ {
+ // Then expected error_type is __error. Check.
+ if (__error != e.code())
+ {
+ throw regex_expected_fail();
+ }
+ }
+ throw;
+ }
+ catch (const logic_error& e)
+ {
+ cout << "logic_error::what " << e.what() << endl;
+ throw;
+ }
+ catch (const std::exception& e)
+ {
+ cout << "exception: " << endl;
+ throw;
+ }
+ }
+
+} // namespace __gnu_test
+#endif