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

Commit 1f8adde

Browse files
perostOpenModelica-Hudson
authored andcommitted
Error message improvements.
- Add division by zero error message in NFCeval.evalBinaryDiv. - Improve the error message for using == and <> on Reals. Belonging to [master]: - #2878 - OpenModelica/OpenModelica-testsuite#1105
1 parent 1f99d4a commit 1f8adde

5 files changed

Lines changed: 51 additions & 22 deletions

File tree

Compiler/FrontEnd/OperatorOverloading.mo

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2057,8 +2057,7 @@ algorithm
20572057
verifyOp(op);
20582058
opString = ExpressionDump.relopSymbol(op);
20592059
stmtString = ExpressionDump.printExpStr(e1) + opString + ExpressionDump.printExpStr(e2);
2060-
pre_str = PrefixUtil.printPrefixStr3(pre);
2061-
Error.addSourceMessage(Error.WARNING_RELATION_ON_REAL, {pre_str,stmtString,opString}, inInfo);
2060+
Error.addSourceMessage(Error.WARNING_RELATION_ON_REAL, {stmtString,opString}, inInfo);
20622061
then
20632062
();
20642063
else ();

Compiler/NFFrontEnd/NFCeval.mo

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ import NFClassTree.ClassTree;
5050
import ComplexType = NFComplexType;
5151
import Subscript = NFSubscript;
5252
import NFTyping.TypingError;
53+
import DAE;
5354

5455
protected
5556
import NFFunction.Function;
@@ -61,6 +62,7 @@ import MetaModelica.Dangerous.*;
6162
import NFClass.Class;
6263
import TypeCheck = NFTypeCheck;
6364
import ExpandExp = NFExpandExp;
65+
import ElementSource;
6466

6567
public
6668
uniontype EvalTarget
@@ -87,6 +89,10 @@ uniontype EvalTarget
8789
SourceInfo info;
8890
end GENERIC;
8991

92+
record STATEMENT
93+
DAE.ElementSource source;
94+
end STATEMENT;
95+
9096
record IGNORE_ERRORS end IGNORE_ERRORS;
9197

9298
function isRange
@@ -109,6 +115,7 @@ uniontype EvalTarget
109115
case RANGE() then true;
110116
case CONDITION() then true;
111117
case GENERIC() then true;
118+
case STATEMENT() then true;
112119
else false;
113120
end match;
114121
end hasInfo;
@@ -123,6 +130,7 @@ uniontype EvalTarget
123130
case RANGE() then target.info;
124131
case CONDITION() then target.info;
125132
case GENERIC() then target.info;
133+
case STATEMENT() then ElementSource.getInfo(target.source);
126134
else Absyn.dummyInfo;
127135
end match;
128136
end getInfo;
@@ -196,7 +204,7 @@ algorithm
196204
exp1 := evalExp(exp.exp1, target);
197205
exp2 := evalExp(exp.exp2, target);
198206
then
199-
evalBinaryOp(exp1, exp.operator, exp2);
207+
evalBinaryOp(exp1, exp.operator, exp2, target);
200208

201209
case Expression.UNARY()
202210
algorithm
@@ -738,13 +746,14 @@ function evalBinaryOp
738746
input Expression exp1;
739747
input Operator op;
740748
input Expression exp2;
749+
input EvalTarget target = EvalTarget.IGNORE_ERRORS();
741750
output Expression exp;
742751
algorithm
743752
exp := match op.op
744753
case Op.ADD then evalBinaryAdd(exp1, exp2);
745754
case Op.SUB then evalBinarySub(exp1, exp2);
746755
case Op.MUL then evalBinaryMul(exp1, exp2);
747-
case Op.DIV then evalBinaryDiv(exp1, exp2);
756+
case Op.DIV then evalBinaryDiv(exp1, exp2, target);
748757
case Op.POW then evalBinaryPow(exp1, exp2);
749758
case Op.ADD_SCALAR_ARRAY then evalBinaryScalarArray(exp1, exp2, evalBinaryAdd);
750759
case Op.ADD_ARRAY_SCALAR then evalBinaryArrayScalar(exp1, exp2, evalBinaryAdd);
@@ -756,8 +765,10 @@ algorithm
756765
case Op.MUL_MATRIX_VECTOR then evalBinaryMulMatrixVector(exp1, exp2);
757766
case Op.SCALAR_PRODUCT then evalBinaryScalarProduct(exp1, exp2);
758767
case Op.MATRIX_PRODUCT then evalBinaryMatrixProduct(exp1, exp2);
759-
case Op.DIV_SCALAR_ARRAY then evalBinaryScalarArray(exp1, exp2, evalBinaryDiv);
760-
case Op.DIV_ARRAY_SCALAR then evalBinaryArrayScalar(exp1, exp2, evalBinaryDiv);
768+
case Op.DIV_SCALAR_ARRAY
769+
then evalBinaryScalarArray(exp1, exp2, function evalBinaryDiv(target = target));
770+
case Op.DIV_ARRAY_SCALAR
771+
then evalBinaryArrayScalar(exp1, exp2, function evalBinaryDiv(target = target));
761772
case Op.POW_SCALAR_ARRAY then evalBinaryScalarArray(exp1, exp2, evalBinaryPow);
762773
case Op.POW_ARRAY_SCALAR then evalBinaryArrayScalar(exp1, exp2, evalBinaryPow);
763774
case Op.POW_MATRIX then evalBinaryPowMatrix(exp1, exp2);
@@ -857,16 +868,29 @@ end evalBinaryMul;
857868
function evalBinaryDiv
858869
input Expression exp1;
859870
input Expression exp2;
871+
input EvalTarget target;
860872
output Expression exp;
861873
algorithm
862874
exp := match (exp1, exp2)
875+
case (_, Expression.REAL(0.0))
876+
algorithm
877+
if EvalTarget.hasInfo(target) then
878+
Error.addSourceMessage(Error.DIVISION_BY_ZERO,
879+
{Expression.toString(exp1), Expression.toString(exp2)}, EvalTarget.getInfo(target));
880+
fail();
881+
else
882+
exp := Expression.BINARY(exp1, Operator.makeDiv(Type.REAL()), exp2);
883+
end if;
884+
then
885+
exp;
886+
863887
case (Expression.REAL(), Expression.REAL())
864888
then Expression.REAL(exp1.value / exp2.value);
865889

