Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit 6f8bb14

Browse files
sjoelundOpenModelica-Hudson
authored andcommitted
Fix code generation where & is used on an rvalue
Added a daeExpReturnLValue function to Susan which converts an rvalue to an lvalue when the code requires it. Can also be used when you want to cache the expression and use its value twice (without evaluating the expression twice). This fixes ticket:4212.
1 parent d5f9643 commit 6f8bb14

File tree

2 files changed

+26
-14
lines changed

2 files changed

+26
-14
lines changed

Compiler/Template/CodegenCFunctions.tpl

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4352,6 +4352,18 @@ end getTempDeclMatchOutputName;
43524352
else error(sourceInfo(), 'Unknown expression: <%ExpressionDumpTpl.dumpExp(exp,"\"")%>')
43534353
end daeExp;
43544354

4355+
/* public */ template daeExpAsLValue(Exp exp, Context context, Text &preExp, Text &varDecls, Text &auxFunction)
4356+
"Generates code for an expression. Makes sure that the output is an lvalue (so you can take the address of it)."
4357+
::=
4358+
let res1 = daeExp(exp, context, &preExp, &varDecls, &auxFunction)
4359+
if isCIdentifier(res1)
4360+
then res1
4361+
else
4362+
let tmp = tempDecl(expTypeFromExpArrayIf(exp),&varDecls)
4363+
let &preExp += '<%tmp%> = <%res1%>;<%\n%>'
4364+
tmp
4365+
end daeExpAsLValue;
4366+
43554367

