16 Star 0 Fork 14

ocs-upgrade/gcc

forked from OpenCloudOS Stream/gcc 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
gcc12-fortran-fdec-promotion.patch 71.91 KB
一键复制 编辑 原始数据 按行查看 历史
nilusyi 提交于 2022-10-25 14:34 . init repo
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093
From 7a27318818e359a277f2fa5f7dc3932d0fb950f5 Mon Sep 17 00:00:00 2001
From: Mark Eggleston <markeggleston@gcc.gnu.org>
Date: Fri, 22 Jan 2021 14:58:07 +0000
Subject: [PATCH 08/10] Support type promotion in calls to intrinsics
Use -fdec-promotion or -fdec to enable this feature.
Merged 2 commits: worked on by Ben Brewer <ben.brewer@codethink.co.uk>,
Francisco Redondo Marchena <francisco.marchena@codethink.co.uk> and
Jeff Law <law@redhat.com>
Re-worked by Mark Eggleston <mark.eggleston@codethink.com>
---
gcc/fortran/check.cc | 71 +++++-
gcc/fortran/intrinsic.cc | 5 +
gcc/fortran/iresolve.cc | 91 ++++---
gcc/fortran/lang.opt | 4 +
gcc/fortran/options.cc | 1 +
gcc/fortran/simplify.cc | 240 ++++++++++++++----
...trinsic_int_real_array_const_promotion_1.f | 18 ++
...trinsic_int_real_array_const_promotion_2.f | 18 ++
...trinsic_int_real_array_const_promotion_3.f | 18 ++
...dec_intrinsic_int_real_const_promotion_1.f | 90 +++++++
...dec_intrinsic_int_real_const_promotion_2.f | 90 +++++++
...dec_intrinsic_int_real_const_promotion_3.f | 92 +++++++
.../dec_intrinsic_int_real_promotion_1.f | 130 ++++++++++
.../dec_intrinsic_int_real_promotion_2.f | 130 ++++++++++
.../dec_intrinsic_int_real_promotion_3.f | 130 ++++++++++
.../dec_intrinsic_int_real_promotion_4.f | 118 +++++++++
.../dec_intrinsic_int_real_promotion_5.f | 118 +++++++++
.../dec_intrinsic_int_real_promotion_6.f | 118 +++++++++
.../dec_intrinsic_int_real_promotion_7.f | 118 +++++++++
.../gfortran.dg/dec_kind_promotion-1.f | 40 +++
.../gfortran.dg/dec_kind_promotion-2.f | 40 +++
.../gfortran.dg/dec_kind_promotion-3.f | 39 +++
22 files changed, 1639 insertions(+), 80 deletions(-)
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
create mode 100644 gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
diff --git a/gcc/fortran/check.cc b/gcc/fortran/check.cc
index 623c1cc470e..e20a834a860 100644
--- a/gcc/fortran/check.cc
+++ b/gcc/fortran/check.cc
@@ -1396,12 +1396,40 @@ gfc_check_allocated (gfc_expr *array)
}
+/* Check function where both arguments must be real or integer
+ and warn if they are different types. */
+
+bool
+check_int_real_promotion (gfc_expr *a, gfc_expr *b)
+{
+ gfc_expr *i;
+
+ if (!int_or_real_check (a, 0))
+ return false;
+
+ if (!int_or_real_check (b, 1))
+ return false;
+
+ if (a->ts.type != b->ts.type)
+ {
+ i = (a->ts.type != BT_REAL ? a : b);
+ gfc_warning_now (OPT_Wconversion, "Conversion from INTEGER to REAL "
+ "at %L might lose precision", &i->where);
+ }
+
+ return true;
+}
+
+
/* Common check function where the first argument must be real or
integer and the second argument must be the same as the first. */
bool
gfc_check_a_p (gfc_expr *a, gfc_expr *p)
{
+ if (flag_dec_promotion)
+ return check_int_real_promotion (a, p);
+
if (!int_or_real_check (a, 0))
return false;
@@ -3724,6 +3752,41 @@ check_rest (bt type, int kind, gfc_actual_arglist *arglist)
}
+/* Check function where all arguments of an argument list must be real
+ or integer. */
+
+static bool
+check_rest_int_real (gfc_actual_arglist *arglist)
+{
+ gfc_actual_arglist *arg, *tmp;
+ gfc_expr *x;
+ int m, n;
+
+ if (!min_max_args (arglist))
+ return false;
+
+ for (arg = arglist, n=1; arg; arg = arg->next, n++)
+ {
+ x = arg->expr;
+ if (x->ts.type != BT_INTEGER && x->ts.type != BT_REAL)
+ {
+ gfc_error ("%<a%d%> argument of %qs intrinsic at %L must be "
+ "INTEGER or REAL", n, gfc_current_intrinsic, &x->where);
+ return false;
+ }
+
+ for (tmp = arglist, m=1; tmp != arg; tmp = tmp->next, m++)
+ if (!gfc_check_conformance (tmp->expr, x,
+ "arguments 'a%d' and 'a%d' for "
+ "intrinsic '%s'", m, n,
+ gfc_current_intrinsic))
+ return false;
+ }
+
+ return true;
+}
+
+
bool
gfc_check_min_max (gfc_actual_arglist *arg)
{
@@ -3748,7 +3811,10 @@ gfc_check_min_max (gfc_actual_arglist *arg)
return false;
}
- return check_rest (x->ts.type, x->ts.kind, arg);
+ if (flag_dec_promotion && x->ts.type != BT_CHARACTER)
+ return check_rest_int_real (arg);
+ else
+ return check_rest (x->ts.type, x->ts.kind, arg);
}
@@ -5121,6 +5187,9 @@ gfc_check_shift (gfc_expr *i, gfc_expr *shift)
bool
gfc_check_sign (gfc_expr *a, gfc_expr *b)
{
+ if (flag_dec_promotion)
+ return check_int_real_promotion (a, b);
+
if (!int_or_real_check (a, 0))
return false;
diff --git a/gcc/fortran/intrinsic.cc b/gcc/fortran/intrinsic.cc
index e68eff8bdbb..81b3a24c2be 100644
--- a/gcc/fortran/intrinsic.cc
+++ b/gcc/fortran/intrinsic.cc
@@ -4467,6 +4467,11 @@ check_arglist (gfc_actual_arglist **ap, gfc_intrinsic_sym *sym,
if (ts.kind == 0)
ts.kind = actual->expr->ts.kind;
+ /* If kind promotion is allowed don't check for kind if it is smaller */
+ if (flag_dec_promotion && ts.type == BT_INTEGER)
+ if (actual->expr->ts.kind < ts.kind)
+ ts.kind = actual->expr->ts.kind;
+
if (!gfc_compare_types (&ts, &actual->expr->ts))
{
if (error_flag)
diff --git a/gcc/fortran/iresolve.cc b/gcc/fortran/iresolve.cc
index e17fe45f080..b9cdaff2499 100644
--- a/gcc/fortran/iresolve.cc
+++ b/gcc/fortran/iresolve.cc
@@ -834,19 +834,22 @@ gfc_resolve_dble (gfc_expr *f, gfc_expr
void
gfc_resolve_dim (gfc_expr *f, gfc_expr *a, gfc_expr *p)
{
- f->ts.type = a->ts.type;
if (p != NULL)
- f->ts.kind = gfc_kind_max (a,p);
- else
- f->ts.kind = a->ts.kind;
-
- if (p != NULL && a->ts.kind != p->ts.kind)
{
- if (a->ts.kind == gfc_kind_max (a,p))
- gfc_convert_type (p, &a->ts, 2);
+ f->ts.kind = gfc_kind_max (a,p);
+ if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
+ f->ts.type = BT_REAL;
else
- gfc_convert_type (a, &p->ts, 2);
+ f->ts.type = BT_INTEGER;
+
+ if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
+ gfc_convert_type (a, &f->ts, 2);
+
+ if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
+ gfc_convert_type (p, &f->ts, 2);
}
+ else
+ f->ts = a->ts;
f->value.function.name
= gfc_get_string ("__dim_%c%d", gfc_type_letter (f->ts.type),
@@ -1622,14 +1625,17 @@ gfc_resolve_minmax (const char *name, gf
/* Find the largest type kind. */
for (a = args->next; a; a = a->next)
{
+ if (a->expr-> ts.type == BT_REAL)
+ f->ts.type = BT_REAL;
+
if (a->expr->ts.kind > f->ts.kind)
f->ts.kind = a->expr->ts.kind;
}
- /* Convert all parameters to the required kind. */
+ /* Convert all parameters to the required type and/or kind. */
for (a = args; a; a = a->next)
{
- if (a->expr->ts.kind != f->ts.kind)
+ if (a->expr->ts.type != f->ts.type || a->expr->ts.kind != f->ts.kind)
gfc_convert_type (a->expr, &f->ts, 2);
}
@@ -2130,19 +2136,22 @@ gfc_resolve_minval (gfc_expr *f, gfc_exp
void
gfc_resolve_mod (gfc_expr *f, gfc_expr *a, gfc_expr *p)
{
- f->ts.type = a->ts.type;
if (p != NULL)
- f->ts.kind = gfc_kind_max (a,p);
- else
- f->ts.kind = a->ts.kind;
-
- if (p != NULL && a->ts.kind != p->ts.kind)
{
- if (a->ts.kind == gfc_kind_max (a,p))
- gfc_convert_type (p, &a->ts, 2);
+ f->ts.kind = gfc_kind_max (a,p);
+ if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
+ f->ts.type = BT_REAL;
else
- gfc_convert_type (a, &p->ts, 2);
+ f->ts.type = BT_INTEGER;
+
+ if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
+ gfc_convert_type (a, &f->ts, 2);
+
+ if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
+ gfc_convert_type (p, &f->ts, 2);
}
+ else
+ f->ts = a->ts;
f->value.function.name
= gfc_get_string ("__mod_%c%d", gfc_type_letter (f->ts.type),
@@ -2153,19 +2162,22 @@ gfc_resolve_mod (gfc_expr *f, gfc_expr *
void
gfc_resolve_modulo (gfc_expr *f, gfc_expr *a, gfc_expr *p)
{
- f->ts.type = a->ts.type;
if (p != NULL)
- f->ts.kind = gfc_kind_max (a,p);
- else
- f->ts.kind = a->ts.kind;
-
- if (p != NULL && a->ts.kind != p->ts.kind)
{
- if (a->ts.kind == gfc_kind_max (a,p))
- gfc_convert_type (p, &a->ts, 2);
+ f->ts.kind = gfc_kind_max (a,p);
+ if (a->ts.type == BT_REAL || p->ts.type == BT_REAL)
+ f->ts.type = BT_REAL;
else
- gfc_convert_type (a, &p->ts, 2);
+ f->ts.type = BT_INTEGER;
+
+ if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
+ gfc_convert_type (a, &f->ts, 2);
+
+ if (p->ts.kind != f->ts.kind || p->ts.type != f->ts.type)
+ gfc_convert_type (p, &f->ts, 2);
}
+ else
+ f->ts = a->ts;
f->value.function.name
= gfc_get_string ("__modulo_%c%d", gfc_type_letter (f->ts.type),
@@ -2543,9 +2555,26 @@ gfc_resolve_shift (gfc_expr *f, gfc_expr
void
-gfc_resolve_sign (gfc_expr *f, gfc_expr *a, gfc_expr *b ATTRIBUTE_UNUSED)
+gfc_resolve_sign (gfc_expr *f, gfc_expr *a, gfc_expr *b)
{
- f->ts = a->ts;
+ if (b != NULL)
+ {
+ f->ts.kind = gfc_kind_max (a, b);
+ if (a->ts.type == BT_REAL || b->ts.type == BT_REAL)
+ f->ts.type = BT_REAL;
+ else
+ f->ts.type = BT_INTEGER;
+
+ if (a->ts.kind != f->ts.kind || a->ts.type != f->ts.type)
+ gfc_convert_type (a, &f->ts, 2);
+
+ if (b->ts.kind != f->ts.kind || b->ts.type != f->ts.type)
+ gfc_convert_type (b, &f->ts, 2);
+ }
+ else
+ {
+ f->ts = a->ts;
+ }
f->value.function.name
= gfc_get_string ("__sign_%c%d", gfc_type_letter (a->ts.type),
gfc_type_abi_kind (&a->ts));
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index d886c2f33ed..4ca2f93f2df 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -505,6 +505,10 @@ fdec-old-init
Fortran Var(flag_dec_old_init)
Enable support for old style initializers in derived types.
+fdec-promotion
+Fortran Var(flag_dec_promotion)
+Add support for type promotion in intrinsic arguments.
+
fdec-structure
Fortran Var(flag_dec_structure)
Enable support for DEC STRUCTURE/RECORD.
diff --git a/gcc/fortran/options.cc b/gcc/fortran/options.cc
index a946c86790a..15079c7e95a 100644
--- a/gcc/fortran/options.cc
+++ b/gcc/fortran/options.cc
@@ -82,6 +82,7 @@ set_dec_flags (int value)
SET_BITFLAG (flag_dec_old_init, value, value);
SET_BITFLAG (flag_dec_override_kind, value, value);
SET_BITFLAG (flag_dec_non_logical_if, value, value);
+ SET_BITFLAG (flag_dec_promotion, value, value);
}
/* Finalize DEC flags. */
diff --git a/gcc/fortran/simplify.cc b/gcc/fortran/simplify.cc
index 9900572424f..3419e06fec2 100644
--- a/gcc/fortran/simplify.cc
+++ b/gcc/fortran/simplify.cc
@@ -2333,39 +2333,79 @@ gfc_simplify_digits (gfc_expr *x)
}
+/* Simplify function which sets the floating-point value of ar from
+ the value of a independently if a is integer of real. */
+
+static void
+simplify_int_real_promotion (const gfc_expr *a, const gfc_expr *b, mpfr_t *ar)
+{
+ if (a->ts.type == BT_REAL)
+ {
+ mpfr_init2 (*ar, (a->ts.kind * 8));
+ mpfr_set (*ar, a->value.real, GFC_RND_MODE);
+ }
+ else
+ {
+ mpfr_init2 (*ar, (b->ts.kind * 8));
+ mpfr_set_z (*ar, a->value.integer, GFC_RND_MODE);
+ }
+}
+
+
+/* Simplify function which promotes a and b arguments from integer to real if
+ required in ar and br floating-point values. This function returns true if
+ a or b are reals and false otherwise. */
+
+static bool
+simplify_int_real_promotion2 (const gfc_expr *a, const gfc_expr *b, mpfr_t *ar,
+ mpfr_t *br)
+{
+ if (a->ts.type != BT_REAL && b->ts.type != BT_REAL)
+ return false;
+
+ simplify_int_real_promotion (a, b, ar);
+ simplify_int_real_promotion (b, a, br);
+
+ return true;
+}
+
+
gfc_expr *
gfc_simplify_dim (gfc_expr *x, gfc_expr *y)
{
gfc_expr *result;
int kind;
+ mpfr_t xr;
+ mpfr_t yr;
+
if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
return NULL;
- kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
- result = gfc_get_constant_expr (x->ts.type, kind, &x->where);
-
- switch (x->ts.type)
+ if ((x->ts.type != BT_REAL && x->ts.type != BT_INTEGER)
+ || (y->ts.type != BT_REAL && y->ts.type != BT_INTEGER))
{
- case BT_INTEGER:
- if (mpz_cmp (x->value.integer, y->value.integer) > 0)
- mpz_sub (result->value.integer, x->value.integer, y->value.integer);
- else
- mpz_set_ui (result->value.integer, 0);
-
- break;
-
- case BT_REAL:
- if (mpfr_cmp (x->value.real, y->value.real) > 0)
- mpfr_sub (result->value.real, x->value.real, y->value.real,
- GFC_RND_MODE);
- else
- mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
+ gfc_internal_error ("gfc_simplify_dim(): Bad arguments");
+ return NULL;
+ }
- break;
+ kind = x->ts.kind > y->ts.kind ? x->ts.kind : y->ts.kind;
- default:
- gfc_internal_error ("gfc_simplify_dim(): Bad type");
+ if (simplify_int_real_promotion2 (x, y, &xr, &yr))
+ {
+ result = gfc_get_constant_expr (BT_REAL, kind, &x->where);
+ if (mpfr_cmp (xr, yr) > 0)
+ mpfr_sub (result->value.real, xr, yr, GFC_RND_MODE);
+ else
+ mpfr_set_ui (result->value.real, 0, GFC_RND_MODE);
+ }
+ else
+ {
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &x->where);
+ if (mpz_cmp (x->value.integer, y->value.integer) > 0)
+ mpz_sub (result->value.integer, x->value.integer, y->value.integer);
+ else
+ mpz_set_ui (result->value.integer, 0);
}
return range_check (result, "DIM");
@@ -4953,6 +4993,76 @@ min_max_choose (gfc_expr *arg, gfc_expr *extremum, int sign, bool back_val)
{
int ret;
+ mpfr_t *arp;
+ mpfr_t *erp;
+ mpfr_t ar;
+ mpfr_t er;
+
+ if (arg->ts.type != extremum->ts.type)
+ {
+ if (arg->ts.type == BT_REAL)
+ {
+ arp = &arg->value.real;
+ }
+ else
+ {
+ mpfr_init2 (ar, (arg->ts.kind * 8));
+ mpfr_set_z (ar, arg->value.integer, GFC_RND_MODE);
+ arp = &ar;
+ }
+
+ if (extremum->ts.type == BT_REAL)
+ {
+ erp = &extremum->value.real;
+ }
+ else
+ {
+ mpfr_init2 (er, (extremum->ts.kind * 8));
+ mpfr_set_z (er, extremum->value.integer, GFC_RND_MODE);
+ erp = &er;
+ }
+
+ if (mpfr_nan_p (*erp))
+ {
+ ret = 1;
+ extremum->ts.type = arg->ts.type;
+ extremum->ts.kind = arg->ts.kind;
+ if (arg->ts.type == BT_INTEGER)
+ {
+ mpz_init2 (extremum->value.integer, (arg->ts.kind * 8));
+ mpz_set (extremum->value.integer, arg->value.integer);
+ }
+ else
+ {
+ mpfr_init2 (extremum->value.real, (arg->ts.kind * 8));
+ mpfr_set (extremum->value.real, *arp, GFC_RND_MODE);
+ }
+ }
+ else if (mpfr_nan_p (*arp))
+ ret = -1;
+ else
+ {
+ ret = mpfr_cmp (*arp, *erp) * sign;
+ if (ret > 0)
+ {
+ extremum->ts.type = arg->ts.type;
+ extremum->ts.kind = arg->ts.kind;
+ if (arg->ts.type == BT_INTEGER)
+ {
+ mpz_init2 (extremum->value.integer, (arg->ts.kind * 8));
+ mpz_set (extremum->value.integer, arg->value.integer);
+ }
+ else
+ {
+ mpfr_init2 (extremum->value.real, (arg->ts.kind * 8));
+ mpfr_set (extremum->value.real, *arp, GFC_RND_MODE);
+ }
+ }
+ }
+
+ return ret;
+ }
+
switch (arg->ts.type)
{
case BT_INTEGER:
@@ -5912,7 +6022,9 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
gfc_expr *result;
int kind;
- /* First check p. */
+ mpfr_t ar;
+ mpfr_t pr;
+
if (p->expr_type != EXPR_CONSTANT)
return NULL;
@@ -5942,16 +6054,24 @@ gfc_simplify_mod (gfc_expr *a, gfc_expr *p)
if (a->expr_type != EXPR_CONSTANT)
return NULL;
+ if (a->ts.type != BT_REAL && a->ts.type != BT_INTEGER)
+ {
+ gfc_internal_error ("gfc_simplify_mod(): Bad arguments");
+ return NULL;
+ }
+
kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
- result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
- if (a->ts.type == BT_INTEGER)
- mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
- else
+ if (simplify_int_real_promotion2 (a, p, &ar, &pr))
{
+ result = gfc_get_constant_expr (BT_REAL, kind, &a->where);
gfc_set_model_kind (kind);
- mpfr_fmod (result->value.real, a->value.real, p->value.real,
- GFC_RND_MODE);
+ mpfr_fmod (result->value.real, ar, pr, GFC_RND_MODE);
+ }
+ else
+ {
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &a->where);
+ mpz_tdiv_r (result->value.integer, a->value.integer, p->value.integer);
}
return range_check (result, "MOD");
@@ -5964,7 +6084,9 @@ gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
gfc_expr *result;
int kind;
- /* First check p. */
+ mpfr_t ar;
+ mpfr_t pr;
+
if (p->expr_type != EXPR_CONSTANT)
return NULL;
@@ -5991,28 +6113,36 @@ gfc_simplify_modulo (gfc_expr *a, gfc_expr *p)
gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
}
+ if (a->ts.type != BT_REAL && a->ts.type != BT_INTEGER)
+ {
+ gfc_internal_error ("gfc_simplify_modulo(): Bad arguments");
+ return NULL;
+ }
+
if (a->expr_type != EXPR_CONSTANT)
return NULL;
kind = a->ts.kind > p->ts.kind ? a->ts.kind : p->ts.kind;
- result = gfc_get_constant_expr (a->ts.type, kind, &a->where);
- if (a->ts.type == BT_INTEGER)
- mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
- else
+ if (simplify_int_real_promotion2 (a, p, &ar, &pr))
{
+ result = gfc_get_constant_expr (BT_REAL, kind, &a->where);
gfc_set_model_kind (kind);
- mpfr_fmod (result->value.real, a->value.real, p->value.real,
- GFC_RND_MODE);
+ mpfr_fmod (result->value.real, ar, pr, GFC_RND_MODE);
if (mpfr_cmp_ui (result->value.real, 0) != 0)
- {
- if (mpfr_signbit (a->value.real) != mpfr_signbit (p->value.real))
- mpfr_add (result->value.real, result->value.real, p->value.real,
- GFC_RND_MODE);
- }
- else
- mpfr_copysign (result->value.real, result->value.real,
- p->value.real, GFC_RND_MODE);
+ {
+ if (mpfr_signbit (ar) != mpfr_signbit (pr))
+ mpfr_add (result->value.real, result->value.real, pr,
+ GFC_RND_MODE);
+ }
+ else
+ mpfr_copysign (result->value.real, result->value.real, pr,
+ GFC_RND_MODE);
+ }
+ else
+ {
+ result = gfc_get_constant_expr (BT_INTEGER, kind, &a->where);
+ mpz_fdiv_r (result->value.integer, a->value.integer, p->value.integer);
}
return range_check (result, "MODULO");
@@ -7578,27 +7708,41 @@ gfc_expr *
gfc_simplify_sign (gfc_expr *x, gfc_expr *y)
{
gfc_expr *result;
+ bool neg;
if (x->expr_type != EXPR_CONSTANT || y->expr_type != EXPR_CONSTANT)
return NULL;
result = gfc_get_constant_expr (x->ts.type, x->ts.kind, &x->where);
+ switch (y->ts.type)
+ {
+ case BT_INTEGER:
+ neg = (mpz_sgn (y->value.integer) < 0);
+ break;
+
+ case BT_REAL:
+ neg = (mpfr_sgn (y->value.real) < 0);
+ break;
+
+ default:
+ gfc_internal_error ("Bad type in gfc_simplify_sign");
+ }
+
switch (x->ts.type)
{
case BT_INTEGER:
mpz_abs (result->value.integer, x->value.integer);
- if (mpz_sgn (y->value.integer) < 0)
+ if (neg)
mpz_neg (result->value.integer, result->value.integer);
break;
case BT_REAL:
- if (flag_sign_zero)
+ if (flag_sign_zero && y->ts.type == BT_REAL)
mpfr_copysign (result->value.real, x->value.real, y->value.real,
- GFC_RND_MODE);
+ GFC_RND_MODE);
else
- mpfr_setsign (result->value.real, x->value.real,
- mpfr_sgn (y->value.real) < 0 ? 1 : 0, GFC_RND_MODE);
+ mpfr_setsign (result->value.real, x->value.real, neg, GFC_RND_MODE);
break;
default:
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
new file mode 100644
index 00000000000..25763852139
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_1.f
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-fdec" }
+!
+! Test promotion between integers and reals for mod and modulo where
+! A is a constant array and P is zero.
+!
+! Compilation errors are expected
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ program promotion_int_real_array_const
+ real a(2) = mod([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
+ a = mod([12.0, 34.0], 0)*4 ! { dg-error "shall not be zero" }
+ real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
+ b = modulo([12.0, 34.0], 0)*4 ! { dg-error "shall not be zero" }
+ end program
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
new file mode 100644
index 00000000000..b78a46054f4
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_2.f
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-fdec-promotion" }
+!
+! Test promotion between integers and reals for mod and modulo where
+! A is a constant array and P is zero.
+!
+! Compilation errors are expected
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ program promotion_int_real_array_const
+ real a(2) = mod([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
+ a = mod([12.0, 34.0], 0)*4 ! { dg-error "shall not be zero" }
+ real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "shall not be zero" }
+ b = modulo([12.0, 34.0], 0)*4 ! { dg-error "shall not be zero" }
+ end program
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
new file mode 100644
index 00000000000..318ab5db97e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_array_const_promotion_3.f
@@ -0,0 +1,18 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec-promotion" }
+!
+! Test promotion between integers and reals for mod and modulo where
+! A is a constant array and P is zero.
+!
+! Compilation errors are expected
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ program promotion_int_real_array_const
+ real a(2) = mod([12, 34], 0.0)*4 ! { dg-error "'a' and 'p' arguments of 'mod'" }
+ a = mod([12.0, 34.0], 0)*4 ! { dg-error "'a' and 'p' arguments of 'mod'" }
+ real b(2) = modulo([12, 34], 0.0)*4 ! { dg-error "'a' and 'p' arguments of 'modulo'" }
+ b = modulo([12.0, 34.0], 0)*4 ! { dg-error "'a' and 'p' arguments of 'modulo'" }
+ end program
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
new file mode 100644
index 00000000000..27eb2582bb2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_1.f
@@ -0,0 +1,90 @@
+! { dg-do run }
+! { dg-options "-fdec -finit-real=snan" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real_const
+ ! array_nan 4th position value is NAN
+ REAL array_nan(4)
+ DATA array_nan(1)/-4.0/
+ DATA array_nan(2)/3.0/
+ DATA array_nan(3)/-2/
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ m_i = MOD(4, 3)
+ if (m_i .ne. 1) STOP 1
+ m_r = MOD(4.0, 3.0)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 2
+ m_r = MOD(4, 3.0)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(4.0, 3)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+
+ md_i = MODULO(4, 3)
+ if (md_i .ne. 1) STOP 5
+ md_r = MODULO(4.0, 3.0)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 6
+ md_r = MODULO(4, 3.0)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 7
+ md_r = MODULO(4.0, 3)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 8
+
+ d_i = DIM(4, 3)
+ if (d_i .ne. 1) STOP 9
+ d_r = DIM(4.0, 3.0)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 10
+ d_r = DIM(4.0, 3)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 11
+ d_r = DIM(3, 4.0)
+ if (abs(d_r) > 1.0D-6) STOP 12
+
+ s_i = SIGN(-4, 3)
+ if (s_i .ne. 4) STOP 13
+ s_r = SIGN(4.0, -3.0)
+ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
+ s_r = SIGN(4.0, -3)
+ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
+ s_r = SIGN(-4, 3.0)
+ if (abs(s_r - 4.0) > 1.0D-6) STOP 16
+
+ mx_i = MAX(-4, -3, 2, 1)
+ if (mx_i .ne. 2) STOP 17
+ mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
+ if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
+ mx_r = MAX(-4, -3.0, 2.0, 1)
+ if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
+ mx_i = MAXLOC(array_nan, 1)
+ if (mx_i .ne. 2) STOP 20
+
+ mn_i = MIN(-4, -3, 2, 1)
+ if (mn_i .ne. -4) STOP 21
+ mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
+ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
+ mn_r = MIN(-4, -3.0, 2.0, 1)
+ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
+ mn_i = MINLOC(array_nan, 1)
+ if (mn_i .ne. 1) STOP 24
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
new file mode 100644
index 00000000000..bdd017b7280
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_2.f
@@ -0,0 +1,90 @@
+! { dg-do run }
+! { dg-options "-fdec-promotion -finit-real=snan" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real_const
+ ! array_nan 4th position value is NAN
+ REAL array_nan(4)
+ DATA array_nan(1)/-4.0/
+ DATA array_nan(2)/3.0/
+ DATA array_nan(3)/-2/
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ m_i = MOD(4, 3)
+ if (m_i .ne. 1) STOP 1
+ m_r = MOD(4.0, 3.0)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 2
+ m_r = MOD(4, 3.0)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(4.0, 3)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+
+ md_i = MODULO(4, 3)
+ if (md_i .ne. 1) STOP 5
+ md_r = MODULO(4.0, 3.0)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 6
+ md_r = MODULO(4, 3.0)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 7
+ md_r = MODULO(4.0, 3)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 8
+
+ d_i = DIM(4, 3)
+ if (d_i .ne. 1) STOP 9
+ d_r = DIM(4.0, 3.0)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 10
+ d_r = DIM(4.0, 3)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 11
+ d_r = DIM(3, 4.0)
+ if (abs(d_r) > 1.0D-6) STOP 12
+
+ s_i = SIGN(-4, 3)
+ if (s_i .ne. 4) STOP 13
+ s_r = SIGN(4.0, -3.0)
+ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
+ s_r = SIGN(4.0, -3)
+ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
+ s_r = SIGN(-4, 3.0)
+ if (abs(s_r - 4.0) > 1.0D-6) STOP 16
+
+ mx_i = MAX(-4, -3, 2, 1)
+ if (mx_i .ne. 2) STOP 17
+ mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
+ if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
+ mx_r = MAX(-4, -3.0, 2.0, 1)
+ if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
+ mx_i = MAXLOC(array_nan, 1)
+ if (mx_i .ne. 2) STOP 20
+
+ mn_i = MIN(-4, -3, 2, 1)
+ if (mn_i .ne. -4) STOP 21
+ mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
+ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
+ mn_r = MIN(-4, -3.0, 2.0, 1)
+ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
+ mn_i = MINLOC(array_nan, 1)
+ if (mn_i .ne. 1) STOP 24
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
new file mode 100644
index 00000000000..ce90a5667d6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_const_promotion_3.f
@@ -0,0 +1,92 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec-promotion -finit-real=snan" }
+!
+! Test that there is no promotion between integers and reals in
+! intrinsic operations.
+!
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real_const
+ ! array_nan 4th position value is NAN
+ REAL array_nan(4)
+ DATA array_nan(1)/-4.0/
+ DATA array_nan(2)/3.0/
+ DATA array_nan(3)/-2/
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ m_i = MOD(4, 3)
+ if (m_i .ne. 1) STOP 1
+ m_r = MOD(4.0, 3.0)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 2
+ m_r = MOD(4, 3.0) ! { dg-error "'a' and 'p' arguments" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(4.0, 3) ! { dg-error "'a' and 'p' arguments" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+
+ md_i = MODULO(4, 3)
+ if (md_i .ne. 1) STOP 5
+ md_r = MODULO(4.0, 3.0)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 6
+ md_r = MODULO(4, 3.0) ! { dg-error "'a' and 'p' arguments" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 7
+ md_r = MODULO(4.0, 3) ! { dg-error "'a' and 'p' arguments" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 8
+
+ d_i = DIM(4, 3)
+ if (d_i .ne. 1) STOP 9
+ d_r = DIM(4.0, 3.0)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 10
+ d_r = DIM(4.0, 3) ! { dg-error "'x' and 'y' arguments" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 11
+ d_r = DIM(3, 4.0) ! { dg-error "'x' and 'y' arguments" }
+ if (abs(d_r) > 1.0D-6) STOP 12
+
+ s_i = SIGN(-4, 3)
+ if (s_i .ne. 4) STOP 13
+ s_r = SIGN(4.0, -3.0)
+ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 14
+ s_r = SIGN(4.0, -3) ! { dg-error "'b' argument" }
+ if (abs(s_r - (-4.0)) > 1.0D-6) STOP 15
+ s_r = SIGN(-4, 3.0) ! { dg-error "'b' argument" }
+ if (abs(s_r - 4.0) > 1.0D-6) STOP 16
+
+ mx_i = MAX(-4, -3, 2, 1)
+ if (mx_i .ne. 2) STOP 17
+ mx_r = MAX(-4.0, -3.0, 2.0, 1.0)
+ if (abs(mx_r - 2.0) > 1.0D-6) STOP 18
+ mx_r = MAX(-4, -3.0, 2.0, 1) ! { dg-error "'a2' argument" }
+ if (abs(mx_r - 2.0) > 1.0D-6) STOP 19
+ mx_i = MAXLOC(array_nan, 1)
+ if (mx_i .ne. 2) STOP 20
+
+ mn_i = MIN(-4, -3, 2, 1)
+ if (mn_i .ne. -4) STOP 21
+ mn_r = MIN(-4.0, -3.0, 2.0, 1.0)
+ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 22
+ mn_r = MIN(-4, -3.0, 2.0, 1) ! { dg-error "'a2' argument" }
+ if (abs(mn_r - (-4.0)) > 1.0D-6) STOP 23
+ mn_i = MINLOC(array_nan, 1)
+ if (mn_i .ne. 1) STOP 24
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
new file mode 100644
index 00000000000..5c2cd931a4b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_1.f
@@ -0,0 +1,130 @@
+! { dg-do run }
+! { dg-options "-fdec" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real
+ REAL l/0.0/
+ INTEGER a_i/4/
+ INTEGER*4 a2_i/4/
+ INTEGER b_i/3/
+ INTEGER*8 b2_i/3/
+ INTEGER x_i/2/
+ INTEGER y_i/1/
+ REAL a_r/4.0/
+ REAL*4 a2_r/4.0/
+ REAL b_r/3.0/
+ REAL*8 b2_r/3.0/
+ REAL x_r/2.0/
+ REAL y_r/1.0/
+
+ REAL array_nan(4)
+ DATA array_nan(1)/-4.0/
+ DATA array_nan(2)/3.0/
+ DATA array_nan(3)/-2/
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ ! array_nan 4th position value is NAN
+ array_nan(4) = 0/l
+
+ m_i = MOD(a_i, b_i)
+ if (m_i .ne. 1) STOP 1
+ m_i = MOD(a2_i, b2_i)
+ if (m_i .ne. 1) STOP 2
+ m_r = MOD(a_r, b_r)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(a2_r, b2_r)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+ m_r = MOD(a_i, b_r)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
+ m_r = MOD(a_r, b_i)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
+
+ md_i = MODULO(a_i, b_i)
+ if (md_i .ne. 1) STOP 7
+ md_i = MODULO(a2_i, b2_i)
+ if (md_i .ne. 1) STOP 8
+ md_r = MODULO(a_r, b_r)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
+ md_r = MODULO(a2_r, b2_r)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
+ md_r = MODULO(a_i, b_r)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
+ md_r = MODULO(a_r, b_i)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
+
+ d_i = DIM(a_i, b_i)
+ if (d_i .ne. 1) STOP 13
+ d_i = DIM(a2_i, b2_i)
+ if (d_i .ne. 1) STOP 14
+ d_r = DIM(a_r, b_r)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
+ d_r = DIM(a2_r, b2_r)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
+ d_r = DIM(a_r, b_i)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
+ d_r = DIM(b_i, a_r)
+ if (abs(d_r) > 1.0D-6) STOP 18
+
+ s_i = SIGN(-a_i, b_i)
+ if (s_i .ne. 4) STOP 19
+ s_i = SIGN(-a2_i, b2_i)
+ if (s_i .ne. 4) STOP 20
+ s_r = SIGN(a_r, -b_r)
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
+ s_r = SIGN(a2_r, -b2_r)
+ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
+ s_r = SIGN(a_r, -b_i)
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
+ s_r = SIGN(-a_i, b_r)
+ if (abs(s_r - a_r) > 1.0D-6) STOP 24
+
+ mx_i = MAX(-a_i, -b_i, x_i, y_i)
+ if (mx_i .ne. x_i) STOP 25
+ mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
+ if (mx_i .ne. x_i) STOP 26
+ mx_r = MAX(-a_r, -b_r, x_r, y_r)
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
+ mx_r = MAX(-a_r, -b_r, x_r, y_r)
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
+ mx_r = MAX(-a_i, -b_r, x_r, y_i)
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
+ mx_i = MAXLOC(array_nan, 1)
+ if (mx_i .ne. 2) STOP 30
+
+ mn_i = MIN(-a_i, -b_i, x_i, y_i)
+ if (mn_i .ne. -a_i) STOP 31
+ mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
+ if (mn_i .ne. -a2_i) STOP 32
+ mn_r = MIN(-a_r, -b_r, x_r, y_r)
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
+ mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
+ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
+ mn_r = MIN(-a_i, -b_r, x_r, y_i)
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
+ mn_i = MINLOC(array_nan, 1)
+ if (mn_i .ne. 1) STOP 36
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
new file mode 100644
index 00000000000..d64d468f7d1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_2.f
@@ -0,0 +1,130 @@
+! { dg-do run }
+! { dg-options "-fdec-promotion" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real
+ REAL l/0.0/
+ INTEGER a_i/4/
+ INTEGER*4 a2_i/4/
+ INTEGER b_i/3/
+ INTEGER*8 b2_i/3/
+ INTEGER x_i/2/
+ INTEGER y_i/1/
+ REAL a_r/4.0/
+ REAL*4 a2_r/4.0/
+ REAL b_r/3.0/
+ REAL*8 b2_r/3.0/
+ REAL x_r/2.0/
+ REAL y_r/1.0/
+
+ REAL array_nan(4)
+ DATA array_nan(1)/-4.0/
+ DATA array_nan(2)/3.0/
+ DATA array_nan(3)/-2/
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ ! array_nan 4th position value is NAN
+ array_nan(4) = 0/l
+
+ m_i = MOD(a_i, b_i)
+ if (m_i .ne. 1) STOP 1
+ m_i = MOD(a2_i, b2_i)
+ if (m_i .ne. 1) STOP 2
+ m_r = MOD(a_r, b_r)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(a2_r, b2_r)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+ m_r = MOD(a_i, b_r)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
+ m_r = MOD(a_r, b_i)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
+
+ md_i = MODULO(a_i, b_i)
+ if (md_i .ne. 1) STOP 7
+ md_i = MODULO(a2_i, b2_i)
+ if (md_i .ne. 1) STOP 8
+ md_r = MODULO(a_r, b_r)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
+ md_r = MODULO(a2_r, b2_r)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
+ md_r = MODULO(a_i, b_r)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
+ md_r = MODULO(a_r, b_i)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
+
+ d_i = DIM(a_i, b_i)
+ if (d_i .ne. 1) STOP 13
+ d_i = DIM(a2_i, b2_i)
+ if (d_i .ne. 1) STOP 14
+ d_r = DIM(a_r, b_r)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
+ d_r = DIM(a2_r, b2_r)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
+ d_r = DIM(a_r, b_i)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
+ d_r = DIM(b_i, a_r)
+ if (abs(d_r) > 1.0D-6) STOP 18
+
+ s_i = SIGN(-a_i, b_i)
+ if (s_i .ne. 4) STOP 19
+ s_i = SIGN(-a2_i, b2_i)
+ if (s_i .ne. 4) STOP 20
+ s_r = SIGN(a_r, -b_r)
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
+ s_r = SIGN(a2_r, -b2_r)
+ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
+ s_r = SIGN(a_r, -b_i)
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
+ s_r = SIGN(-a_i, b_r)
+ if (abs(s_r - a_r) > 1.0D-6) STOP 24
+
+ mx_i = MAX(-a_i, -b_i, x_i, y_i)
+ if (mx_i .ne. x_i) STOP 25
+ mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
+ if (mx_i .ne. x_i) STOP 26
+ mx_r = MAX(-a_r, -b_r, x_r, y_r)
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
+ mx_r = MAX(-a_r, -b_r, x_r, y_r)
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
+ mx_r = MAX(-a_i, -b_r, x_r, y_i)
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
+ mx_i = MAXLOC(array_nan, 1)
+ if (mx_i .ne. 2) STOP 30
+
+ mn_i = MIN(-a_i, -b_i, x_i, y_i)
+ if (mn_i .ne. -a_i) STOP 31
+ mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
+ if (mn_i .ne. -a2_i) STOP 32
+ mn_r = MIN(-a_r, -b_r, x_r, y_r)
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
+ mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
+ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
+ mn_r = MIN(-a_i, -b_r, x_r, y_i)
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
+ mn_i = MINLOC(array_nan, 1)
+ if (mn_i .ne. 1) STOP 36
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
new file mode 100644
index 00000000000..0708b666633
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_3.f
@@ -0,0 +1,130 @@
+! { dg-do compile }
+! { dg-options "-fdec -fno-dec-promotion" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real
+ REAL l/0.0/
+ INTEGER a_i/4/
+ INTEGER*4 a2_i/4/
+ INTEGER b_i/3/
+ INTEGER*8 b2_i/3/
+ INTEGER x_i/2/
+ INTEGER y_i/1/
+ REAL a_r/4.0/
+ REAL*4 a2_r/4.0/
+ REAL b_r/3.0/
+ REAL*8 b2_r/3.0/
+ REAL x_r/2.0/
+ REAL y_r/1.0/
+
+ REAL array_nan(4)
+ DATA array_nan(1)/-4.0/
+ DATA array_nan(2)/3.0/
+ DATA array_nan(3)/-2/
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ ! array_nan 4th position value is NAN
+ array_nan(4) = 0/l
+
+ m_i = MOD(a_i, b_i)
+ if (m_i .ne. 1) STOP 1
+ m_i = MOD(a2_i, b2_i)
+ if (m_i .ne. 1) STOP 2
+ m_r = MOD(a_r, b_r)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(a2_r, b2_r)
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+ m_r = MOD(a_i, b_r) ! { dg-error "'a' and 'p' arguments" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
+ m_r = MOD(a_r, b_i) ! { dg-error "'a' and 'p' arguments" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
+
+ md_i = MODULO(a_i, b_i)
+ if (md_i .ne. 1) STOP 7
+ md_i = MODULO(a2_i, b2_i)
+ if (md_i .ne. 1) STOP 8
+ md_r = MODULO(a_r, b_r)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
+ md_r = MODULO(a2_r, b2_r)
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
+ md_r = MODULO(a_i, b_r) ! { dg-error "'a' and 'p' arguments" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
+ md_r = MODULO(a_r, b_i) ! { dg-error "'a' and 'p' arguments" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
+
+ d_i = DIM(a_i, b_i)
+ if (d_i .ne. 1) STOP 13
+ d_i = DIM(a2_i, b2_i)
+ if (d_i .ne. 1) STOP 14
+ d_r = DIM(a_r, b_r)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
+ d_r = DIM(a2_r, b2_r)
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
+ d_r = DIM(a_r, b_i) ! { dg-error "'x' and 'y' arguments" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
+ d_r = DIM(b_i, a_r) ! { dg-error "'x' and 'y' arguments" }
+ if (abs(d_r) > 1.0D-6) STOP 18
+
+ s_i = SIGN(-a_i, b_i)
+ if (s_i .ne. 4) STOP 19
+ s_i = SIGN(-a2_i, b2_i) ! { dg-error "'b' argument" }
+ if (s_i .ne. 4) STOP 20
+ s_r = SIGN(a_r, -b_r)
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
+ s_r = SIGN(a2_r, -b2_r) ! { dg-error "'b' argument" }
+ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
+ s_r = SIGN(a_r, -b_i) ! { dg-error "'b' argument" }
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
+ s_r = SIGN(-a_i, b_r) ! { dg-error "'b' argument" }
+ if (abs(s_r - a_r) > 1.0D-6) STOP 24
+
+ mx_i = MAX(-a_i, -b_i, x_i, y_i)
+ if (mx_i .ne. x_i) STOP 25
+ mx_i = MAX(-a2_i, -b2_i, x_i, y_i)
+ if (mx_i .ne. x_i) STOP 26
+ mx_r = MAX(-a_r, -b_r, x_r, y_r)
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
+ mx_r = MAX(-a_r, -b_r, x_r, y_r)
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
+ mx_r = MAX(-a_i, -b_r, x_r, y_i) ! { dg-error "'a2' argument" }
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
+ mx_i = MAXLOC(array_nan, 1)
+ if (mx_i .ne. 2) STOP 30
+
+ mn_i = MIN(-a_i, -b_i, x_i, y_i)
+ if (mn_i .ne. -a_i) STOP 31
+ mn_i = MIN(-a2_i, -b2_i, x_i, y_i)
+ if (mn_i .ne. -a2_i) STOP 32
+ mn_r = MIN(-a_r, -b_r, x_r, y_r)
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
+ mn_r = MIN(-a2_r, -b2_r, x_r, y_r)
+ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
+ mn_r = MIN(-a_i, -b_r, x_r, y_i) ! { dg-error "'a2' argument" }
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
+ mn_i = MINLOC(array_nan, 1)
+ if (mn_i .ne. 1) STOP 36
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
new file mode 100644
index 00000000000..efa4f236410
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_4.f
@@ -0,0 +1,118 @@
+! { dg-do compile }
+! { dg-options "-fdec" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real
+ REAL l/0.0/
+ LOGICAL a_l
+ LOGICAL*4 a2_l
+ LOGICAL b_l
+ LOGICAL*8 b2_l
+ LOGICAL x_l
+ LOGICAL y_l
+ CHARACTER a_c
+ CHARACTER*4 a2_c
+ CHARACTER b_c
+ CHARACTER*8 b2_c
+ CHARACTER x_c
+ CHARACTER y_c
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ m_i = MOD(a_l, b_l) ! { dg-error "" }
+ if (m_i .ne. 1) STOP 1
+ m_i = MOD(a2_l, b2_l) ! { dg-error "" }
+ if (m_i .ne. 1) STOP 2
+ m_r = MOD(a_c, b_c) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(a2_c, b2_c) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+ m_r = MOD(a_l, b_c) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
+ m_r = MOD(a_c, b_l) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
+
+ md_i = MODULO(a_l, b_l) ! { dg-error "" }
+ if (md_i .ne. 1) STOP 7
+ md_i = MODULO(a2_l, b2_l) ! { dg-error "" }
+ if (md_i .ne. 1) STOP 8
+ md_r = MODULO(a_c, b_c) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
+ md_r = MODULO(a2_c, b2_c) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
+ md_r = MODULO(a_l, b_c) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
+ md_r = MODULO(a_c, b_l) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
+
+ d_i = DIM(a_l, b_l) ! { dg-error "" }
+ if (d_i .ne. 1) STOP 13
+ d_i = DIM(a2_l, b2_l) ! { dg-error "" }
+ if (d_i .ne. 1) STOP 14
+ d_r = DIM(a_c, b_c) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
+ d_r = DIM(a2_c, b2_c) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
+ d_r = DIM(a_c, b_l) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
+ d_r = DIM(b_l, a_c) ! { dg-error "" }
+ if (abs(d_r) > 1.0D-6) STOP 18
+
+ s_i = SIGN(-a_l, b_l) ! { dg-error "" }
+ if (s_i .ne. 4) STOP 19
+ s_i = SIGN(-a2_l, b2_l) ! { dg-error "" }
+ if (s_i .ne. 4) STOP 20
+ s_r = SIGN(a_c, -b_c) ! { dg-error "" }
+ if (abs(s_r - (-a_c)) > 1.0D-6) STOP 21 ! { dg-error "" }
+ s_r = SIGN(a2_c, -b2_c) ! { dg-error "" }
+ if (abs(s_r - (-a2_c)) > 1.0D-6) STOP 22 ! { dg-error "" }
+ s_r = SIGN(a_c, -b_l) ! { dg-error "" }
+ if (abs(s_r - (-a_c)) > 1.0D-6) STOP 23 ! { dg-error "" }
+ s_r = SIGN(-a_l, b_c) ! { dg-error "" }
+ if (abs(s_r - a_c) > 1.0D-6) STOP 24 ! { dg-error "" }
+
+ mx_i = MAX(-a_l, -b_l, x_l, y_l) ! { dg-error "" }
+ if (mx_i .ne. x_l) STOP 25 ! { dg-error "" }
+ mx_i = MAX(-a2_l, -b2_l, x_l, y_l) ! { dg-error "" }
+ if (mx_i .ne. x_l) STOP 26 ! { dg-error "" }
+ mx_r = MAX(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
+ if (abs(mx_r - x_c) > 1.0D-6) STOP 27 ! { dg-error "" }
+ mx_r = MAX(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
+ if (abs(mx_r - x_c) > 1.0D-6) STOP 28 ! { dg-error "" }
+ mx_r = MAX(-a_l, -b_c, x_c, y_l) ! { dg-error "" }
+ if (abs(mx_r - x_c) > 1.0D-6) STOP 29 ! { dg-error "" }
+
+ mn_i = MIN(-a_l, -b_l, x_l, y_l) ! { dg-error "" }
+ if (mn_i .ne. -a_l) STOP 31 ! { dg-error "" }
+ mn_i = MIN(-a2_l, -b2_l, x_l, y_l) ! { dg-error "" }
+ if (mn_i .ne. -a2_l) STOP 32 ! { dg-error "" }
+ mn_r = MIN(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
+ if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 33 ! { dg-error "" }
+ mn_r = MIN(-a2_c, -b2_c, x_c, y_c) ! { dg-error "" }
+ if (abs(mn_r - (-a2_c)) > 1.0D-6) STOP 34 ! { dg-error "" }
+ mn_r = MIN(-a_l, -b_c, x_c, y_l) ! { dg-error "" }
+ if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 35 ! { dg-error "" }
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
new file mode 100644
index 00000000000..d023af5086d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_5.f
@@ -0,0 +1,118 @@
+! { dg-do compile }
+! { dg-options "-fdec-promotion" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real
+ REAL l/0.0/
+ LOGICAL a_l
+ LOGICAL*4 a2_l
+ LOGICAL b_l
+ LOGICAL*8 b2_l
+ LOGICAL x_l
+ LOGICAL y_l
+ CHARACTER a_c
+ CHARACTER*4 a2_c
+ CHARACTER b_c
+ CHARACTER*8 b2_c
+ CHARACTER x_c
+ CHARACTER y_c
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ m_i = MOD(a_l, b_l) ! { dg-error "" }
+ if (m_i .ne. 1) STOP 1
+ m_i = MOD(a2_l, b2_l) ! { dg-error "" }
+ if (m_i .ne. 1) STOP 2
+ m_r = MOD(a_c, b_c) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(a2_c, b2_c) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+ m_r = MOD(a_l, b_c) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
+ m_r = MOD(a_c, b_l) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
+
+ md_i = MODULO(a_l, b_l) ! { dg-error "" }
+ if (md_i .ne. 1) STOP 7
+ md_i = MODULO(a2_l, b2_l) ! { dg-error "" }
+ if (md_i .ne. 1) STOP 8
+ md_r = MODULO(a_c, b_c) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
+ md_r = MODULO(a2_c, b2_c) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
+ md_r = MODULO(a_l, b_c) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
+ md_r = MODULO(a_c, b_l) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
+
+ d_i = DIM(a_l, b_l) ! { dg-error "" }
+ if (d_i .ne. 1) STOP 13
+ d_i = DIM(a2_l, b2_l) ! { dg-error "" }
+ if (d_i .ne. 1) STOP 14
+ d_r = DIM(a_c, b_c) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
+ d_r = DIM(a2_c, b2_c) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
+ d_r = DIM(a_c, b_l) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
+ d_r = DIM(b_l, a_c) ! { dg-error "" }
+ if (abs(d_r) > 1.0D-6) STOP 18
+
+ s_i = SIGN(-a_l, b_l) ! { dg-error "" }
+ if (s_i .ne. 4) STOP 19
+ s_i = SIGN(-a2_l, b2_l) ! { dg-error "" }
+ if (s_i .ne. 4) STOP 20
+ s_r = SIGN(a_c, -b_c) ! { dg-error "" }
+ if (abs(s_r - (-a_c)) > 1.0D-6) STOP 21 ! { dg-error "" }
+ s_r = SIGN(a2_c, -b2_c) ! { dg-error "" }
+ if (abs(s_r - (-a2_c)) > 1.0D-6) STOP 22 ! { dg-error "" }
+ s_r = SIGN(a_c, -b_l) ! { dg-error "" }
+ if (abs(s_r - (-a_c)) > 1.0D-6) STOP 23 ! { dg-error "" }
+ s_r = SIGN(-a_l, b_c) ! { dg-error "" }
+ if (abs(s_r - a_c) > 1.0D-6) STOP 24 ! { dg-error "" }
+
+ mx_i = MAX(-a_l, -b_l, x_l, y_l) ! { dg-error "" }
+ if (mx_i .ne. x_l) STOP 25 ! { dg-error "" }
+ mx_i = MAX(-a2_l, -b2_l, x_l, y_l) ! { dg-error "" }
+ if (mx_i .ne. x_l) STOP 26 ! { dg-error "" }
+ mx_r = MAX(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
+ if (abs(mx_r - x_c) > 1.0D-6) STOP 27 ! { dg-error "" }
+ mx_r = MAX(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
+ if (abs(mx_r - x_c) > 1.0D-6) STOP 28 ! { dg-error "" }
+ mx_r = MAX(-a_l, -b_c, x_c, y_l) ! { dg-error "" }
+ if (abs(mx_r - x_c) > 1.0D-6) STOP 29 ! { dg-error "" }
+
+ mn_i = MIN(-a_l, -b_l, x_l, y_l) ! { dg-error "" }
+ if (mn_i .ne. -a_l) STOP 31 ! { dg-error "" }
+ mn_i = MIN(-a2_l, -b2_l, x_l, y_l) ! { dg-error "" }
+ if (mn_i .ne. -a2_l) STOP 32 ! { dg-error "" }
+ mn_r = MIN(-a_c, -b_c, x_c, y_c) ! { dg-error "" }
+ if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 33 ! { dg-error "" }
+ mn_r = MIN(-a2_c, -b2_c, x_c, y_c) ! { dg-error "" }
+ if (abs(mn_r - (-a2_c)) > 1.0D-6) STOP 34 ! { dg-error "" }
+ mn_r = MIN(-a_l, -b_c, x_c, y_l) ! { dg-error "" }
+ if (abs(mn_r - (-a_c)) > 1.0D-6) STOP 35 ! { dg-error "" }
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
new file mode 100644
index 00000000000..00f8fb88f1b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_6.f
@@ -0,0 +1,118 @@
+! { dg-do compile }
+! { dg-options "-fdec" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real
+ REAL l/0.0/
+ INTEGER a_i/4/
+ INTEGER*4 a2_i/4/
+ CHARACTER b_c
+ CHARACTER*8 b2_c
+ INTEGER x_i/2/
+ CHARACTER y_c
+ REAL a_r/4.0/
+ REAL*4 a2_r/4.0/
+ LOGICAL b_l
+ LOGICAL*8 b2_l
+ REAL x_r/2.0/
+ LOGICAL y_l
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ m_i = MOD(a_i, b_c) ! { dg-error "" }
+ if (m_i .ne. 1) STOP 1
+ m_i = MOD(a2_i, b2_c) ! { dg-error "" }
+ if (m_i .ne. 1) STOP 2
+ m_r = MOD(a_r, b_l) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(a2_r, b2_l) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+ m_r = MOD(a_i, b_l) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
+ m_r = MOD(a_r, b_c) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
+
+ md_i = MODULO(a_i, b_c) ! { dg-error "" }
+ if (md_i .ne. 1) STOP 7
+ md_i = MODULO(a2_i, b2_c) ! { dg-error "" }
+ if (md_i .ne. 1) STOP 8
+ md_r = MODULO(a_r, b_l) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
+ md_r = MODULO(a2_r, b2_l) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
+ md_r = MODULO(a_i, b_l) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
+ md_r = MODULO(a_r, b_c) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
+
+ d_i = DIM(a_i, b_c) ! { dg-error "" }
+ if (d_i .ne. 1) STOP 13
+ d_i = DIM(a2_i, b2_c) ! { dg-error "" }
+ if (d_i .ne. 1) STOP 14
+ d_r = DIM(a_r, b_l) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
+ d_r = DIM(a2_r, b2_l) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
+ d_r = DIM(a_r, b_c) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
+ d_r = DIM(b_c, a_r) ! { dg-error "" }
+ if (abs(d_r) > 1.0D-6) STOP 18
+
+ s_i = SIGN(-a_i, b_c) ! { dg-error "" }
+ if (s_i .ne. 4) STOP 19
+ s_i = SIGN(-a2_i, b2_c) ! { dg-error "" }
+ if (s_i .ne. 4) STOP 20
+ s_r = SIGN(a_r, -b_l) ! { dg-error "" }
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
+ s_r = SIGN(a2_r, -b2_l) ! { dg-error "" }
+ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
+ s_r = SIGN(a_r, -b_c) ! { dg-error "" }
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
+ s_r = SIGN(-a_i, b_l) ! { dg-error "" }
+ if (abs(s_r - a_r) > 1.0D-6) STOP 24
+
+ mx_i = MAX(-a_i, -b_c, x_i, y_c) ! { dg-error "" }
+ if (mx_i .ne. x_i) STOP 25
+ mx_i = MAX(-a2_i, -b2_c, x_i, y_c) ! { dg-error "" }
+ if (mx_i .ne. x_i) STOP 26
+ mx_r = MAX(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
+ mx_r = MAX(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
+ mx_r = MAX(-a_i, -b_l, x_r, y_c) ! { dg-error "" }
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
+
+ mn_i = MIN(-a_i, -b_c, x_i, y_c) ! { dg-error "" }
+ if (mn_i .ne. -a_i) STOP 31
+ mn_i = MIN(-a2_i, -b2_c, x_i, y_c) ! { dg-error "" }
+ if (mn_i .ne. -a2_i) STOP 32
+ mn_r = MIN(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
+ mn_r = MIN(-a2_r, -b2_l, x_r, y_l) ! { dg-error "" }
+ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
+ mn_r = MIN(-a_i, -b_l, x_r, y_c) ! { dg-error "" }
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
new file mode 100644
index 00000000000..1d4150d81c0
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_intrinsic_int_real_promotion_7.f
@@ -0,0 +1,118 @@
+! { dg-do compile }
+! { dg-options "-fdec-promotion" }
+!
+! Test promotion between integers and reals in intrinsic operations.
+! These operations are: mod, modulo, dim, sign, min, max, minloc and
+! maxloc.
+!
+! Contributed by Francisco Redondo Marchena <francisco.marchena@codethink.co.uk>
+! and Jeff Law <law@redhat.com>
+! Modified by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ PROGRAM promotion_int_real
+ REAL l/0.0/
+ INTEGER a_i/4/
+ INTEGER*4 a2_i/4/
+ CHARACTER b_c
+ CHARACTER*8 b2_c
+ INTEGER x_i/2/
+ CHARACTER y_c
+ REAL a_r/4.0/
+ REAL*4 a2_r/4.0/
+ LOGICAL b_l
+ LOGICAL*8 b2_l
+ REAL x_r/2.0/
+ LOGICAL y_l
+
+ INTEGER m_i/0/
+ REAL m_r/0.0/
+
+ INTEGER md_i/0/
+ REAL md_r/0.0/
+
+ INTEGER d_i/0/
+ REAL d_r/0.0/
+
+ INTEGER s_i/0/
+ REAL s_r/0.0/
+
+ INTEGER mn_i/0/
+ REAL mn_r/0.0/
+
+ INTEGER mx_i/0/
+ REAL mx_r/0.0/
+
+ m_i = MOD(a_i, b_c) ! { dg-error "" }
+ if (m_i .ne. 1) STOP 1
+ m_i = MOD(a2_i, b2_c) ! { dg-error "" }
+ if (m_i .ne. 1) STOP 2
+ m_r = MOD(a_r, b_l) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 3
+ m_r = MOD(a2_r, b2_l) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 4
+ m_r = MOD(a_i, b_l) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 5
+ m_r = MOD(a_r, b_c) ! { dg-error "" }
+ if (abs(m_r - 1.0) > 1.0D-6) STOP 6
+
+ md_i = MODULO(a_i, b_c) ! { dg-error "" }
+ if (md_i .ne. 1) STOP 7
+ md_i = MODULO(a2_i, b2_c) ! { dg-error "" }
+ if (md_i .ne. 1) STOP 8
+ md_r = MODULO(a_r, b_l) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 9
+ md_r = MODULO(a2_r, b2_l) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 10
+ md_r = MODULO(a_i, b_l) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 11
+ md_r = MODULO(a_r, b_c) ! { dg-error "" }
+ if (abs(md_r - 1.0) > 1.0D-6) STOP 12
+
+ d_i = DIM(a_i, b_c) ! { dg-error "" }
+ if (d_i .ne. 1) STOP 13
+ d_i = DIM(a2_i, b2_c) ! { dg-error "" }
+ if (d_i .ne. 1) STOP 14
+ d_r = DIM(a_r, b_l) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 15
+ d_r = DIM(a2_r, b2_l) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 16
+ d_r = DIM(a_r, b_c) ! { dg-error "" }
+ if (abs(d_r - 1.0) > 1.0D-6) STOP 17
+ d_r = DIM(b_c, a_r) ! { dg-error "" }
+ if (abs(d_r) > 1.0D-6) STOP 18
+
+ s_i = SIGN(-a_i, b_c) ! { dg-error "" }
+ if (s_i .ne. 4) STOP 19
+ s_i = SIGN(-a2_i, b2_c) ! { dg-error "" }
+ if (s_i .ne. 4) STOP 20
+ s_r = SIGN(a_r, -b_l) ! { dg-error "" }
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 21
+ s_r = SIGN(a2_r, -b2_l) ! { dg-error "" }
+ if (abs(s_r - (-a2_r)) > 1.0D-6) STOP 22
+ s_r = SIGN(a_r, -b_c) ! { dg-error "" }
+ if (abs(s_r - (-a_r)) > 1.0D-6) STOP 23
+ s_r = SIGN(-a_i, b_l) ! { dg-error "" }
+ if (abs(s_r - a_r) > 1.0D-6) STOP 24
+
+ mx_i = MAX(-a_i, -b_c, x_i, y_c) ! { dg-error "" }
+ if (mx_i .ne. x_i) STOP 25
+ mx_i = MAX(-a2_i, -b2_c, x_i, y_c) ! { dg-error "" }
+ if (mx_i .ne. x_i) STOP 26
+ mx_r = MAX(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 27
+ mx_r = MAX(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 28
+ mx_r = MAX(-a_i, -b_l, x_r, y_c) ! { dg-error "" }
+ if (abs(mx_r - x_r) > 1.0D-6) STOP 29
+
+ mn_i = MIN(-a_i, -b_c, x_i, y_c) ! { dg-error "" }
+ if (mn_i .ne. -a_i) STOP 31
+ mn_i = MIN(-a2_i, -b2_c, x_i, y_c) ! { dg-error "" }
+ if (mn_i .ne. -a2_i) STOP 32
+ mn_r = MIN(-a_r, -b_l, x_r, y_l) ! { dg-error "" }
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 33
+ mn_r = MIN(-a2_r, -b2_l, x_r, y_l) ! { dg-error "" }
+ if (abs(mn_r - (-a2_r)) > 1.0D-6) STOP 34
+ mn_r = MIN(-a_i, -b_l, x_r, y_c) ! { dg-error "" }
+ if (abs(mn_r - (-a_r)) > 1.0D-6) STOP 35
+ END PROGRAM
diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
new file mode 100644
index 00000000000..435bf98350c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-1.f
@@ -0,0 +1,40 @@
+!{ dg-do run }
+!{ dg-options "-fdec" }
+!
+! integer types of a smaller kind than expected should be
+! accepted by type specific intrinsic functions
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ program test_small_type_promtion
+ implicit none
+ integer(1) :: a = 1
+ integer :: i
+ if (iiabs(-9_1).ne.9) stop 1
+ if (iabs(-9_1).ne.9) stop 2
+ if (iabs(-9_2).ne.9) stop 3
+ if (jiabs(-9_1).ne.9) stop 4
+ if (jiabs(-9_2).ne.9) stop 5
+ if (iishft(1_1, 2).ne.4) stop 6
+ if (jishft(1_1, 2).ne.4) stop 7
+ if (jishft(1_2, 2).ne.4) stop 8
+ if (kishft(1_1, 2).ne.4) stop 9
+ if (kishft(1_2, 2).ne.4) stop 10
+ if (kishft(1_4, 2).ne.4) stop 11
+ if (imod(17_1, 3).ne.2) stop 12
+ if (jmod(17_1, 3).ne.2) stop 13
+ if (jmod(17_2, 3).ne.2) stop 14
+ if (kmod(17_1, 3).ne.2) stop 15
+ if (kmod(17_2, 3).ne.2) stop 16
+ if (kmod(17_4, 3).ne.2) stop 17
+ if (inot(5_1).ne.-6) stop 18
+ if (jnot(5_1).ne.-6) stop 19
+ if (jnot(5_2).ne.-6) stop 20
+ if (knot(5_1).ne.-6) stop 21
+ if (knot(5_2).ne.-6) stop 22
+ if (knot(5_4).ne.-6) stop 23
+ if (isign(-77_1, 1).ne.77) stop 24
+ if (isign(-77_1, -1).ne.-77) stop 25
+ if (isign(-77_2, 1).ne.77) stop 26
+ if (isign(-77_2, -1).ne.-77) stop 27
+ end program
diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
new file mode 100644
index 00000000000..7b1697ca665
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-2.f
@@ -0,0 +1,40 @@
+!{ dg-do run }
+!{ dg-options "-fdec-intrinsic-ints -fdec-promotion" }
+!
+! integer types of a smaller kind than expected should be
+! accepted by type specific intrinsic functions
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ program test_small_type_promtion
+ implicit none
+ integer(1) :: a = 1
+ integer :: i
+ if (iiabs(-9_1).ne.9) stop 1
+ if (iabs(-9_1).ne.9) stop 2
+ if (iabs(-9_2).ne.9) stop 3
+ if (jiabs(-9_1).ne.9) stop 4
+ if (jiabs(-9_2).ne.9) stop 5
+ if (iishft(1_1, 2).ne.4) stop 6
+ if (jishft(1_1, 2).ne.4) stop 7
+ if (jishft(1_2, 2).ne.4) stop 8
+ if (kishft(1_1, 2).ne.4) stop 9
+ if (kishft(1_2, 2).ne.4) stop 10
+ if (kishft(1_4, 2).ne.4) stop 11
+ if (imod(17_1, 3).ne.2) stop 12
+ if (jmod(17_1, 3).ne.2) stop 13
+ if (jmod(17_2, 3).ne.2) stop 14
+ if (kmod(17_1, 3).ne.2) stop 15
+ if (kmod(17_2, 3).ne.2) stop 16
+ if (kmod(17_4, 3).ne.2) stop 17
+ if (inot(5_1).ne.-6) stop 18
+ if (jnot(5_1).ne.-6) stop 19
+ if (jnot(5_2).ne.-6) stop 20
+ if (knot(5_1).ne.-6) stop 21
+ if (knot(5_2).ne.-6) stop 22
+ if (knot(5_4).ne.-6) stop 23
+ if (isign(-77_1, 1).ne.77) stop 24
+ if (isign(-77_1, -1).ne.-77) stop 25
+ if (isign(-77_2, 1).ne.77) stop 26
+ if (isign(-77_2, -1).ne.-77) stop 27
+ end program
diff --git a/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f b/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
new file mode 100644
index 00000000000..db8dff6c55d
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_kind_promotion-3.f
@@ -0,0 +1,39 @@
+!{ dg-do compile }
+!{ dg-options "-fdec -fno-dec-promotion" }
+!
+! integer types of a smaller kind than expected should be
+! accepted by type specific intrinsic functions
+!
+! Contributed by Mark Eggleston <mark.eggleston@codethink.com>
+!
+ program test_small_type_promtion
+ integer(1) :: a = 1
+ integer :: i
+ if (iiabs(-9_1).ne.9) stop 1
+ if (iabs(-9_1).ne.9) stop 2 ! { dg-error "type mismatch in argument" }
+ if (iabs(-9_2).ne.9) stop 3 ! { dg-error "type mismatch in argument" }
+ if (jiabs(-9_1).ne.9) stop 4
+ if (jiabs(-9_2).ne.9) stop 5
+ if (iishft(1_1, 2).ne.4) stop 6
+ if (jishft(1_1, 2).ne.4) stop 7
+ if (jishft(1_2, 2).ne.4) stop 8
+ if (kishft(1_1, 2).ne.4) stop 9
+ if (kishft(1_2, 2).ne.4) stop 10
+ if (kishft(1_4, 2).ne.4) stop 11
+ if (imod(17_1, 3).ne.2) stop 12
+ if (jmod(17_1, 3).ne.2) stop 13
+ if (jmod(17_2, 3).ne.2) stop 14
+ if (kmod(17_1, 3).ne.2) stop 15
+ if (kmod(17_2, 3).ne.2) stop 16
+ if (kmod(17_4, 3).ne.2) stop 17
+ if (inot(5_1).ne.-6) stop 18
+ if (jnot(5_1).ne.-6) stop 19
+ if (jnot(5_2).ne.-6) stop 20
+ if (knot(5_1).ne.-6) stop 21
+ if (knot(5_2).ne.-6) stop 22
+ if (knot(5_4).ne.-6) stop 23
+ if (isign(-77_1, 1).ne.77) stop 24 ! { dg-error "type mismatch in argument" }
+ if (isign(-77_1, -1).ne.-77) stop 25 ! { dg-error "type mismatch in argument" }
+ if (isign(-77_2, 1).ne.77) stop 26 ! { dg-error "type mismatch in argument" }
+ if (isign(-77_2, -1).ne.-77) stop 27 ! { dg-error "type mismatch in argument" }
+ end program
--
2.27.0
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/ocs-upgrade/gcc.git
git@gitee.com:ocs-upgrade/gcc.git
ocs-upgrade
gcc
gcc
master

搜索帮助