866890
case (Expression.ARRAY(), Expression.ARRAY())
867891
guard listLength(exp1.elements) == listLength(exp2.elements)
868892
then Expression.makeArray(exp1.ty,
869-
list(evalBinaryDiv(e1, e2) threaded for e1 in exp1.elements, e2 in exp2.elements),
893+
list(evalBinaryDiv(e1, e2, target) threaded for e1 in exp1.elements, e2 in exp2.elements),
870894
literal = true);
871895

872896
else

Compiler/NFFrontEnd/NFEvalFunction.mo

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import NFTyping.ExpOrigin;
5656
import SCode;
5757
import NFPrefixes.Variability;
5858
import EvalFunctionExt = NFEvalFunctionExt;
59+
import NFCeval.EvalTarget;
5960

6061
encapsulated package ReplTree
6162
import BaseAvlTree;
@@ -163,7 +164,7 @@ algorithm
163164

164165
if lang == "builtin" then
165166
// Functions defined as 'external "builtin"', delegate to Ceval.
166-
result := Ceval.evalBuiltinCall(fn, args, NFCeval.EvalTarget.IGNORE_ERRORS());
167+
result := Ceval.evalBuiltinCall(fn, args, EvalTarget.IGNORE_ERRORS());
167168
elseif isKnownExternalFunc(name, ann) then
168169
// External functions that we know how to evaluate without generating code.
169170
// TODO: Move this to EvalFunctionExt and unify evaluateKnownExternal and
@@ -491,11 +492,11 @@ algorithm
491492
// adrpo: we really need some error handling here to detect which statement cannot be evaluated
492493
// try
493494
ctrl := match stmt
494-
case Statement.ASSIGNMENT() then evaluateAssignment(stmt.lhs, stmt.rhs);
495+
case Statement.ASSIGNMENT() then evaluateAssignment(stmt.lhs, stmt.rhs, stmt.source);
495496
case Statement.FOR() then evaluateFor(stmt.iterator, stmt.range, stmt.body, stmt.source);
496-
case Statement.IF() then evaluateIf(stmt.branches);
497+
case Statement.IF() then evaluateIf(stmt.branches, stmt.source);
497498
case Statement.ASSERT() then evaluateAssert(stmt.condition, stmt);
498-
case Statement.NORETCALL() then evaluateNoRetCall(stmt.exp);
499+
case Statement.NORETCALL() then evaluateNoRetCall(stmt.exp, stmt.source);
499500
case Statement.WHILE() then evaluateWhile(stmt.condition, stmt.body, stmt.source);
500501
case Statement.RETURN() then FlowControl.RETURN;
501502
case Statement.BREAK() then FlowControl.BREAK;
@@ -515,9 +516,10 @@ end evaluateStatement;
515516
function evaluateAssignment
516517
input Expression lhsExp;
517518
input Expression rhsExp;
519+
input DAE.ElementSource source;
518520
output FlowControl ctrl = FlowControl.NEXT;
519521
algorithm
520-
assignVariable(lhsExp, Ceval.evalExp(rhsExp));
522+
assignVariable(lhsExp, Ceval.evalExp(rhsExp, EvalTarget.STATEMENT(source)));
521523
end evaluateAssignment;
522524

