Skip to content

Commit

Permalink
- second attempt to fix bug #2113, let's see how many tests we break.
Browse files Browse the repository at this point in the history
- added an error message for when we have a structural parameter/constant with no binding.
- handle negative integers in fill.
- handle non-local constants in external function declarations.
- some left-out minor edits.
- expected output:
  testsuite/flattening/modelica/arrays/NonExpArray2.mo
  testsuite/flattening/libraries/msl31/fluid/Modelica.Fluid.Examples.HeatingSystem.mos
- added a test model for #2113 and a test model for unknown dimension due to a parameter with no binding
  testsuite/flattening/modelica/arrays/TestArrayUnknown.mo
  testsuite/flattening/modelica/arrays/TestFill.mo

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@15806 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
adrpo committed Apr 12, 2013
1 parent d102cff commit e833582
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 31 deletions.
6 changes: 5 additions & 1 deletion Compiler/FrontEnd/ComponentReference.mo
Expand Up @@ -1533,7 +1533,11 @@ algorithm
end crefType;

public function crefLastType "returns the 'last' type of a cref.
For instance, for the cref 'a.b' it returns the type in identifier 'b'"
For instance, for the cref 'a.b' it returns the type in identifier 'b'
adrpo:
NOTE THAT THIS WILL BE AN ARRAY TYPE IF THE LAST CREF IS AN ARRAY TYPE
If you want to get the component reference type considering subscripts use:
crefTypeConsiderSubs"
input ComponentRef inRef;
output DAE.Type res;
algorithm
Expand Down
18 changes: 15 additions & 3 deletions Compiler/FrontEnd/Expression.mo
Expand Up @@ -779,7 +779,7 @@ end expStripLastSubs;

