Skip to content

Commit

Permalink
- Added an error for components having bindings of variabilty higher …
Browse files Browse the repository at this point in the history
…than their own (see http://openmodelica.ida.liu.se:8080/cb/issue/1040);

- Fixed a bug in lookupVarF returning wrong properties;
- Improved error messages for non-processed modifications of built-in types;
- Modified testsuite accordingly.

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@5760 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Alexey Lebedev committed Jun 30, 2010
1 parent 9b5a9f3 commit bb14693
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 27 deletions.
3 changes: 3 additions & 0 deletions Compiler/Error.mo
Expand Up @@ -213,6 +213,7 @@ public constant ErrorID NESTED_WHEN=125;
public constant ErrorID INVALID_ENUM_LITERAL=126;
public constant ErrorID UNEXCPECTED_FUNCTION_INPUTS_WARNING=127;
public constant ErrorID DUPLICATE_CLASSES_NOT_EQUIVALENT=128;
public constant ErrorID HIGHER_VARIABILITY_BINDING=129;

public constant ErrorID UNBOUND_PARAMETER_WARNING=500;
public constant ErrorID BUILTIN_FUNCTION_SUM_HAS_SCALAR_PARAMETER=501;
Expand Down Expand Up @@ -532,6 +533,8 @@ protected constant list<tuple<Integer, MessageType, Severity, String>> errorTabl
"Illegal derivative. der(%s) where %s is of type %s, which is not a subtype of Real"),
(IMPLICIT_ITERATOR_NOT_FOUND_IN_LOOP_BODY,TRANSLATION(),ERROR(),
"Identificator %s of implicit for iterator must be present as array subscript in the loop body."),
(HIGHER_VARIABILITY_BINDING(),TRANSLATION(),ERROR(),
"Component %s of variability %s has binding %s of higher variability %s."),

(INCOMPATIBLE_TYPES_FUNC,SYMBOLIC(),ERROR(),
"While deriving %s to %s, types of inputs: %s and type of %s: %s did not match"),
Expand Down
92 changes: 74 additions & 18 deletions Compiler/Inst.mo
Expand Up @@ -2068,7 +2068,7 @@ algorithm
case(cache,env,( mym as DAE.MOD(f,e,smod::submods,eqmod)),pre)
local String s1; DAE.SubMod smod; DAE.Mod mym;
equation
s1 = Mod.prettyPrintMod(mym,0) +& ", not found in the built-in class Real";
s1 = Mod.prettyPrintSubmod(smod) +& ", not processed in the built-in class Real";
Error.addMessage(Error.UNUSED_MODIFIER,{s1});
then fail();
case(cache,env,DAE.MOD(f,e,{},eqmod),pre) then {};
Expand Down Expand Up @@ -2125,7 +2125,7 @@ algorithm
case(cache,env,DAE.MOD(f,e,smod::submods,eqmod),pre)
local String s1; DAE.SubMod smod;
equation
s1 = Mod.prettyPrintMod(mods,0) +& ", not found in the built-in class Integer";
s1 = Mod.prettyPrintSubmod(smod) +& ", not processed in the built-in class Integer";
Error.addMessage(Error.UNUSED_MODIFIER,{s1});
then fail();
case(cache,env,DAE.MOD(f,e,{},eqmod),pre) then {};
Expand Down Expand Up @@ -2161,7 +2161,7 @@ algorithm
case(cache,env,DAE.MOD(f,e,smod::submods,eqmod),pre)
local String s1; DAE.SubMod smod;
equation
s1 = Mod.prettyPrintMod(mods,0) +& ", not found in the built-in class String";
s1 = Mod.prettyPrintSubmod(smod) +& ", not processed in the built-in class String";
Error.addMessage(Error.UNUSED_MODIFIER,{s1});
then fail();
case(cache,env,DAE.MOD(f,e,{},eqmod),pre) then {};
Expand Down Expand Up @@ -2202,7 +2202,7 @@ algorithm
case(cache,env,DAE.MOD(f,e,smod::submods,eqmod),pre)
local String s1; DAE.SubMod smod;
equation
s1 = Mod.prettyPrintMod(mods,0) +& ", not found in the built-in class Boolean";
s1 = Mod.prettyPrintSubmod(smod) +& ", not processed in the built-in class Boolean";
Error.addMessage(Error.UNUSED_MODIFIER,{s1});
then fail();
case(cache,env,DAE.MOD(f,e,{},eqmod),pre) then {};
Expand Down Expand Up @@ -2253,7 +2253,7 @@ algorithm
case(cache,env,DAE.MOD(f,e,smod::submods,eqmod),pre)
local String s1; DAE.SubMod smod;
equation
s1 = Mod.prettyPrintMod(mods,0) +& ", not found in the built-in class Enumeration";
s1 = Mod.prettyPrintSubmod(smod) +& ", not processed in the built-in class Enumeration";
Error.addMessage(Error.UNUSED_MODIFIER,{s1});
then fail();
case(cache,env,DAE.MOD(f,e,{},eqmod),pre) then {};
Expand All @@ -2277,26 +2277,38 @@ algorithm
var := matchcontinue(cache,env,id,optVal,bind,expectedTp,bindProp)
local
Values.Value v; DAE.Type t_1,bindTp; DAE.Exp bind1;
DAE.Const c;