523525
public
@@ -715,7 +717,7 @@ protected
715717
list<Statement> body = forBody;
716718
Integer i = 0, limit = Flags.getConfigInt(Flags.EVAL_LOOP_LIMIT);
717719
algorithm
718-
range_exp := Ceval.evalExp(Util.getOption(range));
720+
range_exp := Ceval.evalExp(Util.getOption(range), EvalTarget.STATEMENT(source));
719721
range_iter := RangeIterator.fromExp(range_exp);
720722

721723
if RangeIterator.hasNext(range_iter) then
@@ -748,6 +750,7 @@ end evaluateFor;
748750

749751
function evaluateIf
750752
input list<tuple<Expression, list<Statement>>> branches;
753+
input DAE.ElementSource source;
751754
output FlowControl ctrl;
752755
protected
753756
Expression cond;
@@ -756,7 +759,7 @@ algorithm
756759
for branch in branches loop
757760
(cond, body) := branch;
758761

759-
if Expression.isTrue(Ceval.evalExp(cond)) then
762+
if Expression.isTrue(Ceval.evalExp(cond, EvalTarget.STATEMENT(source))) then
760763
ctrl := evaluateStatements(body);
761764
return;
762765
end if;
@@ -770,13 +773,14 @@ function evaluateAssert
770773
input Statement assertStmt;
771774
output FlowControl ctrl = FlowControl.NEXT;
772775
protected
773-
Expression msg, lvl;
776+
Expression cond, msg, lvl;
774777
DAE.ElementSource source;
778+
EvalTarget target = EvalTarget.STATEMENT(Statement.source(assertStmt));
775779
algorithm
776-
if Expression.isFalse(Ceval.evalExp(condition)) then
780+
if Expression.isFalse(Ceval.evalExp(condition, target)) then
777781
Statement.ASSERT(message = msg, level = lvl, source = source) := assertStmt;
778-
msg := Ceval.evalExp(msg);
779-
lvl := Ceval.evalExp(lvl);
782+
msg := Ceval.evalExp(msg, target);
783+
lvl := Ceval.evalExp(lvl, target);
780784

781785
() := match (msg, lvl)
782786
case (Expression.STRING(), Expression.ENUM_LITERAL(name = "warning"))
@@ -804,9 +808,10 @@ end evaluateAssert;
804808

805809
function evaluateNoRetCall
806810
input Expression callExp;
811+
input DAE.ElementSource source;
807812
output FlowControl ctrl = FlowControl.NEXT;
808813
algorithm
809-
Ceval.evalExp(callExp);
814+
Ceval.evalExp(callExp, EvalTarget.STATEMENT(source));
810815
end evaluateNoRetCall;
811816

812817
function evaluateWhile
@@ -816,8 +821,9 @@ function evaluateWhile
816821
output FlowControl ctrl = FlowControl.NEXT;
817822
protected
818823
Integer i = 0, limit = Flags.getConfigInt(Flags.EVAL_LOOP_LIMIT);
824+
EvalTarget target = EvalTarget.STATEMENT(source);
819825
algorithm
820-
while Expression.isTrue(Ceval.evalExp(condition)) loop
826+
while Expression.isTrue(Ceval.evalExp(condition, target)) loop
821827
ctrl := evaluateStatements(body);
822828

823829
if ctrl <> FlowControl.NEXT then

Compiler/NFFrontEnd/NFTypeCheck.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ algorithm
13181318
o := operator.op;
13191319
if ExpOrigin.flagNotSet(origin, ExpOrigin.FUNCTION) and (o == Op.EQUAL or o == Op.NEQUAL) then
13201320
Error.addSourceMessage(Error.WARNING_RELATION_ON_REAL,
1321-
{"<NO COMPONENT>", Expression.toString(outExp), Operator.symbol(operator)}, info);
1321+
{Expression.toString(outExp), Operator.symbol(operator, "")}, info);
13221322
end if;
13231323
then
13241324
valid;

Compiler/Util/Error.mo

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ public constant Message SETTING_FIXED_ATTRIBUTE = MESSAGE(503, TRANSLATION(), WA
831831
public constant Message FAILED_TO_EVALUATE_FUNCTION = MESSAGE(506, TRANSLATION(), ERROR(),
832832
Util.gettext("Failed to evaluate function: %s."));
833833
public constant Message WARNING_RELATION_ON_REAL = MESSAGE(509, TRANSLATION(), WARNING(),
834-
Util.gettext("In component %s, in relation %s, %s on Real numbers is only allowed inside functions."));
834+
Util.gettext("In relation %s, %s on Real numbers is only allowed inside functions."));
835835
public constant Message OUTER_MODIFICATION = MESSAGE(512, TRANSLATION(), WARNING(),
836836
Util.gettext("Ignoring the modification on outer element: %s."));
837837
public constant Message DERIVATIVE_NON_REAL = MESSAGE(514, TRANSLATION(), ERROR(),

0 commit comments

Comments
 (0)