Skip to content

Commit

Permalink
- Disallow local variables shadowing in/out
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@12581 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
sjoelund committed Aug 18, 2012
1 parent ba976eb commit 9c81b9d
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 25 deletions.
1 change: 0 additions & 1 deletion Compiler/BackEnd/BackendDAEOptimize.mo
Original file line number Diff line number Diff line change
Expand Up @@ -5420,7 +5420,6 @@ protected function matrixVectorMultiplication
algorithm
(outExp,outLstRef) := matchcontinue(jac,row,col,vars,size,inExpArr,inLstRef)
local
list<tuple<Integer, Integer, BackendDAE.Equation>> jac;
DAE.Exp e,exp1,eqExp,varExp;
array<DAE.Exp> expArr;
DAE.ComponentRef cr;
Expand Down
3 changes: 1 addition & 2 deletions Compiler/BackEnd/SimCode.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1298,7 +1298,7 @@ algorithm
DAE.Function daeMainFunction;
Function mainFunction;
list<Function> fns;
list<String> libs, includes, includeDirs;
list<String> libs, includeDirs;
MakefileParams makefileParams;
FunctionCode fnCode;
list<RecordDeclaration> extraRecordDecls;
Expand Down Expand Up @@ -2280,7 +2280,6 @@ algorithm
list<BackendDAE.Variables> orderedVars;
BackendDAE.Variables knownVars,vars;
list<BackendDAE.Var> varlst,varlst1,varlst2;
list<RecordDeclaration> recordDecls;

list<JacobianMatrix> LinearMatrices;
HashTableCrefToSimVar crefToSimVarHT;
Expand Down
53 changes: 36 additions & 17 deletions Compiler/FrontEnd/Inst.mo
Original file line number Diff line number Diff line change
Expand Up @@ -11317,7 +11317,7 @@ algorithm
inlineType = isInlineFunc2(c);
partialPrefixBool = SCode.partialBool(partialPrefix);

daeElts = optimizeFunction(fpath,daeElts,NONE(),{},{},{});
daeElts = optimizeFunctionCheckForLocals(fpath,daeElts,NONE(),{},{},{});
cmt = extractClassDefComment(cache, env, cd);
/* Not working 100% yet... Also, a lot of code has unused inputs :( */
Debug.bcall3(false and Config.acceptMetaModelicaGrammar() and not instFunctionTypeOnly,checkFunctionInputUsed,daeElts,NONE(),Absyn.pathString(fpath));
Expand Down Expand Up @@ -17324,8 +17324,9 @@ algorithm
end matchcontinue;
end redeclareBasicType;

protected function optimizeFunction
"Does for example tail recursion optimization"
protected function optimizeFunctionCheckForLocals
"* Checks for shadowing local declarations
* Does tail recursion optimization"
input Absyn.Path path;
input list<DAE.Element> inElts;
input Option<DAE.Element> oalg;
Expand All @@ -17347,24 +17348,25 @@ algorithm
equation
// Adding tail recursion optimization
stmts = optimizeLastStatementTail(path,stmts,listReverse(invars),listReverse(outvars),{});
(_,(false,_)) = DAEUtil.traverseDAEEquationsStmts(stmts,checkMatchShadowing,(false,invars));
then listReverse(DAE.ALGORITHM(DAE.ALGORITHM_STMTS(stmts),source)::acc);
// Remove empty sections
case (path,(elt1 as DAE.ALGORITHM(algorithm_=DAE.ALGORITHM_STMTS({})))::elts,oalg,acc,invars,outvars)
then optimizeFunction(path,elts,oalg,acc,invars,outvars);
then optimizeFunctionCheckForLocals(path,elts,oalg,acc,invars,outvars);
case (path,(elt1 as DAE.ALGORITHM(source=source))::elts,SOME(elt2),acc,invars,outvars)
equation
str = Absyn.pathString(path);
Error.addSourceMessage(Error.FUNCTION_MULTIPLE_ALGORITHM,{str},DAEUtil.getElementSourceFileInfo(source));
then optimizeFunction(path,elts,SOME(elt1),elt2::acc,invars,outvars);
then optimizeFunctionCheckForLocals(path,elts,SOME(elt1),elt2::acc,invars,outvars);
case (path,(elt as DAE.ALGORITHM(source=_))::elts,NONE(),acc,invars,outvars)
then optimizeFunction(path,elts,SOME(elt),acc,invars,outvars);
then optimizeFunctionCheckForLocals(path,elts,SOME(elt),acc,invars,outvars);
case (path,(elt as DAE.VAR(componentRef=DAE.CREF_IDENT(ident=name),direction=DAE.OUTPUT()))::elts,oalg,acc,invars,outvars)
then optimizeFunction(path,elts,oalg,elt::acc,invars,name::outvars);
then optimizeFunctionCheckForLocals(path,elts,oalg,elt::acc,invars,name::outvars);
case (path,(elt as DAE.VAR(componentRef=DAE.CREF_IDENT(ident=name),direction=DAE.INPUT()))::elts,oalg,acc,invars,outvars)
then optimizeFunction(path,elts,oalg,elt::acc,name::invars,outvars);
case (path,elt::elts,oalg,acc,invars,outvars) then optimizeFunction(path,elts,oalg,elt::acc,invars,outvars);
then optimizeFunctionCheckForLocals(path,elts,oalg,elt::acc,name::invars,outvars);
case (path,elt::elts,oalg,acc,invars,outvars) then optimizeFunctionCheckForLocals(path,elts,oalg,elt::acc,invars,outvars);
end match;
end optimizeFunction;
end optimizeFunctionCheckForLocals;

