summaryrefslogtreecommitdiff
path: root/gcc/ada/sem_eval.adb
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-21 13:42:24 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-21 13:42:24 +0000
commit9dfe12ae5b94d03c997ea2903022a5d2d5c5f266 (patch)
treebdfc70477b60f1220cb05dd233a4570dd9c6bb5c /gcc/ada/sem_eval.adb
parent1c662558a1113238a624245a45382d3df90ccf13 (diff)
downloadgcc-9dfe12ae5b94d03c997ea2903022a5d2d5c5f266.tar.gz
2003-10-21 Arnaud Charlet <charlet@act-europe.fr>
* 3psoccon.ads, 3veacodu.adb, 3vexpect.adb, 3vsoccon.ads, 3vsocthi.adb, 3vsocthi.ads, 3vtrasym.adb, 3zsoccon.ads, 3zsocthi.adb, 3zsocthi.ads, 50system.ads, 51system.ads, 55system.ads, 56osinte.adb, 56osinte.ads, 56taprop.adb, 56taspri.ads, 56tpopsp.adb, 57system.ads, 58system.ads, 59system.ads, 5aml-tgt.adb, 5bml-tgt.adb, 5csystem.ads, 5dsystem.ads, 5fosinte.adb, 5gml-tgt.adb, 5hml-tgt.adb, 5isystem.ads, 5lparame.adb, 5msystem.ads, 5psystem.ads, 5sml-tgt.adb, 5sosprim.adb, 5stpopsp.adb, 5tsystem.ads, 5usystem.ads, 5vml-tgt.adb, 5vsymbol.adb, 5vtraent.adb, 5vtraent.ads, 5wml-tgt.adb, 5xparame.ads, 5xsystem.ads, 5xvxwork.ads, 5yparame.ads, 5ytiitho.adb, 5zinit.adb, 5zml-tgt.adb, 5zparame.ads, 5ztaspri.ads, 5ztfsetr.adb, 5zthrini.adb, 5ztiitho.adb, 5ztpopsp.adb, 7stfsetr.adb, 7straces.adb, 7strafor.adb, 7strafor.ads, 7stratas.adb, a-excach.adb, a-exexda.adb, a-exexpr.adb, a-exextr.adb, a-exstat.adb, a-strsup.adb, a-strsup.ads, a-stwisu.adb, a-stwisu.ads, bld.adb, bld.ads, bld-io.adb, bld-io.ads, clean.adb, clean.ads, ctrl_c.c, erroutc.adb, erroutc.ads, errutil.adb, errutil.ads, err_vars.ads, final.c, g-arrspl.adb, g-arrspl.ads, g-boubuf.adb, g-boubuf.ads, g-boumai.ads, g-bubsor.adb, g-bubsor.ads, g-comver.adb, g-comver.ads, g-ctrl_c.ads, g-dynhta.adb, g-dynhta.ads, g-eacodu.adb, g-excact.adb, g-excact.ads, g-heasor.adb, g-heasor.ads, g-memdum.adb, g-memdum.ads, gnatclean.adb, gnatsym.adb, g-pehage.adb, g-pehage.ads, g-perhas.ads, gpr2make.adb, gpr2make.ads, gprcmd.adb, gprep.adb, gprep.ads, g-semaph.adb, g-semaph.ads, g-string.adb, g-string.ads, g-strspl.ads, g-wistsp.ads, i-vthrea.adb, i-vthrea.ads, i-vxwoio.adb, i-vxwoio.ads, Makefile.generic, Makefile.prolog, Makefile.rtl, prep.adb, prep.ads, prepcomp.adb, prepcomp.ads, prj-err.adb, prj-err.ads, s-boarop.ads, s-carsi8.adb, s-carsi8.ads, s-carun8.adb, s-carun8.ads, s-casi16.adb, s-casi16.ads, s-casi32.adb, s-casi32.ads, s-casi64.adb, s-casi64.ads, s-casuti.adb, s-casuti.ads, s-caun16.adb, s-caun16.ads, s-caun32.adb, s-caun32.ads, s-caun64.adb, s-caun64.ads, scng.adb, scng.ads, s-exnint.adb, s-exnllf.adb, s-exnlli.adb, s-expint.adb, s-explli.adb, s-geveop.adb, s-geveop.ads, s-hibaen.ads, s-htable.adb, s-htable.ads, sinput-c.adb, sinput-c.ads, s-memcop.ads, socket.c, s-purexc.ads, s-scaval.adb, s-stopoo.adb, s-strcom.adb, s-strcom.ads, s-strxdr.adb, s-rident.ads, s-thread.adb, s-thread.ads, s-tpae65.adb, s-tpae65.ads, s-tporft.adb, s-traent.adb, s-traent.ads, styleg.adb, styleg.ads, styleg-c.adb, styleg-c.ads, s-veboop.adb, s-veboop.ads, s-vector.ads, symbols.adb, symbols.ads, tb-alvms.c, tb-alvxw.c, tempdir.adb, tempdir.ads, vms_conv.ads, vms_conv.adb, vms_data.ads, vxaddr2line.adb: Files added. Merge with ACT tree. * 4dintnam.ads, 4mintnam.ads, 4uintnam.ads, 52system.ads, 5dosinte.ads, 5etpopse.adb, 5mosinte.ads, 5qosinte.adb, 5qosinte.ads, 5qstache.adb, 5qtaprop.adb, 5qtaspri.ads, 5stpopse.adb, 5uintman.adb, 5uosinte.ads, adafinal.c, g-enblsp.adb, io-aux.c, scn-nlit.adb, scn-slit.adb, s-exnflt.ads, s-exngen.adb, s-exngen.ads, s-exnlfl.ads, s-exnlin.ads, s-exnsfl.ads, s-exnsin.ads, s-exnssi.ads, s-expflt.ads, s-expgen.adb, s-expgen.ads, s-explfl.ads, s-explin.ads, s-expllf.ads, s-expsfl.ads, s-expsin.ads, s-expssi.ads, style.adb: Files removed. Merge with ACT tree. * 1ic.ads, 31soccon.ads, 31soliop.ads, 3asoccon.ads, 3bsoccon.ads, 3gsoccon.ads, 3hsoccon.ads, 3ssoccon.ads, 3ssoliop.ads, 3wsoccon.ads, 3wsocthi.adb, 3wsocthi.ads, 3wsoliop.ads, 41intnam.ads, 42intnam.ads, 4aintnam.ads, 4cintnam.ads, 4gintnam.ads, 4hexcpol.adb, 4hintnam.ads, 4lintnam.ads, 4nintnam.ads, 4ointnam.ads, 4onumaux.ads, 4pintnam.ads, 4sintnam.ads, 4vcaldel.adb, 4vcalend.adb, 4vintnam.ads, 4wexcpol.adb, 4wintnam.ads, 4zintnam.ads, 51osinte.adb, 51osinte.ads, 52osinte.adb, 52osinte.ads, 53osinte.ads, 54osinte.ads, 5aosinte.adb, 5aosinte.ads, 5asystem.ads, 5ataprop.adb, 5atasinf.ads, 5ataspri.ads, 5atpopsp.adb, 5avxwork.ads, 5bosinte.adb, 5bosinte.ads, 5bsystem.ads, 5cosinte.ads, 5esystem.ads, 5fintman.adb, 5fosinte.ads, 5fsystem.ads, 5ftaprop.adb, 5ftasinf.ads, 5ginterr.adb, 5gintman.adb, 5gmastop.adb, 5gosinte.ads, 5gproinf.ads, 5gsystem.ads, 5gtaprop.adb, 5gtasinf.ads, 5gtpgetc.adb, 5hosinte.adb, 5hosinte.ads, 5hsystem.ads, 5htaprop.adb, 5htaspri.ads, 5htraceb.adb, 5iosinte.adb, 5itaprop.adb, 5itaspri.ads, 5ksystem.ads, 5kvxwork.ads, 5lintman.adb, 5lml-tgt.adb, 5losinte.ads, 5lsystem.ads, 5mvxwork.ads, 5ninmaop.adb, 5nintman.adb, 5nosinte.ads, 5ntaprop.adb, 5ntaspri.ads, 5ointerr.adb, 5omastop.adb, 5oosinte.adb, 5oosinte.ads, 5oosprim.adb, 5oparame.adb, 5osystem.ads, 5otaprop.adb, 5otaspri.ads, 5posinte.ads, 5posprim.adb, 5pvxwork.ads, 5sintman.adb, 5sosinte.adb, 5sosinte.ads, 5ssystem.ads, 5staprop.adb, 5stasinf.ads, 5staspri.ads, 5svxwork.ads, 5tosinte.ads, 5vasthan.adb, 5vinmaop.adb, 5vinterr.adb, 5vintman.adb, 5vintman.ads, 5vmastop.adb, 5vosinte.adb, 5vosinte.ads, 5vosprim.adb, 5vsystem.ads, 5vtaprop.adb, 5vtaspri.ads, 5vtpopde.adb, 5vtpopde.ads, 5wgloloc.adb, 5wintman.adb, 5wmemory.adb, 5wosprim.adb, 5wsystem.ads, 5wtaprop.adb, 5wtaspri.ads, 5ysystem.ads, 5zinterr.adb, 5zintman.adb, 5zosinte.adb, 5zosinte.ads, 5zosprim.adb, 5zsystem.ads, 5ztaprop.adb, 6vcpp.adb, 6vcstrea.adb, 6vinterf.ads, 7sinmaop.adb, 7sintman.adb, 7sosinte.adb, 7sosprim.adb, 7staprop.adb, 7staspri.ads, 7stpopsp.adb, 7straceb.adb, 9drpc.adb, a-caldel.adb, a-caldel.ads, a-charac.ads, a-colien.ads, a-comlin.adb, adaint.c, adaint.h, ada-tree.def, a-diocst.adb, a-diocst.ads, a-direio.adb, a-except.adb, a-except.ads, a-excpol.adb, a-exctra.adb, a-exctra.ads, a-filico.adb, a-interr.adb, a-intsig.adb, a-intsig.ads, ali.adb, ali.ads, ali-util.adb, ali-util.ads, a-ngcefu.adb, a-ngcoty.adb, a-ngelfu.adb, a-nudira.adb, a-nudira.ads, a-nuflra.adb, a-nuflra.ads, a-reatim.adb, a-reatim.ads, a-retide.ads, a-sequio.adb, a-siocst.adb, a-siocst.ads, a-ssicst.adb, a-ssicst.ads, a-strbou.adb, a-strbou.ads, a-strfix.adb, a-strmap.adb, a-strsea.ads, a-strunb.adb, a-strunb.ads, a-ststio.adb, a-stunau.adb, a-stunau.ads, a-stwibo.adb, a-stwibo.ads, a-stwifi.adb, a-stwima.adb, a-stwiun.adb, a-stwiun.ads, a-tags.adb, a-tags.ads, a-tasatt.adb, a-taside.adb, a-teioed.adb, a-textio.adb, a-textio.ads, a-tienau.adb, a-tifiio.adb, a-tiflau.adb, a-tiflio.adb, a-tigeau.adb, a-tigeau.ads, a-tiinau.adb, a-timoau.adb, a-tiocst.adb, a-tiocst.ads, atree.adb, atree.ads, a-witeio.adb, a-witeio.ads, a-wtcstr.adb, a-wtcstr.ads, a-wtdeio.adb, a-wtedit.adb, a-wtenau.adb, a-wtflau.adb, a-wtinau.adb, a-wtmoau.adb, bcheck.adb, binde.adb, bindgen.adb, bindusg.adb, checks.adb, checks.ads, cio.c, comperr.adb, comperr.ads, csets.adb, cstand.adb, cstreams.c, debug_a.adb, debug_a.ads, debug.adb, decl.c, einfo.adb, einfo.ads, errout.adb, errout.ads, eval_fat.adb, eval_fat.ads, exp_aggr.adb, expander.adb, expander.ads, exp_attr.adb, exp_ch11.adb, exp_ch13.adb, exp_ch2.adb, exp_ch3.adb, exp_ch3.ads, exp_ch4.adb, exp_ch5.adb, exp_ch6.adb, exp_ch7.adb, exp_ch7.ads, exp_ch8.adb, exp_ch9.adb, exp_code.adb, exp_dbug.adb, exp_dbug.ads, exp_disp.adb, exp_dist.adb, expect.c, exp_fixd.adb, exp_imgv.adb, exp_intr.adb, exp_pakd.adb, exp_prag.adb, exp_strm.adb, exp_strm.ads, exp_tss.adb, exp_tss.ads, exp_util.adb, exp_util.ads, exp_vfpt.adb, fe.h, fmap.adb, fmap.ads, fname.adb, fname.ads, fname-uf.adb, fname-uf.ads, freeze.adb, freeze.ads, frontend.adb, g-awk.adb, g-awk.ads, g-busora.adb, g-busora.ads, g-busorg.adb, g-busorg.ads, g-casuti.adb, g-casuti.ads, g-catiio.adb, g-catiio.ads, g-cgi.adb, g-cgi.ads, g-cgicoo.adb, g-cgicoo.ads, g-cgideb.adb, g-cgideb.ads, g-comlin.adb, g-comlin.ads, g-crc32.adb, g-crc32.ads, g-debpoo.adb, g-debpoo.ads, g-debuti.adb, g-debuti.ads, g-diopit.adb, g-diopit.ads, g-dirope.adb, g-dirope.ads, g-dyntab.adb, g-dyntab.ads, g-except.ads, g-exctra.adb, g-exctra.ads, g-expect.adb, g-expect.ads, g-hesora.adb, g-hesora.ads, g-hesorg.adb, g-hesorg.ads, g-htable.adb, g-htable.ads, gigi.h, g-io.adb, g-io.ads, g-io_aux.adb, g-io_aux.ads, g-locfil.adb, g-locfil.ads, g-md5.adb, g-md5.ads, gmem.c, gnat1drv.adb, gnatbind.adb, gnatchop.adb, gnatcmd.adb, gnatfind.adb, gnatkr.adb, gnatlbr.adb, gnatlink.adb, gnatls.adb, gnatmake.adb, gnatmem.adb, gnatname.adb, gnatprep.adb, gnatprep.ads, gnatpsta.adb, gnatxref.adb, g-os_lib.adb, g-os_lib.ads, g-regexp.adb, g-regexp.ads, g-regist.adb, g-regist.ads, g-regpat.adb, g-regpat.ads, g-soccon.ads, g-socket.adb, g-socket.ads, g-socthi.adb, g-socthi.ads, g-soliop.ads, g-souinf.ads, g-speche.adb, g-speche.ads, g-spipat.adb, g-spipat.ads, g-spitbo.adb, g-spitbo.ads, g-sptabo.ads, g-sptain.ads, g-sptavs.ads, g-table.adb, g-table.ads, g-tasloc.adb, g-tasloc.ads, g-thread.adb, g-thread.ads, g-traceb.adb, g-traceb.ads, g-trasym.adb, g-trasym.ads, hostparm.ads, i-c.ads, i-cobol.adb, i-cpp.adb, i-cstrea.ads, i-cstrin.adb, i-cstrin.ads, impunit.adb, init.c, inline.adb, interfac.ads, i-pacdec.ads, itypes.adb, itypes.ads, i-vxwork.ads, lang.opt, lang-specs.h, layout.adb, lib.adb, lib.ads, lib-list.adb, lib-load.adb, lib-load.ads, lib-sort.adb, lib-util.adb, lib-writ.adb, lib-writ.ads, lib-xref.adb, lib-xref.ads, link.c, live.adb, make.adb, make.ads, Makefile.adalib, Makefile.in, Make-lang.in, makeusg.adb, mdll.adb, mdll-fil.adb, mdll-fil.ads, mdll-utl.adb, mdll-utl.ads, memroot.adb, memroot.ads, memtrack.adb, misc.c, mkdir.c, mlib.adb, mlib.ads, mlib-fil.adb, mlib-fil.ads, mlib-prj.adb, mlib-prj.ads, mlib-tgt.adb, mlib-tgt.ads, mlib-utl.adb, mlib-utl.ads, namet.adb, namet.ads, namet.h, nlists.ads, nlists.h, nmake.adt, opt.adb, opt.ads, osint.adb, osint.ads, osint-b.adb, osint-c.adb, par.adb, par-ch10.adb, par-ch11.adb, par-ch2.adb, par-ch3.adb, par-ch4.adb, par-ch5.adb, par-ch6.adb, par-ch9.adb, par-endh.adb, par-labl.adb, par-load.adb, par-prag.adb, par-sync.adb, par-tchk.adb, par-util.adb, prj.adb, prj.ads, prj-attr.adb, prj-attr.ads, prj-com.adb, prj-com.ads, prj-dect.adb, prj-dect.ads, prj-env.adb, prj-env.ads, prj-ext.adb, prj-ext.ads, prj-makr.adb, prj-makr.ads, prj-nmsc.adb, prj-nmsc.ads, prj-pars.adb, prj-pars.ads, prj-part.adb, prj-part.ads, prj-pp.adb, prj-pp.ads, prj-proc.adb, prj-proc.ads, prj-strt.adb, prj-strt.ads, prj-tree.adb, prj-tree.ads, prj-util.adb, prj-util.ads, raise.c, raise.h, repinfo.adb, repinfo.h, restrict.adb, restrict.ads, rident.ads, rtsfind.adb, rtsfind.ads, s-addima.ads, s-arit64.adb, s-assert.adb, s-assert.ads, s-atacco.adb, s-atacco.ads, s-auxdec.adb, s-auxdec.ads, s-bitops.adb, scans.ads, scn.adb, scn.ads, s-crc32.adb, s-crc32.ads, s-direio.adb, sem.adb, sem.ads, sem_aggr.adb, sem_attr.adb, sem_attr.ads, sem_case.adb, sem_case.ads, sem_cat.adb, sem_cat.ads, sem_ch10.adb, sem_ch11.adb, sem_ch12.adb, sem_ch12.ads, sem_ch13.adb, sem_ch13.ads, sem_ch3.adb, sem_ch3.ads, sem_ch4.adb, sem_ch5.adb, sem_ch5.ads, sem_ch6.adb, sem_ch6.ads, sem_ch7.adb, sem_ch7.ads, sem_ch8.adb, sem_ch8.ads, sem_ch9.adb, sem_disp.adb, sem_disp.ads, sem_dist.adb, sem_elab.adb, sem_eval.adb, sem_eval.ads, sem_intr.adb, sem_maps.adb, sem_mech.adb, sem_prag.adb, sem_prag.ads, sem_res.adb, sem_res.ads, sem_type.adb, sem_type.ads, sem_util.adb, sem_util.ads, sem_warn.adb, s-errrep.adb, s-errrep.ads, s-exctab.adb, s-exctab.ads, s-exnint.ads, s-exnllf.ads, s-exnlli.ads, s-expint.ads, s-explli.ads, s-expuns.ads, s-fatflt.ads, s-fatgen.adb, s-fatgen.ads, s-fatlfl.ads, s-fatllf.ads, s-fatsfl.ads, s-fileio.adb, s-fileio.ads, s-finimp.adb, s-finimp.ads, s-finroo.adb, s-finroo.ads, sfn_scan.adb, s-gloloc.adb, s-gloloc.ads, s-imgdec.adb, s-imgenu.adb, s-imgrea.adb, s-imgwch.adb, sinfo.adb, sinfo.ads, s-inmaop.ads, sinput.adb, sinput.ads, sinput-d.adb, sinput-l.adb, sinput-l.ads, sinput-p.adb, sinput-p.ads, s-interr.adb, s-interr.ads, s-intman.ads, s-maccod.ads, s-mastop.adb, s-mastop.ads, s-memory.adb, s-memory.ads, snames.adb, snames.ads, snames.h, s-osprim.ads, s-parame.ads, s-parint.ads, s-pooloc.adb, s-pooloc.ads, s-poosiz.adb, sprint.adb, s-proinf.ads, s-scaval.ads, s-secsta.adb, s-secsta.ads, s-sequio.adb, s-shasto.adb, s-shasto.ads, s-soflin.ads, s-stache.adb, s-stache.ads, s-stalib.adb, s-stalib.ads, s-stoele.ads, s-stopoo.ads, s-stratt.adb, s-stratt.ads, s-strops.adb, s-strops.ads, s-taasde.adb, s-taasde.ads, s-tadeca.adb, s-tadeca.ads, s-tadert.adb, s-tadert.ads, s-taenca.adb, s-taenca.ads, s-taprob.adb, s-taprob.ads, s-taprop.ads, s-tarest.adb, s-tarest.ads, s-tasdeb.adb, s-tasdeb.ads, s-tasinf.adb, s-tasinf.ads, s-tasini.adb, s-tasini.ads, s-taskin.adb, s-taskin.ads, s-tasque.adb, s-tasque.ads, s-tasren.adb, s-tasren.ads, s-tasres.ads, s-tassta.adb, s-tassta.ads, s-tasuti.adb, s-tasuti.ads, s-tataat.adb, s-tataat.ads, s-tpinop.adb, s-tpinop.ads, s-tpoben.adb, s-tpoben.ads, s-tpobop.adb, s-tpobop.ads, s-tposen.adb, s-tposen.ads, s-traceb.adb, s-traceb.ads, stringt.adb, stringt.ads, stringt.h, style.ads, stylesw.adb, stylesw.ads, s-unstyp.ads, s-vaflop.ads, s-valrea.adb, s-valuti.adb, s-vercon.adb, s-vmexta.adb, s-wchcnv.ads, s-wchcon.ads, s-widcha.adb, switch.adb, switch.ads, switch-b.adb, switch-c.adb, switch-m.adb, s-wwdcha.adb, s-wwdwch.adb, sysdep.c, system.ads, table.adb, table.ads, targparm.adb, targparm.ads, targtyps.c, tbuild.adb, tbuild.ads, tracebak.c, trans.c, tree_io.adb, treepr.adb, treeprs.adt, ttypes.ads, types.ads, types.h, uintp.adb, uintp.ads, uintp.h, uname.adb, urealp.adb, urealp.ads, urealp.h, usage.adb, utils2.c, utils.c, validsw.adb, validsw.ads, widechar.adb, xeinfo.adb, xnmake.adb, xref_lib.adb, xref_lib.ads, xr_tabls.adb, xr_tabls.ads, xtreeprs.adb, xsnames.adb, einfo.h, sinfo.h, treeprs.ads, nmake.ads, nmake.adb, gnatvsn.ads: Merge with ACT tree. * gnatvsn.adb: Rewritten in a simpler and more efficient way. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72751 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/sem_eval.adb')
-rw-r--r--gcc/ada/sem_eval.adb649
1 files changed, 542 insertions, 107 deletions
diff --git a/gcc/ada/sem_eval.adb b/gcc/ada/sem_eval.adb
index 92bf0a14199..cc6d6f3d79f 100644
--- a/gcc/ada/sem_eval.adb
+++ b/gcc/ada/sem_eval.adb
@@ -1,4 +1,4 @@
----------------------
+------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 1992-2002 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2003 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- --
@@ -209,23 +209,42 @@ package body Sem_Eval is
------------------------------
procedure Check_Non_Static_Context (N : Node_Id) is
- T : Entity_Id := Etype (N);
- Checks_On : constant Boolean :=
+ T : constant Entity_Id := Etype (N);
+ Checks_On : constant Boolean :=
not Index_Checks_Suppressed (T)
and not Range_Checks_Suppressed (T);
begin
- -- We need the check only for static expressions not raising CE
- -- We can also ignore cases in which the type is Any_Type
+ -- Ignore cases of non-scalar types or error types
- if not Is_OK_Static_Expression (N)
- or else Etype (N) = Any_Type
- then
+ if T = Any_Type or else not Is_Scalar_Type (T) then
return;
+ end if;
- -- Skip this check for non-scalar expressions
+ -- At this stage we have a scalar type. If we have an expression
+ -- that raises CE, then we already issued a warning or error msg
+ -- so there is nothing more to be done in this routine.
+
+ if Raises_Constraint_Error (N) then
+ return;
+ end if;
+
+ -- Now we have a scalar type which is not marked as raising a
+ -- constraint error exception. The main purpose of this routine
+ -- is to deal with static expressions appearing in a non-static
+ -- context. That means that if we do not have a static expression
+ -- then there is not much to do. The one case that we deal with
+ -- here is that if we have a floating-point value that is out of
+ -- range, then we post a warning that an infinity will result.
+
+ if not Is_Static_Expression (N) then
+ if Is_Floating_Point_Type (T)
+ and then Is_Out_Of_Range (N, Base_Type (T))
+ then
+ Error_Msg_N
+ ("?float value out of range, infinity will be generated", N);
+ end if;
- elsif not Is_Scalar_Type (T) then
return;
end if;
@@ -265,21 +284,16 @@ package body Sem_Eval is
(N, Corresponding_Integer_Value (N) * Small_Value (T));
elsif not UR_Is_Zero (Realval (N)) then
- declare
- RT : constant Entity_Id := Base_Type (T);
- X : constant Ureal := Machine (RT, Realval (N), Round);
- begin
- -- Warn if result of static rounding actually differs from
- -- runtime evaluation, which uses round to even.
+ -- Note: even though RM 4.9(38) specifies biased rounding,
+ -- this has been modified by AI-100 in order to prevent
+ -- confusing differences in rounding between static and
+ -- non-static expressions. AI-100 specifies that the effect
+ -- of such rounding is implementation dependent, and in GNAT
+ -- we round to nearest even to match the run-time behavior.
- if Warn_On_Biased_Rounding and Rounding_Was_Biased then
- Error_Msg_N ("static expression does not round to even"
- & " ('R'M 4.9(38))?", N);
- end if;
-
- Set_Realval (N, X);
- end;
+ Set_Realval
+ (N, Machine (Base_Type (T), Realval (N), Round_Even, N));
end if;
Set_Is_Machine_Number (N);
@@ -361,7 +375,11 @@ package body Sem_Eval is
-- Compile_Time_Compare --
--------------------------
- function Compile_Time_Compare (L, R : Node_Id) return Compare_Result is
+ function Compile_Time_Compare
+ (L, R : Node_Id;
+ Rec : Boolean := False)
+ return Compare_Result
+ is
Ltyp : constant Entity_Id := Etype (L);
Rtyp : constant Entity_Id := Etype (R);
@@ -518,12 +536,47 @@ package body Sem_Eval is
Lf : constant Node_Id := Compare_Fixup (L);
Rf : constant Node_Id := Compare_Fixup (R);
+ function Is_Same_Subscript (L, R : List_Id) return Boolean;
+ -- L, R are the Expressions values from two attribute nodes
+ -- for First or Last attributes. Either may be set to No_List
+ -- if no expressions are present (indicating subscript 1).
+ -- The result is True if both expressions represent the same
+ -- subscript (note that one case is where one subscript is
+ -- missing and the other is explicitly set to 1).
+
+ -----------------------
+ -- Is_Same_Subscript --
+ -----------------------
+
+ function Is_Same_Subscript (L, R : List_Id) return Boolean is
+ begin
+ if L = No_List then
+ if R = No_List then
+ return True;
+ else
+ return Expr_Value (First (R)) = Uint_1;
+ end if;
+
+ else
+ if R = No_List then
+ return Expr_Value (First (L)) = Uint_1;
+ else
+ return Expr_Value (First (L)) = Expr_Value (First (R));
+ end if;
+ end if;
+ end Is_Same_Subscript;
+
+ -- Start of processing for Is_Same_Value
+
begin
-- Values are the same if they are the same identifier and the
- -- identifier refers to a constant object (E_Constant)
+ -- identifier refers to a constant object (E_Constant). This
+ -- does not however apply to Float types, since we may have two
+ -- NaN values and they should never compare equal.
if Nkind (Lf) = N_Identifier and then Nkind (Rf) = N_Identifier
and then Entity (Lf) = Entity (Rf)
+ and then not Is_Floating_Point_Type (Etype (L))
and then (Ekind (Entity (Lf)) = E_Constant or else
Ekind (Entity (Lf)) = E_In_Parameter or else
Ekind (Entity (Lf)) = E_Loop_Parameter)
@@ -552,6 +605,7 @@ package body Sem_Eval is
and then Is_Entity_Name (Prefix (Lf))
and then Is_Entity_Name (Prefix (Rf))
and then Entity (Prefix (Lf)) = Entity (Prefix (Rf))
+ and then Is_Same_Subscript (Expressions (Lf), Expressions (Rf))
then
return True;
@@ -588,7 +642,9 @@ package body Sem_Eval is
elsif No (Ltyp) or else No (Rtyp) then
return Unknown;
- -- We only attempt compile time analysis for scalar values
+ -- We only attempt compile time analysis for scalar values, and
+ -- not for packed arrays represented as modular types, where the
+ -- semantics of comparison is quite different.
elsif not Is_Scalar_Type (Ltyp)
or else Is_Packed_Array_Type (Ltyp)
@@ -655,22 +711,46 @@ package body Sem_Eval is
-- attempt this optimization with generic types, since the type
-- bounds may not be meaningful in this case.
- if Is_Discrete_Type (Ltyp)
+ -- We are in danger of an infinite recursion here. It does not seem
+ -- useful to go more than one level deep, so the parameter Rec is
+ -- used to protect ourselves against this infinite recursion.
+
+ if not Rec
+ and then Is_Discrete_Type (Ltyp)
+ and then Is_Discrete_Type (Rtyp)
and then not Is_Generic_Type (Ltyp)
and then not Is_Generic_Type (Rtyp)
then
- if Is_Same_Value (R, Type_High_Bound (Ltyp)) then
- return LE;
+ -- See if we can get a decisive check against one operand and
+ -- a bound of the other operand (four possible tests here).
+
+ case Compile_Time_Compare (L, Type_Low_Bound (Rtyp), True) is
+ when LT => return LT;
+ when LE => return LE;
+ when EQ => return LE;
+ when others => null;
+ end case;
- elsif Is_Same_Value (R, Type_Low_Bound (Ltyp)) then
- return GE;
+ case Compile_Time_Compare (L, Type_High_Bound (Rtyp), True) is
+ when GT => return GT;
+ when GE => return GE;
+ when EQ => return GE;
+ when others => null;
+ end case;
- elsif Is_Same_Value (L, Type_High_Bound (Rtyp)) then
- return GE;
+ case Compile_Time_Compare (Type_Low_Bound (Ltyp), R, True) is
+ when GT => return GT;
+ when GE => return GE;
+ when EQ => return GE;
+ when others => null;
+ end case;
- elsif Is_Same_Value (L, Type_Low_Bound (Ltyp)) then
- return LE;
- end if;
+ case Compile_Time_Compare (Type_High_Bound (Ltyp), R, True) is
+ when LT => return LT;
+ when LE => return LE;
+ when EQ => return LE;
+ when others => null;
+ end case;
end if;
-- Next attempt is to decompose the expressions to extract
@@ -735,6 +815,17 @@ package body Sem_Eval is
return False;
end if;
+ -- If this is not a static expression and we are in configurable run
+ -- time mode, then we consider it not known at compile time. This
+ -- avoids anomalies where whether something is permitted with a given
+ -- configurable run-time library depends on how good the compiler is
+ -- at optimizing and knowing that things are constant when they
+ -- are non-static.
+
+ if Configurable_Run_Time_Mode and then not Is_Static_Expression (Op) then
+ return False;
+ end if;
+
-- If we have an entity name, then see if it is the name of a constant
-- and if so, test the corresponding constant value, or the name of
-- an enumeration literal, which is always a constant.
@@ -976,8 +1067,11 @@ package body Sem_Eval is
if Right_Int = 0 then
Apply_Compile_Time_Constraint_Error
- (N, "division by zero", CE_Divide_By_Zero);
+ (N, "division by zero",
+ CE_Divide_By_Zero,
+ Warn => not Stat);
return;
+
else
Result := Left_Int / Right_Int;
end if;
@@ -989,7 +1083,9 @@ package body Sem_Eval is
if Right_Int = 0 then
Apply_Compile_Time_Constraint_Error
- (N, "mod with zero divisor", CE_Divide_By_Zero);
+ (N, "mod with zero divisor",
+ CE_Divide_By_Zero,
+ Warn => not Stat);
return;
else
Result := Left_Int mod Right_Int;
@@ -1002,8 +1098,11 @@ package body Sem_Eval is
if Right_Int = 0 then
Apply_Compile_Time_Constraint_Error
- (N, "rem with zero divisor", CE_Divide_By_Zero);
+ (N, "rem with zero divisor",
+ CE_Divide_By_Zero,
+ Warn => not Stat);
return;
+
else
Result := Left_Int rem Right_Int;
end if;
@@ -1018,7 +1117,7 @@ package body Sem_Eval is
Result := Result mod Modulus (Ltype);
end if;
- Fold_Uint (N, Result);
+ Fold_Uint (N, Result, Stat);
end;
-- Cases where at least one operand is a real. We handle the cases
@@ -1063,11 +1162,9 @@ package body Sem_Eval is
Result := Left_Real / Right_Real;
end if;
- Fold_Ureal (N, Result);
+ Fold_Ureal (N, Result, Stat);
end;
end if;
-
- Set_Is_Static_Expression (N, Stat);
end Eval_Arithmetic_Op;
----------------------------
@@ -1185,7 +1282,7 @@ package body Sem_Eval is
Set_Etype (N, Etype (Right));
end if;
- Fold_Str (N, End_String);
+ Fold_Str (N, End_String, True);
end if;
end;
end Eval_Concatenation;
@@ -1279,13 +1376,35 @@ package body Sem_Eval is
Expr : Node_Id;
begin
+ -- Check for non-static context on index values
+
Expr := First (Expressions (N));
while Present (Expr) loop
Check_Non_Static_Context (Expr);
Next (Expr);
end loop;
- -- See if this is a constant array reference
+ -- If the indexed component appears in an object renaming declaration
+ -- then we do not want to try to evaluate it, since in this case we
+ -- need the identity of the array element.
+
+ if Nkind (Parent (N)) = N_Object_Renaming_Declaration then
+ return;
+
+ -- Similarly if the indexed component appears as the prefix of an
+ -- attribute we don't want to evaluate it, because at least for
+ -- some cases of attributes we need the identify (e.g. Access, Size)
+
+ elsif Nkind (Parent (N)) = N_Attribute_Reference then
+ return;
+ end if;
+
+ -- Note: there are other cases, such as the left side of an assignment,
+ -- or an OUT parameter for a call, where the replacement results in the
+ -- illegal use of a constant, But these cases are illegal in the first
+ -- place, so the replacement, though silly, is harmless.
+
+ -- Now see if this is a constant array reference
if List_Length (Expressions (N)) = 1
and then Is_Entity_Name (Prefix (N))
@@ -1446,7 +1565,7 @@ package body Sem_Eval is
end loop;
end if;
- Fold_Uint (N, From_Bits (Left_Bits, Etype (N)));
+ Fold_Uint (N, From_Bits (Left_Bits, Etype (N)), Stat);
end;
else
@@ -1454,20 +1573,18 @@ package body Sem_Eval is
if Nkind (N) = N_Op_And then
Fold_Uint (N,
- Test (Is_True (Left_Int) and then Is_True (Right_Int)));
+ Test (Is_True (Left_Int) and then Is_True (Right_Int)), Stat);
elsif Nkind (N) = N_Op_Or then
Fold_Uint (N,
- Test (Is_True (Left_Int) or else Is_True (Right_Int)));
+ Test (Is_True (Left_Int) or else Is_True (Right_Int)), Stat);
else
pragma Assert (Nkind (N) = N_Op_Xor);
Fold_Uint (N,
- Test (Is_True (Left_Int) xor Is_True (Right_Int)));
+ Test (Is_True (Left_Int) xor Is_True (Right_Int)), Stat);
end if;
end if;
-
- Set_Is_Static_Expression (N, Stat);
end;
end Eval_Logical_Op;
@@ -1601,9 +1718,8 @@ package body Sem_Eval is
Result := not Result;
end if;
- Fold_Uint (N, Test (Result));
+ Fold_Uint (N, Test (Result), True);
Warn_On_Known_Condition (N);
-
end Eval_Membership_Op;
------------------------
@@ -1613,7 +1729,7 @@ package body Sem_Eval is
procedure Eval_Named_Integer (N : Node_Id) is
begin
Fold_Uint (N,
- Expr_Value (Expression (Declaration_Node (Entity (N)))));
+ Expr_Value (Expression (Declaration_Node (Entity (N)))), True);
end Eval_Named_Integer;
---------------------
@@ -1623,7 +1739,7 @@ package body Sem_Eval is
procedure Eval_Named_Real (N : Node_Id) is
begin
Fold_Ureal (N,
- Expr_Value_R (Expression (Declaration_Node (Entity (N)))));
+ Expr_Value_R (Expression (Declaration_Node (Entity (N)))), True);
end Eval_Named_Real;
-------------------
@@ -1667,7 +1783,9 @@ package body Sem_Eval is
if Right_Int < 0 then
Apply_Compile_Time_Constraint_Error
- (N, "integer exponent negative", CE_Range_Check_Failed);
+ (N, "integer exponent negative",
+ CE_Range_Check_Failed,
+ Warn => not Stat);
return;
else
@@ -1681,7 +1799,7 @@ package body Sem_Eval is
Result := Result mod Modulus (Etype (N));
end if;
- Fold_Uint (N, Result);
+ Fold_Uint (N, Result, Stat);
end if;
end;
@@ -1698,19 +1816,19 @@ package body Sem_Eval is
if Right_Int < 0 then
Apply_Compile_Time_Constraint_Error
- (N, "zero ** negative integer", CE_Range_Check_Failed);
+ (N, "zero ** negative integer",
+ CE_Range_Check_Failed,
+ Warn => not Stat);
return;
else
- Fold_Ureal (N, Ureal_0);
+ Fold_Ureal (N, Ureal_0, Stat);
end if;
else
- Fold_Ureal (N, Left_Real ** Right_Int);
+ Fold_Ureal (N, Left_Real ** Right_Int, Stat);
end if;
end;
end if;
-
- Set_Is_Static_Expression (N, Stat);
end;
end Eval_Op_Expon;
@@ -1748,11 +1866,11 @@ package body Sem_Eval is
-- is an arbitrary but consistent definition.
if Is_Modular_Integer_Type (Typ) then
- Fold_Uint (N, Modulus (Typ) - 1 - Rint);
+ Fold_Uint (N, Modulus (Typ) - 1 - Rint, Stat);
else
pragma Assert (Is_Boolean_Type (Typ));
- Fold_Uint (N, Test (not Is_True (Rint)));
+ Fold_Uint (N, Test (not Is_True (Rint)), Stat);
end if;
Set_Is_Static_Expression (N, Stat);
@@ -1811,8 +1929,7 @@ package body Sem_Eval is
-- Fold the result of qualification
if Is_Discrete_Type (Target_Type) then
- Fold_Uint (N, Expr_Value (Operand));
- Set_Is_Static_Expression (N, Stat);
+ Fold_Uint (N, Expr_Value (Operand), Stat);
-- Preserve Print_In_Hex indication
@@ -1821,11 +1938,10 @@ package body Sem_Eval is
end if;
elsif Is_Real_Type (Target_Type) then
- Fold_Ureal (N, Expr_Value_R (Operand));
- Set_Is_Static_Expression (N, Stat);
+ Fold_Ureal (N, Expr_Value_R (Operand), Stat);
else
- Fold_Str (N, Strval (Get_String_Val (Operand)));
+ Fold_Str (N, Strval (Get_String_Val (Operand)), Stat);
if not Stat then
Set_Is_Static_Expression (N, False);
@@ -1836,10 +1952,13 @@ package body Sem_Eval is
return;
end if;
+ -- The expression may be foldable but not static
+
+ Set_Is_Static_Expression (N, Stat);
+
if Is_Out_Of_Range (N, Etype (N)) then
Out_Of_Range (N);
end if;
-
end Eval_Qualified_Expression;
-----------------------
@@ -1903,6 +2022,10 @@ package body Sem_Eval is
-- known at compile time length, then Len is set to this
-- (non-negative length). Otherwise Len is set to minus 1.
+ -----------------------
+ -- Get_Static_Length --
+ -----------------------
+
procedure Get_Static_Length (Op : Node_Id; Len : out Uint) is
T : Entity_Id;
@@ -1942,8 +2065,7 @@ package body Sem_Eval is
and then Len_R /= Uint_Minus_1
and then Len_L /= Len_R
then
- Fold_Uint (N, Test (Nkind (N) = N_Op_Ne));
- Set_Is_Static_Expression (N, False);
+ Fold_Uint (N, Test (Nkind (N) = N_Op_Ne), False);
Warn_On_Known_Condition (N);
return;
end if;
@@ -1986,7 +2108,7 @@ package body Sem_Eval is
raise Program_Error;
end case;
- Fold_Uint (N, Test (Result));
+ Fold_Uint (N, Test (Result), Stat);
end;
-- Real type case
@@ -2011,11 +2133,10 @@ package body Sem_Eval is
raise Program_Error;
end case;
- Fold_Uint (N, Test (Result));
+ Fold_Uint (N, Test (Result), Stat);
end;
end if;
- Set_Is_Static_Expression (N, Stat);
Warn_On_Known_Condition (N);
end Eval_Relational_Op;
@@ -2114,7 +2235,7 @@ package body Sem_Eval is
if (Kind = N_And_Then and then Is_False (Left_Int))
or else (Kind = N_Or_Else and Is_True (Left_Int))
then
- Fold_Uint (N, Left_Int);
+ Fold_Uint (N, Left_Int, Rstat);
return;
end if;
@@ -2132,9 +2253,8 @@ package body Sem_Eval is
-- Otherwise the result depends on the right operand
- Fold_Uint (N, Expr_Value (Right));
+ Fold_Uint (N, Expr_Value (Right), Rstat);
return;
-
end Eval_Short_Circuit;
----------------
@@ -2244,6 +2364,10 @@ package body Sem_Eval is
-- fixed-point type that is not to be treated as an integer (i.e. the
-- flag Conversion_OK is not set on the conversion node).
+ ------------------------------
+ -- To_Be_Treated_As_Integer --
+ ------------------------------
+
function To_Be_Treated_As_Integer (T : Entity_Id) return Boolean is
begin
return
@@ -2251,6 +2375,10 @@ package body Sem_Eval is
or else (Is_Fixed_Point_Type (T) and then Conversion_OK (N));
end To_Be_Treated_As_Integer;
+ ---------------------------
+ -- To_Be_Treated_As_Real --
+ ---------------------------
+
function To_Be_Treated_As_Real (T : Entity_Id) return Boolean is
begin
return
@@ -2292,8 +2420,7 @@ package body Sem_Eval is
-- Fold conversion, case of string type. The result is not static.
if Is_String_Type (Target_Type) then
- Fold_Str (N, Strval (Get_String_Val (Operand)));
- Set_Is_Static_Expression (N, False);
+ Fold_Str (N, Strval (Get_String_Val (Operand)), False);
return;
@@ -2322,12 +2449,12 @@ package body Sem_Eval is
if Is_Fixed_Point_Type (Target_Type) then
Fold_Ureal
- (N, UR_From_Uint (Result) * Small_Value (Target_Type));
+ (N, UR_From_Uint (Result) * Small_Value (Target_Type), Stat);
-- Otherwise result is integer literal
else
- Fold_Uint (N, Result);
+ Fold_Uint (N, Result, Stat);
end if;
end;
@@ -2344,17 +2471,15 @@ package body Sem_Eval is
Result := UR_From_Uint (Expr_Value (Operand));
end if;
- Fold_Ureal (N, Result);
+ Fold_Ureal (N, Result, Stat);
end;
-- Enumeration types
else
- Fold_Uint (N, Expr_Value (Operand));
+ Fold_Uint (N, Expr_Value (Operand), Stat);
end if;
- Set_Is_Static_Expression (N, Stat);
-
if Is_Out_Of_Range (N, Etype (N)) then
Out_Of_Range (N);
end if;
@@ -2412,7 +2537,7 @@ package body Sem_Eval is
Result := abs Rint;
end if;
- Fold_Uint (N, Result);
+ Fold_Uint (N, Result, Stat);
end;
-- Fold for real case
@@ -2434,12 +2559,9 @@ package body Sem_Eval is
Result := abs Rreal;
end if;
- Fold_Ureal (N, Result);
+ Fold_Ureal (N, Result, Stat);
end;
end if;
-
- Set_Is_Static_Expression (N, Stat);
-
end Eval_Unary_Op;
-------------------------------
@@ -2691,40 +2813,79 @@ package body Sem_Eval is
end if;
end Expr_Value_S;
+ --------------------------
+ -- Flag_Non_Static_Expr --
+ --------------------------
+
+ procedure Flag_Non_Static_Expr (Msg : String; Expr : Node_Id) is
+ begin
+ if Error_Posted (Expr) and then not All_Errors_Mode then
+ return;
+ else
+ Error_Msg_F (Msg, Expr);
+ Why_Not_Static (Expr);
+ end if;
+ end Flag_Non_Static_Expr;
+
--------------
-- Fold_Str --
--------------
- procedure Fold_Str (N : Node_Id; Val : String_Id) is
+ procedure Fold_Str (N : Node_Id; Val : String_Id; Static : Boolean) is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
begin
Rewrite (N, Make_String_Literal (Loc, Strval => Val));
- Analyze_And_Resolve (N, Typ);
+
+ -- 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.
+
+ Analyze (N);
+ Set_Is_Static_Expression (N, Static);
+ Set_Etype (N, Typ);
+ Resolve (N);
end Fold_Str;
---------------
-- Fold_Uint --
---------------
- procedure Fold_Uint (N : Node_Id; Val : Uint) is
+ procedure Fold_Uint (N : Node_Id; Val : Uint; Static : Boolean) is
Loc : constant Source_Ptr := Sloc (N);
- Typ : constant Entity_Id := Etype (N);
+ Typ : Entity_Id := Etype (N);
+ Ent : Entity_Id;
begin
+ -- If we are folding a named number, retain the entity in the
+ -- literal, for ASIS use.
+
+ if Is_Entity_Name (N)
+ and then Ekind (Entity (N)) = E_Named_Integer
+ then
+ Ent := Entity (N);
+ else
+ Ent := Empty;
+ end if;
+
+ if Is_Private_Type (Typ) then
+ Typ := Full_View (Typ);
+ end if;
+
-- For a result of type integer, subsitute an N_Integer_Literal node
-- for the result of the compile time evaluation of the expression.
- if Is_Integer_Type (Etype (N)) then
+ if Is_Integer_Type (Typ) then
Rewrite (N, Make_Integer_Literal (Loc, Val));
+ Set_Original_Entity (N, Ent);
-- Otherwise we have an enumeration type, and we substitute either
-- an N_Identifier or N_Character_Literal to represent the enumeration
-- literal corresponding to the given value, which must always be in
-- range, because appropriate tests have already been made for this.
- else pragma Assert (Is_Enumeration_Type (Etype (N)));
+ else pragma Assert (Is_Enumeration_Type (Typ));
Rewrite (N, Get_Enum_Lit_From_Pos (Etype (N), Val, Loc));
end if;
@@ -2733,26 +2894,41 @@ package body Sem_Eval is
-- that was evaluated.
Analyze (N);
+ Set_Is_Static_Expression (N, Static);
Set_Etype (N, Typ);
- Resolve (N, Typ);
+ Resolve (N);
end Fold_Uint;
----------------
-- Fold_Ureal --
----------------
- procedure Fold_Ureal (N : Node_Id; Val : Ureal) is
+ procedure Fold_Ureal (N : Node_Id; Val : Ureal; Static : Boolean) is
Loc : constant Source_Ptr := Sloc (N);
Typ : constant Entity_Id := Etype (N);
+ Ent : Entity_Id;
begin
+ -- If we are folding a named number, retain the entity in the
+ -- literal, for ASIS use.
+
+ if Is_Entity_Name (N)
+ and then Ekind (Entity (N)) = E_Named_Real
+ then
+ Ent := Entity (N);
+ else
+ Ent := Empty;
+ end if;
+
Rewrite (N, Make_Real_Literal (Loc, Realval => Val));
- Analyze (N);
+ Set_Original_Entity (N, Ent);
-- Both the actual and expected type comes from the original expression
+ Analyze (N);
+ Set_Is_Static_Expression (N, Static);
Set_Etype (N, Typ);
- Resolve (N, Typ);
+ Resolve (N);
end Fold_Ureal;
---------------
@@ -2794,6 +2970,15 @@ package body Sem_Eval is
end if;
end Get_String_Val;
+ ----------------
+ -- Initialize --
+ ----------------
+
+ procedure Initialize is
+ begin
+ CV_Cache := (others => (Node_High_Bound, Uint_0));
+ end Initialize;
+
--------------------
-- In_Subrange_Of --
--------------------
@@ -3112,7 +3297,7 @@ package body Sem_Eval is
elsif Is_Generic_Type (Typ) then
return False;
- -- Never out of range unless we have a compile time known value.
+ -- Never out of range unless we have a compile time known value
elsif not Compile_Time_Known_Value (N) then
return False;
@@ -3291,9 +3476,9 @@ package body Sem_Eval is
if Is_Static_Expression (N)
and then not In_Instance
+ and then not In_Inlined_Body
and then Ada_95
then
-
if Nkind (Parent (N)) = N_Defining_Identifier
and then Is_Array_Type (Parent (N))
and then Present (Packed_Array_Type (Parent (N)))
@@ -3313,10 +3498,8 @@ package body Sem_Eval is
-- in an instance, or when we have a non-static expression case.
else
- Warn_On_Instance := True;
Apply_Compile_Time_Constraint_Error
(N, "value not in range of}?", CE_Range_Check_Failed);
- Warn_On_Instance := False;
end if;
end Out_Of_Range;
@@ -3409,7 +3592,7 @@ package body Sem_Eval is
-- we???) but we do at least check that both types are
-- real, or both types are not real.
- elsif (Is_Real_Type (T1) /= Is_Real_Type (T2)) then
+ elsif Is_Real_Type (T1) /= Is_Real_Type (T2) then
return False;
-- Here we check the bounds
@@ -3832,4 +4015,256 @@ package body Sem_Eval is
end loop;
end To_Bits;
+ --------------------
+ -- Why_Not_Static --
+ --------------------
+
+ procedure Why_Not_Static (Expr : Node_Id) is
+ N : constant Node_Id := Original_Node (Expr);
+ Typ : Entity_Id;
+ E : Entity_Id;
+
+ procedure Why_Not_Static_List (L : List_Id);
+ -- A version that can be called on a list of expressions. Finds
+ -- all non-static violations in any element of the list.
+
+ -------------------------
+ -- Why_Not_Static_List --
+ -------------------------
+
+ procedure Why_Not_Static_List (L : List_Id) is
+ N : Node_Id;
+
+ begin
+ if Is_Non_Empty_List (L) then
+ N := First (L);
+ while Present (N) loop
+ Why_Not_Static (N);
+ Next (N);
+ end loop;
+ end if;
+ end Why_Not_Static_List;
+
+ -- Start of processing for Why_Not_Static
+
+ begin
+ -- If in ACATS mode (debug flag 2), then suppress all these
+ -- messages, this avoids massive updates to the ACATS base line.
+
+ if Debug_Flag_2 then
+ return;
+ end if;
+
+ -- Ignore call on error or empty node
+
+ if No (Expr) or else Nkind (Expr) = N_Error then
+ return;
+ end if;
+
+ -- Preprocessing for sub expressions
+
+ if Nkind (Expr) in N_Subexpr then
+
+ -- Nothing to do if expression is static
+
+ if Is_OK_Static_Expression (Expr) then
+ return;
+ end if;
+
+ -- Test for constraint error raised
+
+ if Raises_Constraint_Error (Expr) then
+ Error_Msg_N
+ ("expression raises exception, cannot be static " &
+ "('R'M 4.9(34))!", N);
+ return;
+ end if;
+
+ -- If no type, then something is pretty wrong, so ignore
+
+ Typ := Etype (Expr);
+
+ if No (Typ) then
+ return;
+ end if;
+
+ -- Type must be scalar or string type
+
+ if not Is_Scalar_Type (Typ)
+ and then not Is_String_Type (Typ)
+ then
+ Error_Msg_N
+ ("static expression must have scalar or string type " &
+ "('R'M 4.9(2))!", N);
+ return;
+ end if;
+ end if;
+
+ -- If we got through those checks, test particular node kind
+
+ case Nkind (N) is
+ when N_Expanded_Name | N_Identifier | N_Operator_Symbol =>
+ E := Entity (N);
+
+ if Is_Named_Number (E) then
+ null;
+
+ elsif Ekind (E) = E_Constant then
+ if not Is_Static_Expression (Constant_Value (E)) then
+ Error_Msg_NE
+ ("& is not a static constant ('R'M 4.9(5))!", N, E);
+ end if;
+
+ else
+ Error_Msg_NE
+ ("& is not static constant or named number " &
+ "('R'M 4.9(5))!", N, E);
+ end if;
+
+ when N_Binary_Op | N_And_Then | N_Or_Else | N_In | N_Not_In =>
+ if Nkind (N) in N_Op_Shift then
+ Error_Msg_N
+ ("shift functions are never static ('R'M 4.9(6,18))!", N);
+
+ else
+ Why_Not_Static (Left_Opnd (N));
+ Why_Not_Static (Right_Opnd (N));
+ end if;
+
+ when N_Unary_Op =>
+ Why_Not_Static (Right_Opnd (N));
+
+ when N_Attribute_Reference =>
+ Why_Not_Static_List (Expressions (N));
+
+ E := Etype (Prefix (N));
+
+ if E = Standard_Void_Type then
+ return;
+ end if;
+
+ -- Special case non-scalar'Size since this is a common error
+
+ if Attribute_Name (N) = Name_Size then
+ Error_Msg_N
+ ("size attribute is only static for scalar type " &
+ "('R'M 4.9(7,8))", N);
+
+ -- Flag array cases
+
+ elsif Is_Array_Type (E) then
+ if Attribute_Name (N) /= Name_First
+ and then
+ Attribute_Name (N) /= Name_Last
+ and then
+ Attribute_Name (N) /= Name_Length
+ then
+ Error_Msg_N
+ ("static array attribute must be Length, First, or Last " &
+ "('R'M 4.9(8))!", N);
+
+ -- Since we know the expression is not-static (we already
+ -- tested for this, must mean array is not static).
+
+ else
+ Error_Msg_N
+ ("prefix is non-static array ('R'M 4.9(8))!", Prefix (N));
+ end if;
+
+ return;
+
+ -- Special case generic types, since again this is a common
+ -- source of confusion.
+
+ elsif Is_Generic_Actual_Type (E)
+ or else
+ Is_Generic_Type (E)
+ then
+ Error_Msg_N
+ ("attribute of generic type is never static " &
+ "('R'M 4.9(7,8))!", N);
+
+ elsif Is_Static_Subtype (E) then
+ null;
+
+ elsif Is_Scalar_Type (E) then
+ Error_Msg_N
+ ("prefix type for attribute is not static scalar subtype " &
+ "('R'M 4.9(7))!", N);
+
+ else
+ Error_Msg_N
+ ("static attribute must apply to array/scalar type " &
+ "('R'M 4.9(7,8))!", N);
+ end if;
+
+ when N_String_Literal =>
+ Error_Msg_N
+ ("subtype of string literal is non-static ('R'M 4.9(4))!", N);
+
+ when N_Explicit_Dereference =>
+ Error_Msg_N
+ ("explicit dereference is never static ('R'M 4.9)!", N);
+
+ when N_Function_Call =>
+ Why_Not_Static_List (Parameter_Associations (N));
+ Error_Msg_N ("non-static function call ('R'M 4.9(6,18))!", N);
+
+ when N_Parameter_Association =>
+ Why_Not_Static (Explicit_Actual_Parameter (N));
+
+ when N_Indexed_Component =>
+ Error_Msg_N
+ ("indexed component is never static ('R'M 4.9)!", N);
+
+ when N_Procedure_Call_Statement =>
+ Error_Msg_N
+ ("procedure call is never static ('R'M 4.9)!", N);
+
+ when N_Qualified_Expression =>
+ Why_Not_Static (Expression (N));
+
+ when N_Aggregate | N_Extension_Aggregate =>
+ Error_Msg_N
+ ("an aggregate is never static ('R'M 4.9)!", N);
+
+ when N_Range =>
+ Why_Not_Static (Low_Bound (N));
+ Why_Not_Static (High_Bound (N));
+
+ when N_Range_Constraint =>
+ Why_Not_Static (Range_Expression (N));
+
+ when N_Subtype_Indication =>
+ Why_Not_Static (Constraint (N));
+
+ when N_Selected_Component =>
+ Error_Msg_N
+ ("selected component is never static ('R'M 4.9)!", N);
+
+ when N_Slice =>
+ Error_Msg_N
+ ("slice is never static ('R'M 4.9)!", N);
+
+ when N_Type_Conversion =>
+ Why_Not_Static (Expression (N));
+
+ if not Is_Scalar_Type (Etype (Prefix (N)))
+ or else not Is_Static_Subtype (Etype (Prefix (N)))
+ then
+ Error_Msg_N
+ ("static conversion requires static scalar subtype result " &
+ "('R'M 4.9(9))!", N);
+ end if;
+
+ when N_Unchecked_Type_Conversion =>
+ Error_Msg_N
+ ("unchecked type conversion is never static ('R'M 4.9)!", N);
+
+ when others =>
+ null;
+
+ end case;
+ end Why_Not_Static;
+
end Sem_Eval;