Commit f22c2af3 authored by BenceJanosSzabo's avatar BenceJanosSzabo
Browse files

allowed -infinity, infinity in arithmetic expressions (artf725754)



Change-Id: I6810565b4661d1cc35a739b5fae4df71c3cbc679
Signed-off-by: default avatarBenceJanosSzabo <bence.janos.szabo@ericsson.com>
parent 11342b3c
...@@ -32,6 +32,11 @@ namespace Common { ...@@ -32,6 +32,11 @@ namespace Common {
{ {
return ((r!=r) || (r==REAL_INFINITY) || (r==-REAL_INFINITY)); return ((r!=r) || (r==REAL_INFINITY) || (r==-REAL_INFINITY));
} }
bool isNaN(const Real& r)
{
return r!=r;
}
string Real2string(const Real& r) string Real2string(const Real& r)
{ {
......
...@@ -55,6 +55,7 @@ namespace Common { ...@@ -55,6 +55,7 @@ namespace Common {
/** +/- infinity and not_a_number are non-numeric float values in ttcn-3, /** +/- infinity and not_a_number are non-numeric float values in ttcn-3,
these special values cannot be used in some places */ these special values cannot be used in some places */
bool isSpecialFloatValue(const Real& r); bool isSpecialFloatValue(const Real& r);
bool isNaN(const Real& r);
/** /**
* Converts the Common::Real value to string. * Converts the Common::Real value to string.
......
...@@ -6396,6 +6396,47 @@ error: ...@@ -6396,6 +6396,47 @@ error:
set_valuetype(V_ERROR); set_valuetype(V_ERROR);
} }
} }
void Value::chk_expr_operand_valid_float(Value* v1, Value* v2, const char *opnum1, const char *opnum2, const char *opname)
{
ttcn3float r1, r2;
boolean r1_is_set = FALSE, r2_is_set = FALSE;
if(valuetype!=V_ERROR) {
if(u.expr.state!=EXPR_CHECKING_ERR) {
if(!v1->is_unfoldable()) {
if(v1->get_expr_returntype()==Type::T_REAL) {
r1 = v1->get_val_Real();
r1_is_set = TRUE;
}
}
if(!v2->is_unfoldable()) {
if(v2->get_expr_returntype()==Type::T_REAL) {
r2 = v2->get_val_Real();
r2_is_set = TRUE;
}
}
if (r1_is_set && r2_is_set) {
if ((isSpecialFloatValue(r1) && isSpecialFloatValue(r2)) || isNaN(r1) || isNaN(r2)) {
error("Invalid operands of float %s: %s operand is %s, %s operand is %s",
opname, opnum1, Real2string(r1).c_str(), opnum2, Real2string(r2).c_str());
set_valuetype(V_ERROR);
}
} else if (r1_is_set) {
if (isNaN(r1)) {
v1->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
opnum1, opname, Real2string(r1).c_str());
set_valuetype(V_ERROR);
}
} else if (r2_is_set) {
if (isNaN(r2)) {
v2->error("%s operand of operation `%s' cannot be %s, it must be a numeric value",
opnum2, opname, Real2string(r2).c_str());
set_valuetype(V_ERROR);
}
}
}
}
}
void Value::chk_expr_operands(ReferenceChain *refch, void Value::chk_expr_operands(ReferenceChain *refch,
Type::expected_value_t exp_val) Type::expected_value_t exp_val)
...@@ -6890,29 +6931,23 @@ error: ...@@ -6890,29 +6931,23 @@ error:
case OPTYPE_ADD: // v1 v2 case OPTYPE_ADD: // v1 v2
case OPTYPE_SUBTRACT: case OPTYPE_SUBTRACT:
case OPTYPE_MULTIPLY: case OPTYPE_MULTIPLY:
case OPTYPE_DIVIDE: case OPTYPE_DIVIDE: {
v1=u.expr.v1; v1=u.expr.v1;
{
Error_Context cntxt(this, "In the first operand of operation `%s'", opname);
v1->set_lowerid_to_ref();
tt1=v1->get_expr_returntype(exp_val);
chk_expr_operandtype_int_float(tt1, first, opname, v1);
chk_expr_eval_value(v1, t_chk, refch, exp_val);
chk_expr_operand_valid_float(v1, first, opname);
}
v2=u.expr.v2; v2=u.expr.v2;
{ Error_Context cntxt(this, "In the operands of operation `%s'", opname);
Error_Context cntxt(this, "In the second operand of operation `%s'", opname); v1->set_lowerid_to_ref();
v2->set_lowerid_to_ref(); v2->set_lowerid_to_ref();
tt2=v2->get_expr_returntype(exp_val); tt1=v1->get_expr_returntype(exp_val);
chk_expr_operandtype_int_float(tt2, second, opname, v2); tt2=v2->get_expr_returntype(exp_val);
chk_expr_eval_value(v2, t_chk, refch, exp_val); chk_expr_operandtype_int_float(tt1, first, opname, v1);
chk_expr_operand_valid_float(v2, second, opname); chk_expr_operandtype_int_float(tt2, second, opname, v2);
if(u.expr.v_optype==OPTYPE_DIVIDE) chk_expr_eval_value(v1, t_chk, refch, exp_val);
chk_expr_val_int_float_not0(v2, second, opname); chk_expr_eval_value(v2, t_chk, refch, exp_val);
} chk_expr_operand_valid_float(v1, v2, first, second, opname);
if(u.expr.v_optype==OPTYPE_DIVIDE)
chk_expr_val_int_float_not0(v2, second, opname);
chk_expr_operandtypes_same(tt1, tt2, opname); chk_expr_operandtypes_same(tt1, tt2, opname);
break; break; }
case OPTYPE_MOD: case OPTYPE_MOD:
case OPTYPE_REM: case OPTYPE_REM:
v1=u.expr.v1; v1=u.expr.v1;
......
...@@ -668,6 +668,7 @@ namespace Common { ...@@ -668,6 +668,7 @@ namespace Common {
void chk_expr_operands(ReferenceChain *refch, void chk_expr_operands(ReferenceChain *refch,
Type::expected_value_t exp_val); Type::expected_value_t exp_val);
void chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname); void chk_expr_operand_valid_float(Value* v, const char *opnum, const char *opname);
void chk_expr_operand_valid_float(Value* v1, Value* v2, const char *opnum1, const char *opnum2, const char *opname);
/** Evaluate... /** Evaluate...
* Called by Value::get_value_refd_last() for V_EXPR */ * Called by Value::get_value_refd_last() for V_EXPR */
void evaluate_value(ReferenceChain *refch, Type::expected_value_t exp_val); void evaluate_value(ReferenceChain *refch, Type::expected_value_t exp_val);
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
* Raduly, Csaba * Raduly, Csaba
* Szabados, Kristof * Szabados, Kristof
* Szabo, Janos Zoltan – initial implementation * Szabo, Janos Zoltan – initial implementation
* Szabo, Bence Janos
* Zalanyi, Balazs Andor * Zalanyi, Balazs Andor
* Pandi, Krisztian * Pandi, Krisztian
* *
......
...@@ -130,6 +130,11 @@ boolean FLOAT::is_special(double flt_val) ...@@ -130,6 +130,11 @@ boolean FLOAT::is_special(double flt_val)
return ( (flt_val!=flt_val) || (flt_val==INFINITY) || (flt_val==-INFINITY) ); return ( (flt_val!=flt_val) || (flt_val==INFINITY) || (flt_val==-INFINITY) );
} }
boolean FLOAT::is_nan(double flt_val)
{
return flt_val!=flt_val;
}
void FLOAT::check_numeric(double flt_val, const char *err_msg_begin) void FLOAT::check_numeric(double flt_val, const char *err_msg_begin)
{ {
if (is_special(flt_val)) { if (is_special(flt_val)) {
...@@ -141,8 +146,10 @@ void FLOAT::check_numeric(double flt_val, const char *err_msg_begin) ...@@ -141,8 +146,10 @@ void FLOAT::check_numeric(double flt_val, const char *err_msg_begin)
double FLOAT::operator+(double other_value) const double FLOAT::operator+(double other_value) const
{ {
must_bound("Unbound left operand of float addition."); must_bound("Unbound left operand of float addition.");
check_numeric(float_value, "Left operand of float addition"); // Both of them are +-infinity or one of them is nan
check_numeric(other_value, "Right operand of float addition"); if ((is_special(float_value) && is_special(other_value)) || is_nan(float_value) || is_nan(other_value)) {
TTCN_error("Invalid operands of float addition: Left operand is %g, right operand is %g", (double)float_value, other_value);
}
return float_value + other_value; return float_value + other_value;
} }
...@@ -150,16 +157,20 @@ double FLOAT::operator+(const FLOAT& other_value) const ...@@ -150,16 +157,20 @@ double FLOAT::operator+(const FLOAT& other_value) const
{ {
must_bound("Unbound left operand of float addition."); must_bound("Unbound left operand of float addition.");
other_value.must_bound("Unbound right operand of float addition."); other_value.must_bound("Unbound right operand of float addition.");
check_numeric(float_value, "Left operand of float addition"); // Both of them are +-infinity or one of them is nan
check_numeric(other_value.float_value, "Right operand of float addition"); if ((is_special(float_value) && is_special(other_value.float_value)) || is_nan(float_value) || is_nan(other_value.float_value)) {
TTCN_error("Invalid operands of float addition: Left operand is %g, right operand is %g", (double)float_value, (double)other_value.float_value);
}
return float_value + other_value.float_value; return float_value + other_value.float_value;
} }
double FLOAT::operator-(double other_value) const double FLOAT::operator-(double other_value) const
{ {
must_bound("Unbound left operand of float subtraction."); must_bound("Unbound left operand of float subtraction.");
check_numeric(float_value, "Left operand of float subtraction"); // Both of them are +-infinity or one of them is nan
check_numeric(other_value, "Right operand of float subtraction"); if ((is_special(float_value) && is_special(other_value)) || is_nan(float_value) || is_nan(other_value)) {
TTCN_error("Invalid operands of float subtraction: Left operand is %g, right operand is %g", (double)float_value, other_value);
}
return float_value - other_value; return float_value - other_value;
} }
...@@ -167,16 +178,20 @@ double FLOAT::operator-(const FLOAT& other_value) const ...@@ -167,16 +178,20 @@ double FLOAT::operator-(const FLOAT& other_value) const
{ {
must_bound("Unbound left operand of float subtraction."); must_bound("Unbound left operand of float subtraction.");
other_value.must_bound("Unbound right operand of float subtraction."); other_value.must_bound("Unbound right operand of float subtraction.");
check_numeric(float_value, "Left operand of float subtraction"); // Both of them are +-infinity or one of them is nan
check_numeric(other_value.float_value, "Right operand of float subtraction"); if ((is_special(float_value) && is_special(other_value.float_value)) || is_nan(float_value) || is_nan(other_value.float_value)) {
TTCN_error("Invalid operands of float subtraction: Left operand is %g, right operand is %g", (double)float_value, (double)other_value.float_value);
}
return float_value - other_value.float_value; return float_value - other_value.float_value;
} }
double FLOAT::operator*(double other_value) const double FLOAT::operator*(double other_value) const
{ {
must_bound("Unbound left operand of float multiplication."); must_bound("Unbound left operand of float multiplication.");
check_numeric(float_value, "Left operand of float multiplication"); // Both of them are +-infinity or one of them is nan
check_numeric(other_value, "Right operand of float multiplication"); if ((is_special(float_value) && is_special(other_value)) || is_nan(float_value) || is_nan(other_value)) {
TTCN_error("Invalid operands of float multiplication: Left operand is %g, right operand is %g", (double)float_value, other_value);
}
return float_value * other_value; return float_value * other_value;
} }
...@@ -184,16 +199,20 @@ double FLOAT::operator*(const FLOAT& other_value) const ...@@ -184,16 +199,20 @@ double FLOAT::operator*(const FLOAT& other_value) const
{ {
must_bound("Unbound left operand of float multiplication."); must_bound("Unbound left operand of float multiplication.");
other_value.must_bound("Unbound right operand of float multiplication."); other_value.must_bound("Unbound right operand of float multiplication.");
check_numeric(float_value, "Left operand of float multiplication"); // Both of them are +-infinity or one of them is nan
check_numeric(other_value.float_value, "Right operand of float multiplication"); if ((is_special(float_value) && is_special(other_value.float_value)) || is_nan(float_value) || is_nan(other_value.float_value)) {
TTCN_error("Invalid operands of float multiplication: Left operand is %g, right operand is %g", (double)float_value, (double)other_value.float_value);
}
return float_value * other_value.float_value; return float_value * other_value.float_value;
} }
double FLOAT::operator/(double other_value) const double FLOAT::operator/(double other_value) const
{ {
must_bound("Unbound left operand of float division."); must_bound("Unbound left operand of float division.");
check_numeric(float_value, "Left operand of float division"); // Both of them are +-infinity or one of them is nan
check_numeric(other_value, "Right operand of float division"); if ((is_special(float_value) && is_special(other_value)) || is_nan(float_value) || is_nan(other_value)) {
TTCN_error("Invalid operands of float division: Left operand is %g, right operand is %g", (double)float_value, other_value);
}
if (other_value == 0.0) TTCN_error("Float division by zero."); if (other_value == 0.0) TTCN_error("Float division by zero.");
return float_value / other_value; return float_value / other_value;
} }
...@@ -202,8 +221,10 @@ double FLOAT::operator/(const FLOAT& other_value) const ...@@ -202,8 +221,10 @@ double FLOAT::operator/(const FLOAT& other_value) const
{ {
must_bound("Unbound left operand of float division."); must_bound("Unbound left operand of float division.");
other_value.must_bound("Unbound right operand of float division."); other_value.must_bound("Unbound right operand of float division.");
check_numeric(float_value, "Left operand of float division"); // Both of them are +-infinity or one of them is nan
check_numeric(other_value.float_value, "Right operand of float division"); if ((is_special(float_value) && is_special(other_value.float_value)) || is_nan(float_value) || is_nan(other_value.float_value)) {
TTCN_error("Invalid operands of float division: Left operand is %g, right operand is %g", (double)float_value, (double)other_value.float_value);
}
if (other_value.float_value == 0.0) TTCN_error("Float division by zero."); if (other_value.float_value == 0.0) TTCN_error("Float division by zero.");
return float_value / other_value.float_value; return float_value / other_value.float_value;
} }
...@@ -1174,32 +1195,40 @@ int FLOAT::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok, ...@@ -1174,32 +1195,40 @@ int FLOAT::JSON_decode(const TTCN_Typedescriptor_t& p_td, JSON_Tokenizer& p_tok,
double operator+(double double_value, const FLOAT& other_value) double operator+(double double_value, const FLOAT& other_value)
{ {
other_value.must_bound("Unbound right operand of float addition."); other_value.must_bound("Unbound right operand of float addition.");
FLOAT::check_numeric(double_value, "Left operand of float addition"); // Both of them are +-infinity or one of them is nan
FLOAT::check_numeric(other_value.float_value, "Right operand of float addition"); if ((FLOAT::is_special(double_value) && FLOAT::is_special(other_value.float_value)) || FLOAT::is_nan(double_value) || FLOAT::is_nan(other_value.float_value)) {
TTCN_error("Invalid operands of float addition: Left operand is %g, right operand is %g", double_value, (double)other_value.float_value);
}
return double_value + other_value.float_value; return double_value + other_value.float_value;
} }
double operator-(double double_value, const FLOAT& other_value) double operator-(double double_value, const FLOAT& other_value)
{ {
other_value.must_bound("Unbound right operand of float subtraction."); other_value.must_bound("Unbound right operand of float subtraction.");
FLOAT::check_numeric(double_value, "Left operand of float subtraction"); // Both of them are +-infinity or one of them is nan
FLOAT::check_numeric(other_value.float_value, "Right operand of float subtraction"); if ((FLOAT::is_special(double_value) && FLOAT::is_special(other_value.float_value)) || FLOAT::is_nan(double_value) || FLOAT::is_nan(other_value.float_value)) {
TTCN_error("Invalid operands of float subtraction: Left operand is %g, right operand is %g", double_value, (double)other_value.float_value);
}
return double_value - other_value.float_value; return double_value - other_value.float_value;
} }
double operator*(double double_value, const FLOAT& other_value) double operator*(double double_value, const FLOAT& other_value)
{ {
other_value.must_bound("Unbound right operand of float multiplication."); other_value.must_bound("Unbound right operand of float multiplication.");
FLOAT::check_numeric(double_value, "Left operand of float multiplication"); // Both of them are +-infinity or one of them is nan
FLOAT::check_numeric(other_value.float_value, "Right operand of float multiplication"); if ((FLOAT::is_special(double_value) && FLOAT::is_special(other_value.float_value)) || FLOAT::is_nan(double_value) || FLOAT::is_nan(other_value.float_value)) {
TTCN_error("Invalid operands of float multiplication: Left operand is %g, right operand is %g", double_value, (double)other_value.float_value);
}
return double_value * other_value.float_value; return double_value * other_value.float_value;
} }
double operator/(double double_value, const FLOAT& other_value) double operator/(double double_value, const FLOAT& other_value)
{ {
other_value.must_bound("Unbound right operand of float division."); other_value.must_bound("Unbound right operand of float division.");
FLOAT::check_numeric(double_value, "Left operand of float division"); // Both of them are +-infinity or one of them is nan
FLOAT::check_numeric(other_value.float_value, "Right operand of float division"); if ((FLOAT::is_special(double_value) && FLOAT::is_special(other_value.float_value)) || FLOAT::is_nan(double_value) || FLOAT::is_nan(other_value.float_value)) {
TTCN_error("Invalid operands of float division: Left operand is %g, right operand is %g", double_value, (double)other_value.float_value);
}
if (other_value.float_value == 0.0) TTCN_error("Float division by zero."); if (other_value.float_value == 0.0) TTCN_error("Float division by zero.");
return double_value / other_value.float_value; return double_value / other_value.float_value;
} }
......
...@@ -106,6 +106,7 @@ public: ...@@ -106,6 +106,7 @@ public:
/** special TTCN-3 float values are not_a_number and +/- infinity */ /** special TTCN-3 float values are not_a_number and +/- infinity */
static boolean is_special(double flt_val); static boolean is_special(double flt_val);
static boolean is_nan(double flt_val);
static void check_numeric(double flt_val, const char *err_msg_begin); static void check_numeric(double flt_val, const char *err_msg_begin);
void log() const; void log() const;
......
...@@ -9,9 +9,10 @@ ...@@ -9,9 +9,10 @@
# Balasko, Jeno # Balasko, Jeno
# Baranyi, Botond # Baranyi, Botond
# Ormandi, Matyas # Ormandi, Matyas
# Szabo, Bence Janos
# #
############################################################################## ##############################################################################
SADIRS := ver xer encode param template any_from pattern_ref SADIRS := ver xer encode param template any_from pattern_ref float
ifeq ($(RT2), yes) ifeq ($(RT2), yes)
SADIRS += deprecated SADIRS += deprecated
endif endif
......
/******************************************************************************
* Copyright (c) 2000-2016 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Bence Janos Szabo
*
******************************************************************************/
module special_SE { //^In TTCN-3 module//
const float err1 := infinity + infinity; //^In constant definition// //^In the operands of operation \`\+\'// //^error: Invalid operands of float \+\: First operand is INF\, Second operand is INF//
const float err2 := infinity + -infinity; //^In constant definition// //^In the operands of operation \`\+\'// //^error: Invalid operands of float \+\: First operand is INF\, Second operand is -INF//
const float err3 := -infinity + -infinity; //^In constant definition// //^In the operands of operation \`\+\'// //^error: Invalid operands of float \+\: First operand is -INF\, Second operand is -INF//
const float err4 := infinity - infinity; //^In constant definition// //^In the operands of operation \`\-\'// //^error: Invalid operands of float \-\: First operand is INF\, Second operand is INF//
const float err5 := infinity - -infinity; //^In constant definition// //^In the operands of operation \`\-\'// //^error: Invalid operands of float \-\: First operand is INF\, Second operand is -INF//
const float err6 := -infinity - -infinity; //^In constant definition// //^In the operands of operation \`\-\'// //^error: Invalid operands of float \-\: First operand is -INF\, Second operand is -INF//
const float err7 := infinity * infinity; //^In constant definition// //^In the operands of operation \`\*\'// //^error: Invalid operands of float \*\: First operand is INF\, Second operand is INF//
const float err8 := infinity * -infinity; //^In constant definition// //^In the operands of operation \`\*\'// //^error: Invalid operands of float \*\: First operand is INF\, Second operand is -INF//
const float err9 := -infinity * -infinity; //^In constant definition// //^In the operands of operation \`\*\'// //^error: Invalid operands of float \*\: First operand is -INF\, Second operand is -INF//
const float err10 := infinity / infinity; //^In constant definition// //^In the operands of operation \`\/\'// //^error: Invalid operands of float \/\: First operand is INF\, Second operand is INF//
const float err11 := infinity / -infinity; //^In constant definition// //^In the operands of operation \`\/\'// //^error: Invalid operands of float \/\: First operand is INF\, Second operand is -INF//
const float err12 := -infinity / -infinity; //^In constant definition// //^In the operands of operation \`\/\'// //^error: Invalid operands of float \/\: First operand is -INF\, Second operand is -INF//
const float err13 := not_a_number + 2.0; //^In constant definition// //^In the operands of operation \`\+\'// //^error: Invalid operands of float \+\: First operand is NaN\, Second operand is 2\.0e0//
const float err14 := not_a_number - 2.0; //^In constant definition// //^In the operands of operation \`\-\'// //^error: Invalid operands of float \-\: First operand is NaN\, Second operand is 2\.0e0//
const float err15 := not_a_number * 2.0; //^In constant definition// //^In the operands of operation \`\*\'// //^error: Invalid operands of float \*\: First operand is NaN\, Second operand is 2\.0e0//
const float err16 := not_a_number / 2.0; //^In constant definition// //^In the operands of operation \`\/\'// //^error: Invalid operands of float \/\: First operand is NaN\, Second operand is 2\.0e0//
const float err17 := not_a_number + infinity; //^In constant definition// //^In the operands of operation \`\+\'// //^error: Invalid operands of float \+\: First operand is NaN\, Second operand is INF//
const float err18 := not_a_number + -infinity; //^In constant definition// //^In the operands of operation \`\+\'// //^error: Invalid operands of float \+\: First operand is NaN\, Second operand is -INF//
function fun() { //^In function definition//
var float f := 2.0;
var float f2 := f + not_a_number; //^In variable definition// //^In the operands of operation \`\+\'// //^error: Second operand of operation \`\+\' cannot be NaN\, it must be a numeric value//
f2 := not_a_number + f; //^In variable assignment// //^In the operands of operation \`\+\'// //^error: First operand of operation \`\+\' cannot be NaN\, it must be a numeric value//
f2 := not_a_number - f; //^In variable assignment// //^In the operands of operation \`\-\'// //^error: First operand of operation \`\-\' cannot be NaN\, it must be a numeric value//
f2 := f - not_a_number; //^In variable assignment// //^In the operands of operation \`\-\'// //^error: Second operand of operation \`\-\' cannot be NaN\, it must be a numeric value//
f2 := not_a_number * f; //^In variable assignment// //^In the operands of operation \`\*\'// //^error: First operand of operation \`\*\' cannot be NaN\, it must be a numeric value//
f2 := f * not_a_number; //^In variable assignment// //^In the operands of operation \`\*\'// //^error: Second operand of operation \`\*\' cannot be NaN\, it must be a numeric value//
f2 := not_a_number / f; //^In variable assignment// //^In the operands of operation \`\/\'// //^error: First operand of operation \`\/\' cannot be NaN\, it must be a numeric value//
f2 := f / not_a_number; //^In variable assignment// //^In the operands of operation \`\/\'// //^error: Second operand of operation \`\/\' cannot be NaN\, it must be a numeric value//
}
}
...@@ -8,15 +8,29 @@ ...@@ -8,15 +8,29 @@
* Contributors: * Contributors:
* Balasko, Jeno * Balasko, Jeno
* Raduly, Csaba * Raduly, Csaba
* Szabo, Bence Janos
* *
******************************************************************************/ ******************************************************************************/
module subtype_SE { //^In TTCN-3 module// module subtype_SE { //^In TTCN-3 module//
import from subtype_OK all;
type component floater {} type component floater {}
type myf123 su2 (3.14); //^In type definition// //^error: The subtype restriction is not a subset of the restriction on the parent type\. Subtype \(3\.14e0\) is not subset of subtype \(1\.0e0,2\.0e0,3\.0e0\)$// type float myf123 (1.0, 2.0, 3.0)
type minf_to_zero su3 (!6.0 .. 10.0); //^In type definition// //^error: The subtype restriction is not a subset of the restriction on the parent type\. Subtype \(!6\.0e0\.\.1\.0e1\) is not subset of subtype \(-INF\.\.0\.0e0\)$// type float minf_to_zero (-infinity..0.0)
type float minf_to_mzero (-infinity..-0.0)
type float reals (-infinity..infinity)
type float reals_and_some (-infinity..infinity, 0.0, 1.0, 2.0, 3.0)
//type myf5 myf6
type float pow2 (2147483648.0, 4294967296.0, 8589934592.0)
type float two31_32 (2147483648.0..8589934592.0)
type float myf9 (myf123, minf_to_zero)
type myf9 myf10 (myf123)
type two31_32 myf11 (2147483648.0..4294967296.0, 4294967296.0..4294967300.0)
type myf123 su2 (3.14); //^In type definition// //^error\: The subtype restriction is not a subset of the restriction on the parent type\. Subtype \(3\.14e0\) is not subset of subtype \(1\.0e0,2\.0e0,3\.0e0\)$//
type minf_to_zero su3 (!6.0 .. 10.0); //^In type definition// //^error\: The subtype restriction is not a subset of the restriction on the parent type\. Subtype \(\!6\.0e0\.\.1\.0e1\) is not subset of subtype \(\-INF\.\.0\.0e0\)$//
type float buzz_lightyear (infinity .. not_a_number) //^In type definition// //^error: upper boundary cannot be not_a_number in float subtype range$// type float buzz_lightyear (infinity .. not_a_number) //^In type definition// //^error: upper boundary cannot be not_a_number in float subtype range$//
// to infinity and beyond // to infinity and beyond
......
...@@ -23,7 +23,7 @@ include $(TOPDIR)/Makefile.regression ...@@ -23,7 +23,7 @@ include $(TOPDIR)/Makefile.regression
TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX) TTCN3_LIB = ttcn3$(RT2_SUFFIX)$(DYNAMIC_SUFFIX)
TTCN3_MODULES = TfloatOper.ttcn TTCN3_MODULES = TfloatOper.ttcn TfloatOperSpecial.ttcn
GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc) GENERATED_SOURCES = $(TTCN3_MODULES:.ttcn=.cc)
GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh) GENERATED_HEADERS = $(GENERATED_SOURCES:.cc=.hh)
...@@ -38,7 +38,7 @@ endif ...@@ -38,7 +38,7 @@ endif
OBJECTS = $(GENERATED_SOURCES:.cc=.o) OBJECTS = $(GENERATED_SOURCES:.cc=.o)
TARGET = TfloatOper$(EXESUFFIX) TARGET = TfloatOperTests$(EXESUFFIX)
all: $(TARGET) all: $(TARGET)
......
/******************************************************************************
* Copyright (c) 2000-2016 Ericsson Telecom AB
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Szabo, Bence Janos
*
******************************************************************************/
module TfloatOperSpecial {
type component EmptyCT {}
testcase tc_addition() runs on EmptyCT {
var float f := infinity;
var float f2 := 1.0;
f := f + 1.0;
if (f != infinity) {
setverdict(fail);
}
f := f + f2;
if (f != infinity) {
setverdict(fail);
}
f := -infinity;
f := f + 1.0;
if (f != -infinity) {
setverdict(fail);
}
f := f + f2;
if (f != -infinity) {
setverdict(fail);
}
// Checked at compile time
f := infinity + 1.0;
if (f != infinity) {
setverdict(fail);
}
f := -infinity + 1.0;
if (f != -infinity) {
setverdict(fail);
}
var charstring dte_message := "Dynamic test case error: Invalid operands of float addition: Left operand is inf, right operand is inf";
@try {
f := infinity;
f2 := infinity;
f := f + f2;
setverdict(fail, "Expected dynamic test case error");
}
@catch (msg) {