# HG changeset patch # User Mario de Sousa # Date 1328724973 0 # Node ID 82cb6a64a763b9ab204cc2605de5c2e004686da4 # Parent c1278e52bcbca01718899a4221e9195c2c1e45ce Change negation expression (neg_expression_c) to only allow signed data types. diff -r c1278e52bcbc -r 82cb6a64a763 stage3/datatype_functions.cc --- a/stage3/datatype_functions.cc Tue Feb 07 17:45:17 2012 +0000 +++ b/stage3/datatype_functions.cc Wed Feb 08 18:16:13 2012 +0000 @@ -220,6 +220,13 @@ } /* A helper function... */ +bool is_ANY_signed_MAGNITUDE_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;} + return is_ANY_signed_NUM_type(type_symbol); +} + +/* A helper function... */ bool is_ANY_SAFEMAGNITUDE_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;} @@ -227,15 +234,29 @@ } /* A helper function... */ +bool is_ANY_signed_SAFEMAGNITUDE_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;} + return is_ANY_signed_SAFENUM_type(type_symbol); +} + +/* A helper function... */ bool is_ANY_MAGNITUDE_compatible(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} if (is_ANY_MAGNITUDE_type (type_symbol)) {return true;} if (is_ANY_SAFEMAGNITUDE_type(type_symbol)) {return true;} - return is_ANY_NUM_compatible(type_symbol); } /* A helper function... */ +bool is_ANY_signed_MAGNITUDE_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_signed_MAGNITUDE_type (type_symbol)) {return true;} + if (is_ANY_signed_SAFEMAGNITUDE_type(type_symbol)) {return true;} + return is_ANY_signed_NUM_compatible(type_symbol); +} + +/* A helper function... */ bool is_ANY_NUM_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} if (is_ANY_REAL_type(type_symbol)) {return true;} @@ -244,6 +265,14 @@ } /* A helper function... */ +bool is_ANY_signed_NUM_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_REAL_type(type_symbol)) {return true;} + if (is_ANY_signed_INT_type(type_symbol)) {return true;} + return false; +} + +/* A helper function... */ bool is_ANY_SAFENUM_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} return is_ANY_SAFEREAL_type(type_symbol) @@ -251,6 +280,13 @@ } /* A helper function... */ +bool is_ANY_signed_SAFENUM_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + return is_ANY_SAFEREAL_type(type_symbol) + || is_ANY_signed_SAFEINT_type (type_symbol); +} + +/* A helper function... */ bool is_ANY_NUM_compatible(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} if (is_ANY_REAL_compatible(type_symbol)) {return true;} @@ -259,6 +295,14 @@ } /* A helper function... */ +bool is_ANY_signed_NUM_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_REAL_compatible(type_symbol)) {return true;} + if (is_ANY_signed_INT_compatible(type_symbol)) {return true;} + return false; +} + +/* A helper function... */ bool is_ANY_DATE_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;} @@ -324,6 +368,26 @@ } /* A helper function... */ +bool is_ANY_signed_INT_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(sint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(int_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(dint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(lint_type_name_c)) {return true;} + return false; +} + +/* A helper function... */ +bool is_ANY_signed_SAFEINT_type(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (typeid(*type_symbol) == typeid(safesint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safeint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safedint_type_name_c)) {return true;} + if (typeid(*type_symbol) == typeid(safelint_type_name_c)) {return true;} + return false; +} + +/* A helper function... */ bool is_ANY_SAFEINT_type(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} if (typeid(*type_symbol) == typeid(safesint_type_name_c)) {return true;} @@ -338,6 +402,15 @@ } /* A helper function... */ +bool is_ANY_signed_INT_compatible(symbol_c *type_symbol) { + if (type_symbol == NULL) {return false;} + if (is_ANY_signed_INT_type (type_symbol)) {return true;} + if (is_ANY_signed_SAFEINT_type(type_symbol)) {return true;} +// if (is_literal_integer_type(type_symbol)) {return true;} + return false; +} + +/* A helper function... */ bool is_ANY_INT_compatible(symbol_c *type_symbol) { if (type_symbol == NULL) {return false;} if (is_ANY_INT_type (type_symbol)) {return true;} diff -r c1278e52bcbc -r 82cb6a64a763 stage3/datatype_functions.hh --- a/stage3/datatype_functions.hh Tue Feb 07 17:45:17 2012 +0000 +++ b/stage3/datatype_functions.hh Wed Feb 08 18:16:13 2012 +0000 @@ -133,6 +133,10 @@ bool is_ANY_SAFEMAGNITUDE_type (symbol_c *type_symbol); bool is_ANY_MAGNITUDE_compatible (symbol_c *type_symbol); +bool is_ANY_signed_MAGNITUDE_type (symbol_c *type_symbol); +bool is_ANY_signed_SAFEMAGNITUDE_type (symbol_c *type_symbol); +bool is_ANY_signed_MAGNITUDE_compatible (symbol_c *type_symbol); + bool is_ANY_DATE_type (symbol_c *type_symbol); bool is_ANY_SAFEDATE_type (symbol_c *type_symbol); bool is_ANY_DATE_compatible (symbol_c *type_symbol); @@ -145,6 +149,10 @@ bool is_ANY_SAFEINT_type (symbol_c *type_symbol); bool is_ANY_INT_compatible (symbol_c *type_symbol); +bool is_ANY_signed_INT_type (symbol_c *type_symbol); +bool is_ANY_signed_SAFEINT_type (symbol_c *type_symbol); +bool is_ANY_signed_INT_compatible (symbol_c *type_symbol); + bool is_ANY_REAL_type (symbol_c *type_symbol); bool is_ANY_SAFEREAL_type (symbol_c *type_symbol); bool is_ANY_REAL_compatible (symbol_c *type_symbol); @@ -153,6 +161,10 @@ bool is_ANY_SAFENUM_type (symbol_c *type_symbol); bool is_ANY_NUM_compatible (symbol_c *type_symbol); +bool is_ANY_signed_NUM_type (symbol_c *type_symbol); +bool is_ANY_signed_SAFENUM_type (symbol_c *type_symbol); +bool is_ANY_signed_NUM_compatible (symbol_c *type_symbol); + bool is_ANY_BIT_type (symbol_c *type_symbol); bool is_ANY_SAFEBIT_type (symbol_c *type_symbol); bool is_ANY_BIT_compatible (symbol_c *type_symbol); diff -r c1278e52bcbc -r 82cb6a64a763 stage3/fill_candidate_datatypes.cc --- a/stage3/fill_candidate_datatypes.cc Tue Feb 07 17:45:17 2012 +0000 +++ b/stage3/fill_candidate_datatypes.cc Wed Feb 08 18:16:13 2012 +0000 @@ -1666,9 +1666,33 @@ void *fill_candidate_datatypes_c::visit(neg_expression_c *symbol) { + /* NOTE: The standard defines the syntax for this 'negation' operation, but + * does not define the its semantics. + * + * We could be tempted to consider that the semantics of the + * 'negation' operation are similar/identical to the semantics of the + * SUB expression/operation. This would include assuming that the + * possible datatypes for the 'negation' operation is also + * the same as those for the SUB expression/operation, namely ANY_MAGNITUDE. + * + * However, this would then mean that the following ST code would be + * syntactically and semantically correct: + * uint_var := - (uint_var); + * + * According to the standard, the above code should result in a + * runtime error, when we try to apply a negative value to the + * UINT typed variable 'uint_var'. + * + * It is much easier for the compiler to detect this at compile time, + * and it is probably safer to the resulting code too. + * + * To detect these tyes of errors at compile time, the easisest solution + * is to only allow ANY_NUM datatytpes that are signed. + * So, that is what we do here! + */ symbol->exp->accept(*this); for (unsigned int i = 0; i < symbol->exp->candidate_datatypes.size(); i++) { - if (is_ANY_MAGNITUDE_compatible(symbol->exp->candidate_datatypes[i])) + if (is_ANY_signed_MAGNITUDE_compatible(symbol->exp->candidate_datatypes[i])) symbol->candidate_datatypes.push_back(symbol->exp->candidate_datatypes[i]); } if (debug) std::cout << "neg [" << symbol->exp->candidate_datatypes.size() << "] ==> " << symbol->candidate_datatypes.size() << " result.\n";