Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit e30046d

Browse files
perostOpenModelica-Hudson
authored andcommitted
[NF] Fix size as external argument.
Belonging to [master]: - #2298 - OpenModelica/OpenModelica-testsuite#887
1 parent fc8513b commit e30046d

File tree

3 files changed

+79
-41
lines changed

3 files changed

+79
-41
lines changed

Compiler/NFFrontEnd/NFExpression.mo

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2570,6 +2570,16 @@ public
25702570
end match;
25712571
end isScalarConst;
25722572

2573+
function isInteger
2574+
input Expression exp;
2575+
output Boolean isInteger;
2576+
algorithm
2577+
isInteger := match exp
2578+
case INTEGER() then true;
2579+
else false;
2580+
end match;
2581+
end isInteger;
2582+
25732583
function fillType
25742584
input Type ty;
25752585
input Expression fillExp;

Compiler/NFFrontEnd/NFTyping.mo

Lines changed: 67 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,9 +1710,13 @@ algorithm
17101710
end printRangeTypeError;
17111711

17121712
function typeSize
1713+
"Types a size expression. If evaluate is true the size expression is also
1714+
evaluated if the dimension is known and the index is a parameter expression,
1715+
otherwise a typed size expression is returned."
17131716
input output Expression sizeExp;
17141717
input ExpOrigin.Type origin;
17151718
input SourceInfo info;
1719+
input Boolean evaluate = true;
17161720
output Type sizeType;
17171721
output Variability variability;
17181722
protected
@@ -1724,7 +1728,7 @@ protected
17241728
TypingError ty_err;
17251729
algorithm
17261730
(sizeExp, sizeType, variability) := match sizeExp
1727-
case Expression.SIZE(dimIndex = SOME(index))
1731+
case Expression.SIZE(exp = exp, dimIndex = SOME(index))
17281732
algorithm
17291733
(index, index_ty, variability) := typeExp(index, origin, info);
17301734

@@ -1747,33 +1751,15 @@ algorithm
17471751
Expression.INTEGER(iindex) := index;
17481752

17491753
// Get the iindex'd dimension of the expression.
1750-
(dim, ty_err) := typeExpDim(sizeExp.exp, iindex, origin, info);
1754+
(dim, ty_err) := typeExpDim(exp, iindex, origin, info);
1755+
checkSizeTypingError(ty_err, exp, iindex, info);
17511756

1752-
() := match ty_err
1753-
case NO_ERROR() then ();
1754-
1755-
// The first argument wasn't an array.
1756-
case OUT_OF_BOUNDS(0)
1757-
algorithm
1758-
Error.addSourceMessage(Error.INVALID_ARGUMENT_TYPE_FIRST_ARRAY, {"size"}, info);
1759-
then
1760-
fail();
1761-
1762-
// The index referred to an invalid dimension.
1763-
case OUT_OF_BOUNDS()
1764-
algorithm
1765-
Error.addSourceMessage(Error.INVALID_SIZE_INDEX,
1766-
{String(iindex), Expression.toString(sizeExp.exp), String(ty_err.upperBound)}, info);
1767-
then
1768-
fail();
1769-
end match;
1770-
1771-
if Dimension.isKnown(dim) then
1772-
// The dimension size is known, return its size.
1757+
if Dimension.isKnown(dim) and evaluate then
1758+
// If the dimension size is known, return its size.
17731759
exp := Expression.INTEGER(Dimension.size(dim));
17741760
else
1775-
// The dimension size is unknown, return a size expression. This can
1776-
// happen in functions where unknown dimensions are allowed.
1761+
// If the dimension size is unknown (e.g. in a function) or
1762+
// evaluation is disabled, return a size expression instead.
17771763
exp := typeExp(sizeExp.exp, origin, info);
17781764
exp := Expression.SIZE(exp, SOME(index));
17791765
end if;
@@ -1815,6 +1801,32 @@ algorithm
18151801
end match;
18161802
end typeSize;
18171803

