diff options
author | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-10-21 13:42:24 +0000 |
---|---|---|
committer | charlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-10-21 13:42:24 +0000 |
commit | 9dfe12ae5b94d03c997ea2903022a5d2d5c5f266 (patch) | |
tree | bdfc70477b60f1220cb05dd233a4570dd9c6bb5c /gcc/ada/sem_eval.adb | |
parent | 1c662558a1113238a624245a45382d3df90ccf13 (diff) | |
download | gcc-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.adb | 649 |
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; |