protected function optimizeLastStatementTail
input Absyn.Path path;
Expand Down Expand Up @@ -17507,35 +17509,52 @@ algorithm
then (DAE.IFEXP(e1,e2,e3),true);
case (path,DAE.MATCHEXPRESSION(matchType as DAE.MATCH(_) /*TODO:matchcontinue*/,inputs,localDecls,cases,et),vars,source)
equation
checkShadowing(localDecls,vars);
cases = optimizeStatementTailMatchCases(path,cases,false,{},vars,source);
then (DAE.MATCHEXPRESSION(matchType,inputs,localDecls,cases,et),true);
else (rhs,false);
end matchcontinue;
end optimizeStatementTail3;

protected function checkMatchShadowing
input tuple<DAE.Exp,tuple<Boolean,list<String>>> inTpl;
output tuple<DAE.Exp,tuple<Boolean,list<String>>> outTpl;
algorithm
outTpl := matchcontinue inTpl
local
DAE.Exp exp;
list<String> vars;
list<DAE.Element> localDecls;
Boolean b;
case ((exp as DAE.MATCHEXPRESSION(localDecls=localDecls),(_,vars)))
equation
b = checkShadowing(localDecls,vars);
then ((exp,(b,vars)));
else inTpl;
end matchcontinue;
end checkMatchShadowing;

protected function checkShadowing
input list<DAE.Element> inElts;
input list<String> vars;
output Boolean shadows;
algorithm
_ := matchcontinue (inElts,vars)
shadows := matchcontinue (inElts,vars)
local
String name;
DAE.ElementSource source;
list<DAE.Element> elts;

case ({},_) then ();
case ({},_) then false;
case (DAE.VAR(componentRef=DAE.CREF_IDENT(ident=name))::elts,vars)
equation
// TODO: Make this scale better than squared
false = listMember(name,vars);
checkShadowing(elts,vars);
then ();
then checkShadowing(elts,vars);
case (DAE.VAR(componentRef=DAE.CREF_IDENT(ident=name),source=source)::elts,vars)
equation
true = listMember(name,vars);
Error.addSourceMessage(Error.MATCH_SHADOWING_OPTIMIZER,{name},DAEUtil.getElementSourceFileInfo(source));
then fail();
Error.addSourceMessage(Error.MATCH_SHADOWING,{name},DAEUtil.getElementSourceFileInfo(source));
then true;
end matchcontinue;
end checkShadowing;

Expand Down
1 change: 0 additions & 1 deletion Compiler/FrontEnd/InstExtends.mo
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,6 @@ algorithm
list<SCode.Enum> enumLst;
String n,name;
Option<SCode.ExternalDecl> extdecl;
Absyn.Info info;
Prefix.Prefix pre;

case (cache,env,ih,mod,pre,SCode.CLASS(name = name, classDef =
Expand Down
6 changes: 2 additions & 4 deletions Compiler/Util/Error.mo
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,9 @@ public constant Message RECURSION_DEPTH_REACHED = MESSAGE(526, TRANSLATION(), ER
Util.gettext("The maximum recursion depth was reached, probably due to mutual recursion. The current scope: %s."));

public constant Message MATCH_SHADOWING = MESSAGE(5001, TRANSLATION(), ERROR(),
Util.gettext(" Local variable '%s' shadows input or result variables in a {match,matchcontinue} expression."));
Util.gettext("Local variable '%s' shadows input or result variables in a match-expression."));
public constant Message META_POLYMORPHIC = MESSAGE(5002, TRANSLATION(), ERROR(),
Util.gettext(" %s uses invalid subtypeof syntax. Only subtypeof Any is supported."));
Util.gettext("%s uses invalid subtypeof syntax. Only subtypeof Any is supported."));
public constant Message META_FUNCTION_TYPE_NO_PARTIAL_PREFIX = MESSAGE(5003, TRANSLATION(), ERROR(),
Util.gettext("%s is used as a function reference, but doesn't specify the partial prefix."));
public constant Message META_MATCH_EQUATION_FORBIDDEN = MESSAGE(5004, TRANSLATION(), ERROR(),
Expand Down Expand Up @@ -657,8 +657,6 @@ public constant Message REDUCTION_TYPE_ERROR = MESSAGE(5030, TRANSLATION(), ERRO
Util.gettext("Reductions require the types of the %s and %s to be %s, but got: %s and %s."));
public constant Message UNSUPPORTED_REDUCTION_TYPE = MESSAGE(5031, TRANSLATION(), ERROR(),
Util.gettext("Expected a reduction function with type signature ('A,'B) => 'B, but got %s."));
public constant Message MATCH_SHADOWING_OPTIMIZER = MESSAGE(5032, TRANSLATION(), WARNING(),
Util.gettext("Cannot optimize function due to a local variable having the same name as an input variable: %s."));
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 9c81b9d

Please sign in to comment.