1804+
function checkSizeTypingError
1805+
input TypingError typingError;
1806+
input Expression exp;
1807+
input Integer index;
1808+
input SourceInfo info;
1809+
algorithm
1810+
() := match typingError
1811+
case NO_ERROR() then ();
1812+
1813+
// The first argument wasn't an array.
1814+
case OUT_OF_BOUNDS(0)
1815+
algorithm
1816+
Error.addSourceMessage(Error.INVALID_ARGUMENT_TYPE_FIRST_ARRAY, {"size"}, info);
1817+
then
1818+
fail();
1819+
1820+
// The index referred to an invalid dimension.
1821+
case OUT_OF_BOUNDS()
1822+
algorithm
1823+
Error.addSourceMessage(Error.INVALID_SIZE_INDEX,
1824+
{String(index), Expression.toString(exp), String(typingError.upperBound)}, info);
1825+
then
1826+
fail();
1827+
end match;
1828+
end checkSizeTypingError;
1829+
18181830
function evaluateEnd
18191831
input Expression exp;
18201832
input Dimension dim;
@@ -1912,30 +1924,44 @@ function typeExternalArg
19121924
protected
19131925
Type ty;
19141926
Variability var;
1927+
Expression index;
19151928
algorithm
1916-
(outArg, ty, var) := typeExp(arg, ExpOrigin.FUNCTION, info);
1917-
1918-
// Check that the external function argument is valid. The valid types of
1919-
// expressions are crefs, scalar constants and size expressions with constant
1920-
// index. The reason why we match on the untyped expression here is because
1921-
// size expressions might be evaluated during typing, but the variability
1922-
// would still be parameter in that case.
19231929
outArg := match arg
1924-
case Expression.CREF() then outArg;
1925-
case Expression.SIZE() guard var <= Variability.PARAMETER then outArg;
1926-
else
1930+
case Expression.SIZE(dimIndex = SOME(_))
19271931
algorithm
1928-
if Type.isScalarBuiltin(ty) and var == Variability.CONSTANT then
1929-
outArg := Ceval.evalExp(outArg, Ceval.EvalTarget.GENERIC(info));
1930-
outArg := SimplifyExp.simplifyExp(arg);
1931-
else
1932-
Error.addSourceMessage(Error.EXTERNAL_ARG_WRONG_EXP,
1933-
{Expression.toString(outArg)}, info);
1932+
outArg := typeSize(arg, ExpOrigin.FUNCTION, info, evaluate = false);
1933+
Expression.SIZE(dimIndex = SOME(index)) := outArg;
1934+
1935+
// Size expression must have a constant dimension index.
1936+
if not Expression.isInteger(index) then
1937+
Error.addSourceMessage(Error.EXTERNAL_ARG_NONCONSTANT_SIZE_INDEX,
1938+
{Expression.toString(arg)}, info);
19341939
fail();
19351940
end if;
19361941
then
19371942
outArg;
19381943

1944+
else
1945+
algorithm
1946+
(outArg, ty, var) := typeExp(arg, ExpOrigin.FUNCTION, info);
1947+
then
1948+
match arg
1949+
// All kinds of crefs are allowed.
1950+
case Expression.CREF() then outArg;
1951+
else
1952+
algorithm
1953+
// The only other kind of expression that's allowed is scalar constants.
1954+
if Type.isScalarBuiltin(ty) and var == Variability.CONSTANT then
1955+
outArg := Ceval.evalExp(outArg, Ceval.EvalTarget.GENERIC(info));
1956+
outArg := SimplifyExp.simplifyExp(arg);
1957+
else
1958+
Error.addSourceMessage(Error.EXTERNAL_ARG_WRONG_EXP,
1959+
{Expression.toString(outArg)}, info);
1960+
fail();
1961+
end if;
1962+
then
1963+
outArg;
1964+
end match;
19391965
end match;
19401966
end typeExternalArg;
19411967

Compiler/Util/Error.mo

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,8 @@ public constant Message REDECLARE_OF_CONSTANT = MESSAGE(326, TRANSLATION(), ERRO
781781
Util.gettext("%s is constant and may not be redeclared."));
782782
public constant Message REDECLARE_MISMATCHED_PREFIX = MESSAGE(327, TRANSLATION(), ERROR(),
783783
Util.gettext("Invalid redeclaration '%s %s', original element is declared '%s'."));
784+
public constant Message EXTERNAL_ARG_NONCONSTANT_SIZE_INDEX = MESSAGE(328, TRANSLATION(), ERROR(),
785+
Util.gettext("Invalid external argument '%s', the dimension index must be a constant expression."));
784786
public constant Message INITIALIZATION_NOT_FULLY_SPECIFIED = MESSAGE(496, TRANSLATION(), WARNING(),
785787
Util.gettext("The initial conditions are not fully specified. %s."));
786788
public constant Message INITIALIZATION_OVER_SPECIFIED = MESSAGE(497, TRANSLATION(), WARNING(),

0 commit comments

Comments
 (0)