Skip to content

Commit

Permalink
Check for uninitialized outputs in functions (#9763)
Browse files Browse the repository at this point in the history
  • Loading branch information
perost committed Nov 26, 2022
1 parent d880fb8 commit d03a6d3
Show file tree
Hide file tree
Showing 12 changed files with 90 additions and 37 deletions.
7 changes: 7 additions & 0 deletions OMCompiler/Compiler/NFFrontEnd/NFFunction.mo
Expand Up @@ -2623,6 +2623,13 @@ protected
body := getBody(fn);
checkUseBeforeAssign2(unassigned, body);
for var in Vector.toList(unassigned) loop
if InstNode.isOutput(var) then
Error.addSourceMessage(Error.UNASSIGNED_FUNCTION_OUTPUT, {InstNode.name(var)}, InstNode.info(var));
fail();
end if;
end for;
end checkUseBeforeAssign;
function addUnassignedComponents
Expand Down
Expand Up @@ -7,12 +7,14 @@
function f
input Real x;
output Real y;
algorithm
y := x;
end f;

model A
replaceable function f2 = f(x = 0);

Real x = f2();
Real x = f2(time);
end A;

model ConstrainingClassFunc2
Expand All @@ -23,9 +25,11 @@ end ConstrainingClassFunc2;
// function ConstrainingClassFunc2.a.f2
// input Real x = 1.0;
// output Real y;
// algorithm
// y := x;
// end ConstrainingClassFunc2.a.f2;
//
// class ConstrainingClassFunc2
// Real a.x = ConstrainingClassFunc2.a.f2(1.0);
// Real a.x = ConstrainingClassFunc2.a.f2(time);
// end ConstrainingClassFunc2;
// endResult
Expand Up @@ -9,12 +9,16 @@ model FuncOverloadAmbiguousDefault
function F
input Integer f1;
output Integer f2;
algorithm
f2 := f1;
end F;

function G
input Integer g1;
input Integer g2 = 1;
output Integer g3;
algorithm
g3 := g1 + g2;
end G;

function OV = $overload(F,G);
Expand All @@ -24,7 +28,7 @@ end FuncOverloadAmbiguousDefault;

// Result:
// Error processing file: FuncOverloadAmbiguousDefault.mo
// [flattening/modelica/scodeinst/FuncOverloadAmbiguousDefault.mo:22:3-22:20:writable] Error: Ambiguous matching functions found for FuncOverloadAmbiguousDefault.OV(/*Integer*/ 1).
// [flattening/modelica/scodeinst/FuncOverloadAmbiguousDefault.mo:26:3-26:20:writable] Error: Ambiguous matching functions found for FuncOverloadAmbiguousDefault.OV(/*Integer*/ 1).
// Candidates are:
// FuncOverloadAmbiguousDefault.G(Integer g1, Integer g2 = 1) => Integer
// FuncOverloadAmbiguousDefault.F(Integer f1) => Integer
Expand Down
19 changes: 6 additions & 13 deletions testsuite/flattening/modelica/scodeinst/FuncOverloadExactPrefer.mo
Expand Up @@ -10,12 +10,16 @@ model FuncOverloadExactPrefer
function F
input Integer f1;
output Integer f2;
algorithm
f2 := f1;
end F;

function G
input Real g1;
input Integer g2 = 1;
output Integer g3;
algorithm
g3 := g2;
end G;

function OV = $overload(F,G);
Expand All @@ -25,19 +29,8 @@ model FuncOverloadExactPrefer
end FuncOverloadExactPrefer;

// Result:
// function FuncOverloadExactPrefer.F
// input Integer f1;
// output Integer f2;
// end FuncOverloadExactPrefer.F;
//
// function FuncOverloadExactPrefer.G
// input Real g1;
// input Integer g2 = 1;
// output Integer g3;
// end FuncOverloadExactPrefer.G;
//
// class FuncOverloadExactPrefer
// Integer x = FuncOverloadExactPrefer.F(1);
// Integer y = FuncOverloadExactPrefer.G(1.0, 1);
// Integer x = 1;
// Integer y = 1;
// end FuncOverloadExactPrefer;
// endResult
Expand Up @@ -9,11 +9,15 @@ model FuncOverloadNoMatch
function F
input Integer f1;
output Integer f2;
algorithm
f2 := f1;
end F;

function G
input Real g1;
output Integer g3;
algorithm
g3 := integer(g1);
end G;

function OV = $overload(F,G);
Expand All @@ -23,7 +27,7 @@ end FuncOverloadNoMatch;

// Result:
// Error processing file: FuncOverloadNoMatch.mo
// [flattening/modelica/scodeinst/FuncOverloadNoMatch.mo:21:3-21:23:writable] Error: No matching function found for FuncOverloadNoMatch.OV(/*Boolean*/ true).
// [flattening/modelica/scodeinst/FuncOverloadNoMatch.mo:25:3-25:23:writable] Error: No matching function found for FuncOverloadNoMatch.OV(/*Boolean*/ true).
// Candidates are:
// FuncOverloadNoMatch.F(Integer f1) => Integer
// FuncOverloadNoMatch.G(Real g1) => Integer
Expand Down
19 changes: 6 additions & 13 deletions testsuite/flattening/modelica/scodeinst/FuncOverloadSimple.mo
Expand Up @@ -9,12 +9,16 @@ model FuncOverloadSimple
function F
input Integer f1;
output Integer f2;
algorithm
f2 := f1;
end F;

function G
input Integer g1;
input Integer g2;
output Integer g3;
algorithm
g3 := g1 + g2;
end G;

function OV = $overload(F,G);
Expand All @@ -24,19 +28,8 @@ model FuncOverloadSimple
end FuncOverloadSimple;

// Result:
// function FuncOverloadSimple.F
// input Integer f1;
// output Integer f2;
// end FuncOverloadSimple.F;
//
// function FuncOverloadSimple.G
// input Integer g1;
// input Integer g2;
// output Integer g3;
// end FuncOverloadSimple.G;
//
// class FuncOverloadSimple
// Integer x = FuncOverloadSimple.F(1);
// Integer y = FuncOverloadSimple.G(1, 2);
// Integer x = 1;
// Integer y = 3;
// end FuncOverloadSimple;
// endResult
4 changes: 4 additions & 0 deletions testsuite/flattening/modelica/scodeinst/FuncVectorization2.mo
Expand Up @@ -13,6 +13,8 @@ model FuncVectorization2
input Integer a[4];
input Integer b;
output Integer o;
algorithm
o := b + sum(a);
end F;


Expand All @@ -28,6 +30,8 @@ end FuncVectorization2;
// input Integer[4] a;
// input Integer b;
// output Integer o;
// algorithm
// o := b + a[1] + a[2] + a[3] + a[4];
// end FuncVectorization2.F;
//
// class FuncVectorization2
Expand Down
25 changes: 25 additions & 0 deletions testsuite/flattening/modelica/scodeinst/FunctionUnitialized3.mo
@@ -0,0 +1,25 @@
// name: FunctionUnitialized3
// keywords:
// status: incorrect
// cflags: -d=newInst
//
//

model FunctionUnitialized3
Real y = f(time);

function f
input Real x;
output Real y;
end f;
end FunctionUnitialized3;

// Result:
// Error processing file: FunctionUnitialized3.mo
// [flattening/modelica/scodeinst/FunctionUnitialized3.mo:13:5-13:18:writable] Error: Output parameter y was not assigned a value
//
// # Error encountered! Exiting...
// # Please check the error message and the flags.
//
// Execution failed!
// endResult
1 change: 1 addition & 0 deletions testsuite/flattening/modelica/scodeinst/Makefile
Expand Up @@ -664,6 +664,7 @@ FunctionSections5.mo \
FunctionStreamPrefix.mo \
FunctionUnitialized1.mo \
FunctionUnitialized2.mo \
FunctionUnitialized3.mo \
IfConnect1.mo \
IfConnect2.mo \
IfConnect3.mo \
Expand Down
4 changes: 4 additions & 0 deletions testsuite/flattening/modelica/scodeinst/Prefix3.mo
Expand Up @@ -10,6 +10,8 @@ package P
function f
input Real x;
output Real y;
algorithm
y := x;
end f;

Real x = f(time);
Expand All @@ -21,6 +23,8 @@ end P;
// function P.P2.Prefix3.f
// input Real x;
// output Real y;
// algorithm
// y := x;
// end P.P2.Prefix3.f;
//
// class P.P2.Prefix3
Expand Down
10 changes: 7 additions & 3 deletions testsuite/simulation/modelica/unitcheck/UnitCheck1.mos
Expand Up @@ -13,6 +13,8 @@ package unitCheckTests
function f1
input Real V(unit = \"m/s\");
output Real O(unit = \"m\");
algorithm
O := V;
end f1;
Real S(unit = \"m\") = if time > 0.5 then V else X2;
Real V(unit = \"m/s\");
Expand Down Expand Up @@ -63,6 +65,8 @@ instantiateModel(unitCheckTests.UnitCheck1); getErrorString();
// "function unitCheckTests.UnitCheck1.f1
// input Real V(unit = \"m/s\");
// output Real O(unit = \"m\");
// algorithm
// O := V;
// end unitCheckTests.UnitCheck1.f1;
//
// class unitCheckTests.UnitCheck1
Expand All @@ -88,15 +92,15 @@ instantiateModel(unitCheckTests.UnitCheck1); getErrorString();
// der(V) = A;
// end unitCheckTests.UnitCheck1;
// "
// "[<interactive>:12:5-12:54:writable] Warning: The following equation is INCONSISTENT due to specified unit information: S = if time > 0.5 then V else X2
// "[<interactive>:14:5-14:54:writable] Warning: The following equation is INCONSISTENT due to specified unit information: S = if time > 0.5 then V else X2
// Warning: The units of following sub-expressions need to be equal:
// - sub-expression \"V\" has unit \"m/s\"
// - sub-expression \"X2\" has unit \"m\"
// [<interactive>:28:5-28:10:writable] Warning: The following equation is INCONSISTENT due to specified unit information: H = G
// [<interactive>:30:5-30:10:writable] Warning: The following equation is INCONSISTENT due to specified unit information: H = G
// Warning: The units of following sub-expressions need to be equal:
// - sub-expression \"G\" has unit \"m/s\"
// - sub-expression \"H\" has unit \"m\"
// [<interactive>:30:5-30:14:writable] Warning: The following equation is INCONSISTENT due to specified unit information: V = S + C
// [<interactive>:32:5-32:14:writable] Warning: The following equation is INCONSISTENT due to specified unit information: V = S + C
// Warning: The units of following sub-expressions need to be equal:
// - sub-expression \"S\" has unit \"m\"
// - sub-expression \"C\" has unit \"m/s\"
Expand Down
18 changes: 14 additions & 4 deletions testsuite/simulation/modelica/unitcheck/UnitCheck18.mos
Expand Up @@ -9,12 +9,17 @@ package unitCheckTests
function test2
input Real a(unit=\"s\");
output Real b(unit=\"m/s2\");
algorithm
b := a;
end test2;
function test
input Real x(unit=\"m\");
input Real y(unit=\"m\");
output Real z(unit=\"m\") ;
output Real r(unit=\"m/s\");
algorithm
z := x;
r := y;
end test;
Real y1(unit=\"m/s\");
Real y2(unit=\"J\");
Expand Down Expand Up @@ -47,11 +52,16 @@ instantiateModel(unitCheckTests.UnitCheck18); getErrorString();
// input Real y(unit = \"m\");
// output Real z(unit = \"m\");
// output Real r(unit = \"m/s\");
// algorithm
// z := x;
// r := y;
// end unitCheckTests.UnitCheck18.test;
//
// function unitCheckTests.UnitCheck18.test2
// input Real a(unit = \"s\");
// output Real b(unit = \"m/s2\");
// algorithm
// b := a;
// end unitCheckTests.UnitCheck18.test2;
//
// class unitCheckTests.UnitCheck18
Expand All @@ -65,19 +75,19 @@ instantiateModel(unitCheckTests.UnitCheck18); getErrorString();
// b = unitCheckTests.UnitCheck18.test2(t2);
// end unitCheckTests.UnitCheck18;
// "
// "[<interactive>:20:5-20:26:writable] Warning: The following equation is INCONSISTENT due to specified unit information: (y1, y2) = unitCheckTests.UnitCheck18.test(t1, t2)
// "[<interactive>:25:5-25:26:writable] Warning: The following equation is INCONSISTENT due to specified unit information: (y1, y2) = unitCheckTests.UnitCheck18.test(t1, t2)
// Warning: The units of following sub-expressions need to be equal:
// - sub-expression \"y1\" has unit \"m/s\"
// - sub-expression \"unitCheckTests.UnitCheck18.test().z\" has unit \"m\"
// [<interactive>:20:5-20:26:writable] Warning: The following equation is INCONSISTENT due to specified unit information: (y1, y2) = unitCheckTests.UnitCheck18.test(t1, t2)
// [<interactive>:25:5-25:26:writable] Warning: The following equation is INCONSISTENT due to specified unit information: (y1, y2) = unitCheckTests.UnitCheck18.test(t1, t2)
// Warning: The units of following sub-expressions need to be equal:
// - sub-expression \"y2\" has unit \"J\"
// - sub-expression \"unitCheckTests.UnitCheck18.test().r\" has unit \"m/s\"
// [<interactive>:20:5-20:26:writable] Warning: The following equation is INCONSISTENT due to specified unit information: (y1, y2) = unitCheckTests.UnitCheck18.test(t1, t2)
// [<interactive>:25:5-25:26:writable] Warning: The following equation is INCONSISTENT due to specified unit information: (y1, y2) = unitCheckTests.UnitCheck18.test(t1, t2)
// Warning: The units of following sub-expressions need to be equal:
// - sub-expression \"t2\" has unit \"m/s\"
// - sub-expression \"unitCheckTests.UnitCheck18.test().y\" has unit \"m\"
// [<interactive>:21:5-21:18:writable] Warning: The following equation is INCONSISTENT due to specified unit information: b = unitCheckTests.UnitCheck18.test2(t2)
// [<interactive>:26:5-26:18:writable] Warning: The following equation is INCONSISTENT due to specified unit information: b = unitCheckTests.UnitCheck18.test2(t2)
// Warning: The units of following sub-expressions need to be equal:
// - sub-expression \"t2\" has unit \"m/s\"
// - sub-expression \"unitCheckTests.UnitCheck18.test2().a\" has unit \"s\"
Expand Down

0 comments on commit d03a6d3

Please sign in to comment.