43564368
template daeExternalCExp(Exp exp, Context context, Text &preExp, Text &varDecls, Text &auxFunction)
43574369
"Like daeExp, but also converts the type to external C"
@@ -5750,20 +5762,20 @@ template daeExpCall(Exp call, Context context, Text &preExp, Text &varDecls, Tex
57505762

57515763
case CALL(path=IDENT(name="max"), attr=CALL_ATTR(ty = ty), expLst={array}) then
57525764
let expVar = daeExp(array, context, &preExp, &varDecls, &auxFunction)
5753-
let arr_tp_str = '<%expTypeArray(ty)%>'
5765+
let arr_tp_str = expTypeArray(ty)
57545766
let tvar = tempDecl(expTypeModelica(ty), &varDecls)
57555767
let &preExp += '<%tvar%> = max_<%arr_tp_str%>(<%expVar%>);<%\n%>'
57565768
tvar
57575769

57585770
case CALL(path=IDENT(name="min"), attr=CALL_ATTR(ty = ty), expLst={array}) then
57595771
let expVar = daeExp(array, context, &preExp, &varDecls, &auxFunction)
5760-
let arr_tp_str = '<%expTypeArray(ty)%>'
5772+
let arr_tp_str = expTypeArray(ty)
57615773
let tvar = tempDecl(expTypeModelica(ty), &varDecls)
57625774
let &preExp += '<%tvar%> = min_<%arr_tp_str%>(<%expVar%>);<%\n%>'
57635775
tvar
57645776

57655777
case CALL(path=IDENT(name="fill"), expLst=val::dims, attr=CALL_ATTR(ty = ty)) then
5766-
let valExp = daeExp(val, context, &preExp, &varDecls, &auxFunction)
5778+
let valExp = daeExpAsLValue(val, context, &preExp, &varDecls, &auxFunction)
57675779
let dimsExp = (dims |> dim =>
57685780
daeExp(dim, context, &preExp, &varDecls, &auxFunction) ;separator=", ")
57695781
let ty_str = expTypeArray(ty)
@@ -5776,7 +5788,7 @@ template daeExpCall(Exp call, Context context, Text &preExp, Text &varDecls, Tex
57765788
let tvarc = tempDecl("int", &varDecls)
57775789
let tvardata = tempDecl("void *", &varDecls)
57785790
let nElts = tempDecl("int", &varDecls)
5779-
let val = daeExp(exp, context, &preExp, &varDecls, &auxFunction)
5791+
let val = daeExpAsLValue(exp, context, &preExp, &varDecls, &auxFunction)
57805792
let szElt = 'sizeof(<%expTypeModelica(ty)%>)'
57815793
let dims =
57825794
(getDimensionSizes(Expression.typeof(exp)) |> sz hasindex ix fromindex 1 =>
@@ -5802,51 +5814,51 @@ simple_alloc_1d_base_array(&<%tvar%>, <%nElts%>, <%tvardata%>);
58025814
case CALL(path=IDENT(name="cat"), expLst=dim::arrays, attr=CALL_ATTR(ty = ty)) then
58035815
let dim_exp = daeExp(dim, context, &preExp, &varDecls, &auxFunction)
58045816
let arrays_exp = (arrays |> array =>
5805-
daeExp(array, context, &preExp, &varDecls, &auxFunction) ;separator=", &")
5817+
daeExpAsLValue(array, context, &preExp, &varDecls, &auxFunction) ;separator=", &")
58065818
let ty_str = expTypeArray(ty)
58075819
let tvar = tempDecl(ty_str, &varDecls)
58085820
let &preExp += 'cat_alloc_<%ty_str%>(<%dim_exp%>, &<%tvar%>, <%listLength(arrays)%>, &<%arrays_exp%>);<%\n%>'
58095821
tvar
58105822
58115823
case CALL(path=IDENT(name="promote"), expLst={A, n}) then
5812-
let var1 = daeExp(A, context, &preExp, &varDecls, &auxFunction)
5824+
let var1 = daeExpAsLValue(A, context, &preExp, &varDecls, &auxFunction)
58135825
let var2 = daeExp(n, context, &preExp, &varDecls, &auxFunction)
58145826
let arr_tp_str = '<%expTypeFromExpArray(A)%>'
58155827
let tvar = tempDecl(arr_tp_str, &varDecls)
58165828
let &preExp += 'promote_alloc_<%arr_tp_str%>(&<%var1%>, <%var2%>, &<%tvar%>);<%\n%>'
58175829
tvar
58185830
58195831
case CALL(path=IDENT(name="transpose"), expLst={A}) then
5820-
let var1 = daeExp(A, context, &preExp, &varDecls, &auxFunction)
5832+
let var1 = daeExpAsLValue(A, context, &preExp, &varDecls, &auxFunction)
58215833
let arr_tp_str = '<%expTypeFromExpArray(A)%>'
58225834
let tvar = tempDecl(arr_tp_str, &varDecls)
58235835
let &preExp += 'transpose_alloc_<%arr_tp_str%>(&<%var1%>, &<%tvar%>);<%\n%>'
58245836
tvar
58255837
58265838
case CALL(path=IDENT(name="symmetric"), expLst={A}) then
5827-
let var1 = daeExp(A, context, &preExp, &varDecls, &auxFunction)
5839+
let var1 = daeExpAsLValue(A, context, &preExp, &varDecls, &auxFunction)
58285840
let arr_tp_str = '<%expTypeFromExpArray(A)%>'
58295841
let tvar = tempDecl(arr_tp_str, &varDecls)
58305842
let &preExp += 'symmetric_<%arr_tp_str%>(&<%var1%>, &<%tvar%>);<%\n%>'
58315843
tvar
58325844
58335845
case CALL(path=IDENT(name="skew"), expLst={A}) then
5834-
let var1 = daeExp(A, context, &preExp, &varDecls, &auxFunction)
5846+
let var1 = daeExpAsLValue(A, context, &preExp, &varDecls, &auxFunction)
58355847
let arr_tp_str = '<%expTypeFromExpArray(A)%>'
58365848
let tvar = tempDecl(arr_tp_str, &varDecls)
58375849
let &preExp += 'skew_<%arr_tp_str%>(&<%var1%>, &<%tvar%>);<%\n%>'
58385850
tvar
58395851
58405852
case CALL(path=IDENT(name="cross"), expLst={v1, v2}) then
5841-
let var1 = daeExp(v1, context, &preExp, &varDecls, &auxFunction)
5842-
let var2 = daeExp(v2, context, &preExp, &varDecls, &auxFunction)
5853+
let var1 = daeExpAsLValue(v1, context, &preExp, &varDecls, &auxFunction)
5854+
let var2 = daeExpAsLValue(v2, context, &preExp, &varDecls, &auxFunction)
58435855
let arr_tp_str = expTypeFromExpArray(v1)
58445856
let tvar = tempDecl(arr_tp_str, &varDecls)
58455857
let &preExp += 'cross_alloc_<%arr_tp_str%>(&<%var1%>, &<%var2%>, &<%tvar%>);<%\n%>'
58465858
tvar
58475859
58485860
case CALL(path=IDENT(name="identity"), expLst={A}) then
5849-
let var1 = daeExp(A, context, &preExp, &varDecls, &auxFunction)
5861+
let var1 = daeExpAsLValue(A, context, &preExp, &varDecls, &auxFunction)
58505862
let arr_tp_str = expTypeFromExpArray(A)
58515863
let tvar = tempDecl(arr_tp_str, &varDecls)
58525864
let &preExp += 'identity_alloc_<%arr_tp_str%>(<%var1%>, &<%tvar%>);<%\n%>'
@@ -5856,7 +5868,7 @@ simple_alloc_1d_base_array(&<%tvar%>, <%nElts%>, <%tvardata%>);
58565868
let arr_tp_str = expTypeFromExpArray(A)
58575869
let tvar = tempDecl(arr_tp_str, &varDecls)
58585870
let params = (A.array |> e =>
5859-
'<%daeExp(e, context, &preExp, &varDecls, &auxFunction)%>'
5871+
daeExp(e, context, &preExp, &varDecls, &auxFunction)
58605872
;separator=", ")
58615873
let &preExp += 'diagonal_alloc_<%arr_tp_str%>(&<%tvar%>, <%listLength(A.array)%>, <%params%>);<%\n%>'
58625874
tvar

Compiler/Util/Util.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1711,7 +1711,7 @@ public function isCIdentifier
17111711
protected
17121712
Integer i;
17131713
algorithm
1714-
(i,_) := System.regex(str, "^[][_A-Za-z0-9]*$", 0, true, false);
1714+
(i,_) := System.regex(str, "^[_A-Za-z][_A-Za-z0-9]*$", 0, true, false);
17151715
b := i == 1;
17161716
end isCIdentifier;
17171717

0 commit comments

Comments
 (0)