public function expStripLastIdent
"function: expStripLastIdent
Strips the last subscripts of a Exp"
Strips the last identifier of a cref Exp"
input DAE.Exp inExp;
output DAE.Exp outExp;
algorithm
Expand Down Expand Up @@ -2693,8 +2693,8 @@ algorithm
equation
true = Flags.isSet(Flags.CHECK_DAE_CREF_TYPE);
tExisting = ComponentReference.crefLastType(cref);
failure(equality(tGiven = tExisting)); // false = valueEq(tGiven, tExisting);
Debug.traceln("Warning: Expression.makeCrefExp: given type DAE.CREF.ty: " +&
failure(equality(tGiven = tExisting));
Debug.traceln("Warning: Expression.makeCrefExp: cref " +& ComponentReference.printComponentRefStr(cref) +& " was given type DAE.CREF.ty: " +&
Types.unparseType(tGiven) +&
" is different from existing DAE.CREF.componentRef.ty: " +&
Types.unparseType(tExisting));
Expand Down Expand Up @@ -8304,6 +8304,18 @@ algorithm
end matchcontinue;
end dimensionKnown;

public function dimensionUnknownOrExp
"Checks whether a dimensions is known or not."
input DAE.Dimension dim;
output Boolean known;
algorithm
known := matchcontinue(dim)
case DAE.DIM_UNKNOWN() then true;
case DAE.DIM_EXP(exp = _) then true;
case _ then false;
end matchcontinue;
end dimensionUnknownOrExp;

public function subscriptEqual
"function: subscriptEqual
Returns true if two subscript lists are equal."
Expand Down
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/ExpressionSimplify.mo
Expand Up @@ -996,7 +996,7 @@ algorithm
case (DAE.CALL(path = Absyn.IDENT("fill"), expLst = e::expl))
equation
valueLst = List.map(expl, ValuesUtil.expValue);
(_,outExp,_) = Static.elabBuiltinFill2(Env.emptyCache(), Env.emptyEnv, e, DAE.T_UNKNOWN_DEFAULT, valueLst, DAE.C_CONST(),Prefix.NOPRE());
(_,outExp,_) = Static.elabBuiltinFill2(Env.emptyCache(), Env.emptyEnv, e, DAE.T_UNKNOWN_DEFAULT, valueLst, DAE.C_CONST(), Prefix.NOPRE(), {}, Absyn.dummyInfo);
then
outExp;

Expand Down
57 changes: 41 additions & 16 deletions Compiler/FrontEnd/Inst.mo
Expand Up @@ -2039,7 +2039,7 @@ algorithm
then
(cache,env_3,ih,store,DAEUtil.emptyDae,csets,ci_state_1,tys2,bc /* NONE() */,NONE(),NONE(),graph);

/* Instantiate a class definition made of parts */
// Instantiate a class definition made of parts
case (cache,env,ih,store,mods,pre,ci_state,
c as SCode.CLASS(name = n,restriction = r,classDef = d,info=info,partialPrefix = partialPrefix,encapsulatedPrefix = encapsulatedPrefix),
vis,inst_dims,impl,callscope,graph,_,_)
Expand Down Expand Up @@ -3975,7 +3975,7 @@ algorithm
equation
s1 = Mod.prettyPrintMod(inmod,0);
s2 = s1 +& " not found in <" +& callingScope +& ">";
// Line below can be used for testing test-suite for dangeling modifiers when getErrorString() is not called.
// Line below can be used for testing test-suite for dangling modifiers when getErrorString() is not called.
//print(" *** ERROR Unused modifer...: " +& s2 +& "\n");
Error.addMessage(Error.UNUSED_MODIFIER,{s2});
then
Expand Down Expand Up @@ -10717,6 +10717,7 @@ algorithm
SCode.Element cl;
SCode.Attributes attr;
Integer i,stop,i_1;
DAE.Dimension dim;
DAE.Dimensions dims;
list<DAE.Subscript> idxs;
InstDims inst_dims;
Expand All @@ -10739,12 +10740,13 @@ algorithm
SCode.Prefixes pf;
UnitAbsyn.InstStore store;

/* component environment If is a function var. */
case (cache,env,ih,store,(ci_state as ClassInf.FUNCTION(path = _)),mod,pre,n,(cl,attr),pf,i,DAE.DIM_UNKNOWN(),dims,idxs,inst_dims,impl,comment,_,graph, csets)
// component environment If is a function var.
case (cache,env,ih,store,(ci_state as ClassInf.FUNCTION(path = _)),mod,pre,n,(cl,attr),pf,i,dim,dims,idxs,inst_dims,impl,comment,_,graph, csets)
equation
true = Expression.dimensionUnknownOrExp(dim);
SOME(DAE.TYPED(e,_,p,_,_)) = Mod.modEquation(mod);
(cache,env_1,ih,store,dae1,_,ty,st,_,graph) =
instClass(cache,env,ih,store, mod, pre, cl, inst_dims, true, INNER_CALL(),graph, csets) "Which has an expression binding";
instClass(cache,env,ih,store, mod, pre, cl, inst_dims, true, INNER_CALL(), graph, csets) "Which has an expression binding";
ty_1 = Types.simplifyType(ty);
(cache,cr) = PrefixUtil.prefixCref(cache,env,ih,pre,ComponentReference.makeCrefIdent(n,ty_1,{})) "check their types";
(rhs,_) = Types.matchProp(e,p,DAE.PROP(ty,DAE.C_VAR()),true);
Expand All @@ -10769,7 +10771,7 @@ algorithm
then
(cache,compenv,ih,store,daeLst,csets,ty,graph);

/* Special case when instantiating Real[0]. We need to know the type */
// Special case when instantiating Real[0]. We need to know the type
case (cache,env,ih,store,ci_state,mod,pre,n,(cl,attr),pf,i,DAE.DIM_INTEGER(0),dims,idxs,inst_dims,impl,comment,_,graph, csets)
equation
ErrorExt.setCheckpoint("instArray Real[0]");
Expand All @@ -10780,7 +10782,7 @@ algorithm
then
(cache,compenv,ih,store,DAEUtil.emptyDae,csets,ty,graph);

/* Keep the errors if we somehow fail */
// Keep the errors if we somehow fail
case (_, _, _, _, _, _, _, _, _, _, _, DAE.DIM_INTEGER(0), _, _, _, _, _, _, _, _)
equation
ErrorExt.delCheckpoint("instArray Real[0]");
Expand All @@ -10794,7 +10796,7 @@ algorithm
then
(cache,env,ih,store,DAEUtil.emptyDae,csets,DAE.T_UNKNOWN_DEFAULT,graph);

/* adrpo: if a class is derived WITH AN ARRAY DIMENSION we should instVar2 the derived from type not the actual type!!! */
// adrpo: if a class is derived WITH AN ARRAY DIMENSION we should instVar2 the derived from type not the actual type!!!
case (cache,env,ih,store,ci_state,mod,pre,n,
(cl as SCode.CLASS(classDef=SCode.DERIVED(typeSpec=Absyn.TPATH(path,SOME(_)),
modifications=scodeMod,attributes=absynAttr)),
Expand Down Expand Up @@ -11086,18 +11088,19 @@ algorithm
// The size of function input arguments should not be set here, since they
// may vary depending on the inputs. So we ignore any modifications on input
// variables here.
case (cache, env, cref, _, ad, _, impl, st, doVect, true,pre,info,_)
case (cache, env, cref, _, ad, _, impl, st, doVect, true, pre, info, _)
equation
(cache, dim) = Static.elabArrayDims(cache, env, cref, ad, true, st, doVect,pre,info);
(cache, dim) = Static.elabArrayDims(cache, env, cref, ad, true, st, doVect, pre, info);
then
(cache, dim);

case (cache,env,cref,_,ad,NONE(),impl,st,doVect, _,pre,info,_) /* impl */
case (cache,env,cref,_,ad,NONE(),impl,st,doVect,_,pre,info,_) /* impl */
equation
(cache,dim) = Static.elabArrayDims(cache,env, cref, ad, impl, st,doVect,pre,info);
then
(cache,dim);
case (cache,env,cref,_,ad,SOME(DAE.TYPED(e,_,prop,_,info)),impl,st,doVect, _ ,pre,_,inst_dims) /* Untyped expressions must be elaborated. */

case (cache,env,cref,_,ad,SOME(DAE.TYPED(e,_,prop,_,info)),impl,st,doVect,_ ,pre,_,inst_dims) /* Untyped expressions must be elaborated. */
equation
t = Types.getPropType(prop);
(cache,dim1) = Static.elabArrayDims(cache,env, cref, ad, impl, st,doVect,pre,info);
Expand All @@ -11106,6 +11109,7 @@ algorithm
dim3 = List.threadMap(dim1, dim2, compatibleArraydim);
then
(cache,dim3);

case (cache,env,cref,_,ad,SOME(DAE.UNTYPED(aexp,info)),impl,st,doVect, _,pre,_,inst_dims)
equation
(cache,e_1,prop,_) = Static.elabExp(cache,env, aexp, impl, st,doVect,pre,info);
Expand All @@ -11117,6 +11121,7 @@ algorithm
dim3 = List.threadMap(dim1, dim2, compatibleArraydim);
then
(cache,dim3);

case (cache,env,cref,_,ad,SOME(DAE.TYPED(e,_,DAE.PROP(t,_),_,info)),impl,st,doVect, _,pre,_,inst_dims)
equation
// adrpo: do not display error when running checkModel
Expand All @@ -11131,6 +11136,7 @@ algorithm
Error.addSourceMessage(Error.ARRAY_DIMENSION_MISMATCH, {e_str,t_str,dim_str}, info);
then
fail();

// print some failures
case (_,_,cref,_,ad,eq,_,_,_,_,_,_,_)
equation
Expand Down Expand Up @@ -13161,7 +13167,7 @@ algorithm
case (cache,env,SCode.EXTERNALDECL(funcName = id,lang = lang,output_ = retcr,args = absexps),impl,pre,_)
equation
(cache,exps,props,_) = elabExpListExt(cache,env, absexps, impl,NONE(),pre,info);
(cache,extargs) = instExtGetFargs2(cache,env, exps, props);
(cache,extargs) = instExtGetFargs2(cache, env, exps, props);
then
(cache,extargs);
case (_,_,_,impl,_,_)
Expand Down Expand Up @@ -13196,8 +13202,8 @@ algorithm
case (cache,_,{},_) then (cache,{});
case (cache,env,(e :: exps),(p :: props))
equation
(cache,extargs) = instExtGetFargs2(cache,env, exps, props);
(cache,extarg) = instExtGetFargsSingle(cache,env, e, p);
(cache,extargs) = instExtGetFargs2(cache, env, exps, props);
(cache,extarg) = instExtGetFargsSingle(cache, env, e, p);
then
(cache,extarg :: extargs);
end match;
Expand Down Expand Up @@ -13227,13 +13233,32 @@ algorithm
DAE.Exp dim,exp;
DAE.Properties prop;
Env.Cache cache;
SCode.Variability variability;
Values.Value val;

case (cache,env,DAE.CREF(componentRef = cref,ty = crty),DAE.PROP(type_ = ty,constFlag = cnst))
equation
(cache,attr,ty,bnd,_,_,_,_,_) = Lookup.lookupVarLocal(cache,env, cref);
(cache,attr,ty,bnd,_,_,_,_,_) = Lookup.lookupVarLocal(cache,env,cref);
then
(cache,DAE.EXTARG(cref,attr,ty));

// adrpo: these can be non-local if they are constants or parameters!
case (cache,env,DAE.CREF(componentRef = cref,ty = crty),DAE.PROP(type_ = ty,constFlag = cnst))
equation
(cache,attr as DAE.ATTR(variability = variability),ty,bnd,_,_,_,_,_) = Lookup.lookupVar(cache,env,cref);
true = SCode.isConstant(variability);
(cache, exp, prop) = Ceval.cevalIfConstant(cache, env, inExp, inProperties, false, Absyn.dummyInfo);
then
(cache,DAE.EXTARGEXP(exp, ty));

// adrpo: these can be non-local if they are constants or parameters!
case (cache,env,DAE.CREF(componentRef = cref,ty = crty),DAE.PROP(type_ = ty,constFlag = cnst))
equation
(cache,attr as DAE.ATTR(variability = variability),ty,bnd,_,_,_,_,_) = Lookup.lookupVar(cache,env,cref);
true = SCode.isParameterOrConst(variability);
then
(cache,DAE.EXTARG(cref, attr, ty));

case (cache,env,DAE.CREF(componentRef = cref,ty = crty),DAE.PROP(type_ = ty,constFlag = cnst))
equation
failure((_,_,_,_,_,_,_,_,_) = Lookup.lookupVarLocal(cache,env,cref));
Expand Down
57 changes: 47 additions & 10 deletions Compiler/FrontEnd/Static.mo
Expand Up @@ -3444,7 +3444,7 @@ algorithm
c1 = Types.constAnd(c1,Types.propAllConst(prop));
sty = Types.getPropType(prop);
(cache,dimvals,_) = Ceval.cevalList(cache, env, dims_1, impl, NONE(), Ceval.NO_MSG());
(cache,exp,prop) = elabBuiltinFill2(cache, env, s_1, sty, dimvals, c1, pre);
(cache,exp,prop) = elabBuiltinFill2(cache, env, s_1, sty, dimvals, c1, pre, dims, info);
then
(cache, exp, prop);

Expand Down Expand Up @@ -3479,6 +3479,15 @@ algorithm
then
(cache, exp, prop);

case (cache,env,dims,_,impl,pre,_)
equation
str = "Static.elabBuiltinFill failed in component" +& PrefixUtil.printPrefixStr3(inPrefix) +&
" and scope: " +& Env.printEnvPathStr(env) +&
" for expression: fill(" +& Dump.printExpLstStr(dims) +& ")";
Error.addSourceMessage(Error.INTERNAL_ERROR, {str}, info);
then
fail();

case (cache,env,dims,_,impl,pre,_)
equation
true = Flags.isSet(Flags.FAILTRACE);
Expand Down Expand Up @@ -3509,11 +3518,13 @@ public function elabBuiltinFill2
input list<Values.Value> inValuesValueLst;
input DAE.Const constVar;
input Prefix.Prefix inPrefix;
input list<Absyn.Exp> inDims;
input Absyn.Info inInfo;
output Env.Cache outCache;
output DAE.Exp outExp;
output DAE.Properties outProperties;
algorithm
(outCache,outExp,outProperties) := matchcontinue (inCache,inEnv,inExp,inType,inValuesValueLst,constVar,inPrefix)
(outCache,outExp,outProperties) := matchcontinue (inCache,inEnv,inExp,inType,inValuesValueLst,constVar,inPrefix,inDims,inInfo)
local
list<DAE.Exp> arraylist;
DAE.Type at;
Expand All @@ -3529,29 +3540,43 @@ algorithm
Prefix.Prefix pre;
String str;

case (cache,env,s,sty,{Values.INTEGER(integer = v)},c1,_)
// we might get here negative integers!
case (cache,env,s,sty,{Values.INTEGER(integer = v)},c1,_,_,_)
equation
true = intLt(v, 0); // fill with 0 then!
v = 0;
arraylist = List.fill(s, v);
sty2 = DAE.T_ARRAY(sty, {DAE.DIM_INTEGER(v)}, DAE.emptyTypeSource);
at = Types.simplifyType(sty2);
a = Types.isArray(sty2, {});
then
(cache,DAE.ARRAY(at,a,arraylist),DAE.PROP(sty2,c1));

case (cache,env,s,sty,(Values.INTEGER(integer = v) :: rest),c1,pre)
case (cache,env,s,sty,{Values.INTEGER(integer = v)},c1,_,_,_)
equation
(cache,exp,DAE.PROP(ty,con)) = elabBuiltinFill2(cache,env, s, sty, rest,c1,pre);
arraylist = List.fill(s, v);
sty2 = DAE.T_ARRAY(sty, {DAE.DIM_INTEGER(v)}, DAE.emptyTypeSource);
at = Types.simplifyType(sty2);
a = Types.isArray(sty2, {});
then
(cache,DAE.ARRAY(at,a,arraylist),DAE.PROP(sty2,c1));

case (cache,env,s,sty,(Values.INTEGER(integer = v) :: rest),c1,pre,_,_)
equation
(cache,exp,DAE.PROP(ty,con)) = elabBuiltinFill2(cache,env, s, sty, rest,c1,pre,inDims,inInfo);
arraylist = List.fill(exp, v);
sty2 = DAE.T_ARRAY(ty, {DAE.DIM_INTEGER(v)}, DAE.emptyTypeSource);
at = Types.simplifyType(sty2);
a = Types.isArray(sty2, {});
then
(cache,DAE.ARRAY(at,a,arraylist),DAE.PROP(sty2,c1));

case (_,_,_,_,_,_,pre)
case (cache,env,s,sty,_,c1,_,_,_)
equation
str = "Static.elabBuiltinFill2 failed in component" +& PrefixUtil.printPrefixStr3(inPrefix);
Error.addMessage(Error.INTERNAL_ERROR, {str});
str = "Static.elabBuiltinFill2 failed in component" +& PrefixUtil.printPrefixStr3(inPrefix) +&
" and scope: " +& Env.printEnvPathStr(env) +&
" for expression: fill(" +& Dump.printExpLstStr(inDims) +& ")";
Error.addSourceMessage(Error.INTERNAL_ERROR, {str}, inInfo);
then
fail();
end matchcontinue;
Expand Down Expand Up @@ -14100,7 +14125,10 @@ algorithm
// bug #2113, seems that there is nothing in the specs
// that requires that fill arguments are of parameter/constant
// variability, so allow it.
else DAE.C_UNKNOWN();
else
equation
true = Config.splitArrays();
then DAE.C_UNKNOWN();
end matchcontinue;
end unevaluatedFunctionVariability;

Expand Down Expand Up @@ -14408,6 +14436,15 @@ algorithm
then
(inCache, SOME(DAE.DIM_UNKNOWN()));

// an integer parameter with no binding
case (_, _, _, DAE.PROP(DAE.T_INTEGER(varLst = _), cnst), _, _, _, _, _)
equation
true = Types.isParameterOrConstant(cnst);
e_str = ExpressionDump.printExpStr(inExp);
Error.addSourceMessage(Error.STRUCTURAL_PARAMETER_OR_CONSTANT_WITH_NO_BINDING, {e_str}, inInfo);
then
(inCache, NONE());

case (_, _, _, DAE.PROP(ty, _), _, _, _, _, _)
equation
e_str = ExpressionDump.printExpStr(inExp);
Expand Down
2 changes: 2 additions & 0 deletions Compiler/Util/Error.mo
Expand Up @@ -706,6 +706,8 @@ public constant Message UNSUPPORTED_REDUCTION_TYPE = MESSAGE(5031, TRANSLATION()
Util.gettext("Expected a reduction function with type signature ('A,'B) => 'B, but got %s."));
public constant Message FOUND_NON_NUMERIC_TYPES = MESSAGE(5032, TRANSLATION(), ERROR(),
Util.gettext("Operator %s expects numeric types as operands, but got '%s and %s'."));
public constant Message STRUCTURAL_PARAMETER_OR_CONSTANT_WITH_NO_BINDING = MESSAGE(5033, TRANSLATION(), ERROR(),
Util.gettext("Structural parameter (or constant): %s which gives array dimensions has no binding. Array dimensions must be known at compile time."));
public constant Message COMPILER_ERROR = MESSAGE(5999, TRANSLATION(), ERROR(),
Util.notrans("%s"));
public constant Message COMPILER_WARNING = MESSAGE(6000, TRANSLATION(), WARNING(),
Expand Down

0 comments on commit e833582

Please sign in to comment.