From d82185e196fe2edfd9e307528d4eb2d8fb53bc91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Per=20=C3=96stlund?= Date: Mon, 8 Apr 2019 13:32:49 +0200 Subject: [PATCH] [NF] Various fixes. - 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]: - OpenModelica/OpenModelica#130 - OpenModelica/OMCompiler#3042 --- Compiler/NFFrontEnd/NFExpandExp.mo | 2 +- Compiler/NFFrontEnd/NFExpression.mo | 1 + Compiler/NFFrontEnd/NFTyping.mo | 56 ++++++++++++++++++++++------- Compiler/Util/Error.mo | 2 ++ 4 files changed, 47 insertions(+), 14 deletions(-) diff --git a/Compiler/NFFrontEnd/NFExpandExp.mo b/Compiler/NFFrontEnd/NFExpandExp.mo index f4f14ef7a8..cd16f544b9 100644 --- a/Compiler/NFFrontEnd/NFExpandExp.mo +++ b/Compiler/NFFrontEnd/NFExpandExp.mo @@ -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); diff --git a/Compiler/NFFrontEnd/NFExpression.mo b/Compiler/NFFrontEnd/NFExpression.mo index a796e2003d..2b84fec27d 100644 --- a/Compiler/NFFrontEnd/NFExpression.mo +++ b/Compiler/NFFrontEnd/NFExpression.mo @@ -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; diff --git a/Compiler/NFFrontEnd/NFTyping.mo b/Compiler/NFFrontEnd/NFTyping.mo index c926e80707..148f14cce4 100644 --- a/Compiler/NFFrontEnd/NFTyping.mo +++ b/Compiler/NFFrontEnd/NFTyping.mo @@ -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 @@ -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 @@ -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. @@ -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; @@ -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." @@ -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); diff --git a/Compiler/Util/Error.mo b/Compiler/Util/Error.mo index 38c3f85756..d7354840a4 100644 --- a/Compiler/Util/Error.mo +++ b/Compiler/Util/Error.mo @@ -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(),