Skip to content

Commit

Permalink
[NF] Various fixes.
Browse files Browse the repository at this point in the history
- Changed ExpandExp.expandCref to return an array with the same
  dimensions as the input cref, even when the cref's type has
  zero-dimensions.
- Added case for Expression.TYPENAME in Expression.typeOf.
- Added better error checking when deducing unknown dimensions.
- Added check for negative dimension sizes.

Belonging to [master]:
  - #130
  - OpenModelica/OMCompiler#3042
  • Loading branch information
perost authored and OpenModelica-Hudson committed Apr 8, 2019
1 parent 2ee23a6 commit d82185e
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Compiler/NFFrontEnd/NFExpandExp.mo
Expand Up @@ -121,7 +121,7 @@ public
case Expression.CREF(cref = ComponentRef.CREF())
algorithm
if Type.hasZeroDimension(crefExp.ty) then
arrayExp := Expression.makeEmptyArray(Type.ARRAY(Type.arrayElementType(crefExp.ty), {Dimension.fromInteger(0)}));
arrayExp := Expression.makeEmptyArray(crefExp.ty);
expanded := true;
elseif Type.hasKnownSize(crefExp.ty) then
subs := expandCref2(crefExp.cref);
Expand Down
1 change: 1 addition & 0 deletions Compiler/NFFrontEnd/NFExpression.mo
Expand Up @@ -778,6 +778,7 @@ public
case ENUM_LITERAL() then exp.ty;
case CLKCONST() then Type.CLOCK();
case CREF() then exp.ty;
case TYPENAME() then exp.ty;
case ARRAY() then exp.ty;
case RANGE() then exp.ty;
case TUPLE() then exp.ty;
Expand Down
56 changes: 43 additions & 13 deletions Compiler/NFFrontEnd/NFTyping.mo
Expand Up @@ -522,6 +522,7 @@ algorithm
Dimension dim;
Binding b;
Type ty;
TypingError ty_err;

// Print an error when a dimension that's currently being processed is
// found, which indicates a dependency loop. Another way of handling this
Expand Down Expand Up @@ -608,7 +609,7 @@ algorithm
end if;
end if;

dim := match b
(dim, ty_err) := match b
// Print an error if there's no binding.
case Binding.UNBOUND()
algorithm
Expand All @@ -621,18 +622,25 @@ algorithm
// to get the dimension we're looking for.
case Binding.UNTYPED_BINDING()
algorithm
dim := typeExpDim(b.bindingExp, index + Binding.countPropagatedDims(b),
ExpOrigin.setFlag(origin, ExpOrigin.DIMENSION), info);
(dim, _, ty_err) := typeExpDim(b.bindingExp, index + Binding.countPropagatedDims(b),
ExpOrigin.setFlag(origin, ExpOrigin.DIMENSION), info);
then
dim;
(dim, ty_err);

// A typed binding, get the dimension from the binding's type.
case Binding.TYPED_BINDING()
then nthDimensionBoundsChecked(b.bindingType, index + Binding.countPropagatedDims(b));
end match;

() := match ty_err
case TypingError.OUT_OF_BOUNDS()
algorithm
dim := nthDimensionBoundsChecked(b.bindingType, index + Binding.countPropagatedDims(b));
Error.addSourceMessage(Error.DIMENSION_DEDUCTION_FROM_BINDING_FAILURE,
{String(index), InstNode.name(component), Binding.toString(b)}, info);
then
dim;
fail();

else ();
end match;

// Make sure the dimension is constant evaluted, and also mark it as structural.
Expand All @@ -644,6 +652,12 @@ algorithm
then
Dimension.fromExp(exp, dim.var);

case Dimension.UNKNOWN()
algorithm
Error.addInternalError(getInstanceName() + " returned unknown dimension in a non-function context", info);
then
fail();

else dim;
end match;

Expand All @@ -654,8 +668,31 @@ algorithm
// Other kinds of dimensions are already typed.
else dimension;
end match;

verifyDimension(dimension, component, info);
end typeDimension;

function verifyDimension
input Dimension dimension;
input InstNode component;
input SourceInfo info;
algorithm
() := match dimension
case Dimension.INTEGER()
algorithm
// Check that integer dimensions are not negative.
if dimension.size < 0 then
Error.addSourceMessage(Error.NEGATIVE_DIMENSION_INDEX,
{String(dimension.size), InstNode.name(component)}, info);
fail();
end if;
then
();

else ();
end match;
end verifyDimension;

function getRecordElementBinding
"Tries to fetch the binding for a given record field by using the binding of
the record instance."
Expand Down Expand Up @@ -1885,13 +1922,6 @@ algorithm
case Expression.SIZE()
algorithm
(exp, exp_ty, _) := typeExp(sizeExp.exp, next_origin, info);

// The first argument must be an array of any type.
if not Type.isArray(exp_ty) then
Error.addSourceMessage(Error.INVALID_ARGUMENT_TYPE_FIRST_ARRAY, {"size"}, info);
fail();
end if;

sizeType := Type.sizeType(exp_ty);
then
(Expression.SIZE(exp, NONE()), sizeType, Variability.PARAMETER);
Expand Down
2 changes: 2 additions & 0 deletions Compiler/Util/Error.mo
Expand Up @@ -827,6 +827,8 @@ public constant Message INST_RECURSION_LIMIT_REACHED = MESSAGE(349, TRANSLATION(
Util.gettext("Recursion limit reached while instantiating ‘%s‘."));
public constant Message WHEN_IF_VARIABLE_MISMATCH = MESSAGE(350, TRANSLATION(), ERROR(),
Util.gettext("The branches of an if-equation inside a when-equation must have the same set of component references on the left-hand side."));
public constant Message DIMENSION_DEDUCTION_FROM_BINDING_FAILURE = MESSAGE(351, TRANSLATION(), ERROR(),
Util.gettext("Dimension %s of ‘%s‘ could not be deduced from the component's binding equation ‘%s‘."));
public constant Message INITIALIZATION_NOT_FULLY_SPECIFIED = MESSAGE(496, TRANSLATION(), WARNING(),
Util.gettext("The initial conditions are not fully specified. %s."));
public constant Message INITIALIZATION_OVER_SPECIFIED = MESSAGE(497, TRANSLATION(), WARNING(),
Expand Down

0 comments on commit d82185e

Please sign in to comment.