case(cache,env,id,SOME(v),bind,expectedTp,DAE.PROP(bindTp,_))
case(cache,env,id,SOME(v),bind,expectedTp,DAE.PROP(bindTp,c))
equation
failure(equality(c=DAE.C_VAR));
(bind1,t_1) = Types.matchType(bind,bindTp,expectedTp,true);
then DAE.TYPES_VAR(id,DAE.ATTR(false,false,SCode.RO(),SCode.PARAM(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
false,t_1,DAE.EQBOUND(bind1,SOME(v),DAE.C_PARAM()),NONE());

case(cache,env,id,_,bind,expectedTp,DAE.PROP(bindTp,_))
case(cache,env,id,_,bind,expectedTp,DAE.PROP(bindTp,c))
equation
failure(equality(c=DAE.C_VAR));
(bind1,t_1) = Types.matchType(bind,bindTp,expectedTp,true);
(cache,v,_) = Ceval.ceval(cache,env, bind1, false, NONE, NONE, Ceval.NO_MSG());
then DAE.TYPES_VAR(id,DAE.ATTR(false,false,SCode.RO(),SCode.PARAM(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
false,t_1,DAE.EQBOUND(bind1,SOME(v),DAE.C_PARAM()),NONE());

case(cache,env,id,_,bind,expectedTp,DAE.PROP(bindTp,_))
case(cache,env,id,_,bind,expectedTp,DAE.PROP(bindTp,c))
equation
(bind1,t_1) = Types.matchType(bind,bindTp,expectedTp,true);
failure(equality(c=DAE.C_VAR));
(bind1,t_1) = Types.matchType(bind,bindTp,expectedTp,true);
then DAE.TYPES_VAR(id,DAE.ATTR(false,false,SCode.RO(),SCode.PARAM(),Absyn.BIDIR(),Absyn.UNSPECIFIED()),
false,t_1,DAE.EQBOUND(bind1,NONE(),DAE.C_PARAM()),NONE());

case(cache,env,id,_,bind,expectedTp,DAE.PROP(bindTp,c))
local String s;
equation
equality(c=DAE.C_VAR);
s = Exp.printExpStr(bind);
Error.addMessage(Error.HIGHER_VARIABILITY_BINDING,{id,"PARAM",s,"VAR"});
then fail();

case(cache,env,id,_,bind,expectedTp,DAE.PROP(bindTp,_)) local String s1,s2;
equation
failure((_,_) = Types.matchType(bind,bindTp,expectedTp,true));
Expand Down Expand Up @@ -6759,7 +6771,7 @@ algorithm

// set the source of this element
source = DAEUtil.createElementSource(Env.getEnvPath(env), PrefixUtil.prefixToCrefOpt(pre), NONE(), NONE());
eOpt = makeVariableBinding(ty,mod);
eOpt = makeVariableBinding(ty,mod,DAE.C_CONST,pre,n);
dae3 = daeDeclare(cr, ci_state, ty, SCode.ATTR({},flowPrefix,streamPrefix,acc,vt,dir),prot, eOpt, inst_dims, NONE, dae_var_attr, comment,io,finalPrefix,source,false);
dae = DAEUtil.joinDaes(dae1_1, dae3);
store = UnitAbsynBuilder.instAddStore(store,ty,cr);
Expand All @@ -6785,7 +6797,7 @@ algorithm

// set the source of this element
source = DAEUtil.createElementSource(Env.getEnvPath(env), PrefixUtil.prefixToCrefOpt(pre), NONE(), NONE());
eOpt = makeVariableBinding(ty,mod);
eOpt = makeVariableBinding(ty,mod,DAE.C_PARAM,pre,n);
dae3 = daeDeclare(cr, ci_state, ty, SCode.ATTR({},flowPrefix,streamPrefix,acc,vt,dir),prot, eOpt, inst_dims, start, dae_var_attr, comment,io,finalPrefix, source, false);

dae2 = instModEquation(cr, ty, mod, source, impl);
Expand Down Expand Up @@ -6831,7 +6843,7 @@ algorithm
//Debug.fprint("insttrind", "\n ******************\n ");
//Debug.fprint("insttrind", "\n ");
start = instStartBindingExp(mod, ty, idxs_1);
eOpt = makeVariableBinding(ty,mod);
eOpt = makeVariableBinding(ty,mod,DAE.C_VAR,pre,n);
(cache,dae_var_attr) = instDaeVariableAttributes(cache,env, mod, ty, {}) "idxs\'" ;
dir = propagateAbSCDirection(dir,oDA);
// adrpo: we cannot check this here as:
Expand Down Expand Up @@ -6943,22 +6955,66 @@ If the type is not externa object, the normal binding value is bound,
Unless it is a complex var that not inherites a basic type. In that case DAE.Equation are generated."
input DAE.Type tp;
input DAE.Mod mod;
input DAE.Const const;
input Prefix.Prefix pre;
input Ident name;
output Option<DAE.Exp> eOpt;
algorithm eOpt := matchcontinue(tp,mod)
local DAE.Exp e,e1;DAE.Properties p;
algorithm eOpt := matchcontinue(tp,mod,const,pre,name)
local
DAE.Exp e,e1;DAE.Properties p;
DAE.Const c,c1;
Ident n;
Prefix.Prefix pr;
case ((DAE.T_COMPLEX(complexClassType=ClassInf.EXTERNAL_OBJ(_)),_),
DAE.MOD(eqModOption = SOME(DAE.TYPED(e,_,_,_))))
DAE.MOD(eqModOption = SOME(DAE.TYPED(e,_,_,_))),_,_,_)
then SOME(e);
case(tp,mod)
case(tp,mod,c,pr,n)
equation
SOME(DAE.TYPED(e,_,p,_)) = Mod.modEquation(mod);
(e1,_) = Types.matchProp(e,p,DAE.PROP(tp,DAE.C_VAR()),true);
(e1,DAE.PROP(_,c1)) = Types.matchProp(e,p,DAE.PROP(tp,c),true);
checkHigherVariability(c,c1,pr,n,e);
then
SOME(e1);
case (_,_) then NONE;
case (_,mod,_,_,_)
equation
failure(SOME(DAE.TYPED(_,_,_,_)) = Mod.modEquation(mod));
then NONE;
end matchcontinue;
end makeVariableBinding;

protected function checkHigherVariability
"If the binding expression has higher variability that the component, generates an error.
Helper to makeVariableBinding. Author -- alleb"
input DAE.Const compConst;
input DAE.Const bindConst;
input Prefix.Prefix pre;
input Ident name;
input DAE.Exp binding;
algorithm
_ := matchcontinue(compConst,bindConst,pre,name,binding)
local
DAE.Const c,c1;
Prefix.Prefix p;
Ident n;
String sc,sc1,se,sn;
DAE.Exp e;
case (c,c1,_,_,_)
equation
equality(c=c1);
then ();
// Since c1 is generated by Types.matchProp, it can not be lower that c, so no need to check that it is higher
case (c,c1,pre,n,e)
equation
sn = PrefixUtil.printPrefixStr2(pre)+&n;
sc = DAEUtil.constStr(c);
sc1 = DAEUtil.constStr(c1);
se = Exp.printExpStr(e);
Error.addMessage(Error.HIGHER_VARIABILITY_BINDING,{sn,sc,se,sc1});
then
fail();
end matchcontinue;
end checkHigherVariability;

public function makeArrayType
"function: makeArrayType
Creates an array type from the element type
Expand Down
16 changes: 9 additions & 7 deletions Compiler/Lookup.mo
Expand Up @@ -2470,7 +2470,7 @@ algorithm
String n,id;
Boolean f,streamPrefix;
SCode.Accessibility acc;
SCode.Variability vt;
SCode.Variability vt,vt2;
Absyn.Direction di;
tuple<DAE.TType, Option<Absyn.Path>> ty,ty_1,idTp;
DAE.Binding bind,binding,binding2;
Expand Down Expand Up @@ -2512,12 +2512,12 @@ algorithm
case (cache,ht,xCref as (DAE.CREF_QUAL(ident = id,subscriptLst = ss,componentRef = ids)))
local Types.Type idTp;
equation
(cache,DAE.TYPES_VAR(n,DAE.ATTR(f,streamPrefix,acc,vt,di,io),_,ty2,bind,cnstForRange),_,_,componentEnv) = lookupVar2(cache,ht, id);
(cache,DAE.TYPES_VAR(n,DAE.ATTR(_,_,_,vt2,_,_),_,ty2,bind,cnstForRange),_,_,componentEnv) = lookupVar2(cache,ht, id);
// outer variables are not local!
// this doesn't work yet!
// false = Absyn.isOuter(io);
//
(cache,attr,ty,binding,cnstForRange,SPLICEDEXPDATA(texp,idTp),_,componentEnv) = lookupVar(cache, componentEnv, ids);
(cache,DAE.ATTR(f,streamPrefix,acc,vt,di,io),ty,binding,cnstForRange,SPLICEDEXPDATA(texp,idTp),_,componentEnv) = lookupVar(cache, componentEnv, ids);
(tCref::ltCref) = elabComponentRecursive((texp));
ty1 = checkSubscripts(ty2, ss);
ty = sliceDimensionType(ty1,ty);
Expand All @@ -2526,17 +2526,19 @@ algorithm
xCref = DAE.CREF_QUAL(id,ty2_2,ss,tCref);
eType = Types.elabType(ty);
splicedExp = DAE.CREF(xCref,eType);
vt = SCode.variabilityOr(vt,vt2);
then
(cache,attr,ty,binding,cnstForRange,SPLICEDEXPDATA(SOME(splicedExp),idTp),componentEnv);
(cache,DAE.ATTR(f,streamPrefix,acc,vt,di,io),ty,binding,cnstForRange,SPLICEDEXPDATA(SOME(splicedExp),idTp),componentEnv);

// Qualified componentname without spliced exp.
case (cache,ht,xCref as (DAE.CREF_QUAL(ident = id,subscriptLst = ss,componentRef = ids)))
equation
(cache,DAE.TYPES_VAR(n,DAE.ATTR(f,streamPrefix,acc,vt,di,io),_,ty2,bind,cnstForRange),_,_,componentEnv) = lookupVar2(cache,ht, id);
(cache,attr,ty,binding,cnstForRange,SPLICEDEXPDATA(texp,idTp),_,componentEnv) = lookupVar(cache, componentEnv, ids);
(cache,DAE.TYPES_VAR(n,DAE.ATTR(_,_,_,vt2,_,_),_,ty2,bind,cnstForRange),_,_,componentEnv) = lookupVar2(cache,ht, id);
(cache,DAE.ATTR(f,streamPrefix,acc,vt,di,io),ty,binding,cnstForRange,SPLICEDEXPDATA(texp,idTp),_,componentEnv) = lookupVar(cache, componentEnv, ids);
{} = elabComponentRecursive((texp));
vt = SCode.variabilityOr(vt,vt2);
then
(cache,attr,ty,binding,cnstForRange,SPLICEDEXPDATA(NONE(),idTp),componentEnv);
(cache,DAE.ATTR(f,streamPrefix,acc,vt,di,io),ty,binding,cnstForRange,SPLICEDEXPDATA(NONE(),idTp),componentEnv);
end matchcontinue;
end lookupVarF;

Expand Down
30 changes: 30 additions & 0 deletions Compiler/Mod.mo
Expand Up @@ -2174,6 +2174,36 @@ algorithm str := matchcontinue(inSubs,depth)
end matchcontinue;
end prettyPrintSubs;

public function prettyPrintSubmod "
Prints a readable format of a sub-modifier, used in error reporting for built-in classes"
input DAE.SubMod inSub;
output String str;
algorithm str := matchcontinue(inSub)
local
String s1,s2,id;
DAE.Mod m;
list<Integer> li;
case(DAE.NAMEMOD(id,(m as DAE.REDECL(finalPrefix=_))))
equation
s2 = " redeclare(" +& id +& ")";
then
s2;
case(DAE.NAMEMOD(id,m))
equation
s2 = prettyPrintMod(m,0);
s2 = Util.if_(stringLength(s2) == 0, ""," = " +& s2);
s2 = id +& s2;
then
s2;
case(DAE.IDXMOD(li,m))
equation
s2 = prettyPrintMod(m,0);
s1 = "["+& Util.stringDelimitList(Util.listMap(li,intString),",")+&"]" +& " = " +& s2;
then
s1;
end matchcontinue;
end prettyPrintSubmod;

public function printSubs1Str "function: printSubs1Str
Helper function to printModStr"
input list<DAE.SubMod> inTypesSubModLst;
Expand Down
14 changes: 14 additions & 0 deletions Compiler/PrefixUtil.mo
Expand Up @@ -99,6 +99,20 @@ algorithm
end matchcontinue;
end printPrefixStr;

public function printPrefixStr2 "function: printPrefixStr2
Prints a Prefix to a string. Designed to be used in Error messages"
input Prefix inPrefix;
output String outString;
algorithm
outString := matchcontinue (inPrefix)
local
Prefix p;
case Prefix.NOPRE() then "";
case Prefix.PREFIX(Prefix.NOCOMPPRE(),_) then "";
case p then printPrefixStr(p)+&".";
end matchcontinue;
end printPrefixStr2;

public function printPrefix "function: printPrefix
Prints a prefix to the Print buffer."
input Prefix p;
Expand Down
16 changes: 16 additions & 0 deletions Compiler/SCode.mo
Expand Up @@ -2271,6 +2271,22 @@ algorithm
{"quantity", "min", "max", "start", "fixed"});
end isValidEnumLiteral;

public function variabilityOr
"returns the more constant of two Variabilities (considers VAR < DISCRETE < PARAM < CONST ), similarly to Types.constOr"
input Variability inConst1;
input Variability inConst2;
output Variability outConst;
algorithm
outConst := matchcontinue(inConst1, inConst2)
case (CONST,_) then CONST;
case (_,CONST) then CONST;
case (PARAM,_) then PARAM;
case (_,PARAM) then PARAM;
case (DISCRETE,_) then DISCRETE;
case (_,DISCRETE) then DISCRETE;
case (_,_) then VAR;
end matchcontinue;
end variabilityOr;

end SCode;

4 changes: 2 additions & 2 deletions Compiler/Static.mo
Expand Up @@ -3176,7 +3176,7 @@ algorithm
(cache,dimp,DAE.PROP(_,c1),_,dae1) = elabExp(cache, env, dim, impl, NONE, true) ;
(cache,arraycrefe,DAE.PROP(arrtp,_),_,dae2) = elabExp(cache, env, arraycr, impl, NONE, true);
c2 = Types.dimensionsKnown(arrtp);
c2_1 = Types.boolConst(c2);
c2_1 = Types.boolConstSize(c2);
c = Types.constAnd(c1, c2_1);
exp = DAE.SIZE(arraycrefe,SOME(dimp));
dae = DAEUtil.joinDaes(dae1,dae2);
Expand All @@ -3189,7 +3189,7 @@ algorithm
equation
(cache,arraycrefe,DAE.PROP(arrtp,_),_,dae1) = elabExp(cache,env, arraycr, impl, NONE,true) ;
c = Types.dimensionsKnown(arrtp);
c_1 = Types.boolConst(c);
c_1 = Types.boolConstSize(c);
exp = DAE.SIZE(arraycrefe,NONE);
then
(cache,exp,DAE.PROP((DAE.T_ARRAY(DAE.DIM(SOME(1)),DAE.T_INTEGER_DEFAULT),NONE),c_1),dae1);
Expand Down
16 changes: 16 additions & 0 deletions Compiler/Types.mo
Expand Up @@ -4730,6 +4730,22 @@ algorithm
end matchcontinue;
end boolConst;

public function boolConstSize "function: boolConstSize
author: alleb
A version of boolConst supposed to be used by Static.elabBuiltinSize.
Creates a Const value from a bool. If true, C_CONST,
if false C_PARAM."
input Boolean inBoolean;
output Const outConst;
algorithm
outConst:=
matchcontinue (inBoolean)
case (false) then DAE.C_PARAM();
case (true) then DAE.C_CONST();
end matchcontinue;
end boolConstSize;

public function printPropStr "function: printPropStr
Print the properties to a string."
input Properties inProperties;
Expand Down

0 comments on commit bb14693

Please sign in to comment.