Fix extract_real (thanks Manuele), and add check for overflow.
authorMario de Sousa <msousa@fe.up.pt>
Sun, 10 Jun 2012 21:47:15 +0100
changeset 576 8368ec909825
parent 575 a1b63f776535
child 577 f578f14cb97f
Fix extract_real (thanks Manuele), and add check for overflow.
absyntax_utils/absyntax_utils.cc
absyntax_utils/absyntax_utils.hh
stage3/constant_folding.cc
--- a/absyntax_utils/absyntax_utils.cc	Sun Jun 10 15:54:10 2012 +0100
+++ b/absyntax_utils/absyntax_utils.cc	Sun Jun 10 21:47:15 2012 +0100
@@ -139,14 +139,28 @@
 
 /* extract the value of a real from an real_c object !! */
 /* NOTE: it must ignore underscores! */
-real64_t extract_real_value(symbol_c *sym) {
+/* From iec_bison.yy
+ *  real:
+ *   real_token		{$$ = new real_c($1, locloc(@$));}
+ * | fixed_point_token	{$$ = new real_c($1, locloc(@$));}
+ *
+ * From iec_flex.ll
+ * {real}			{yylval.ID=strdup(yytext); return real_token;}
+ * {fixed_point}		{yylval.ID=strdup(yytext); return fixed_point_token;}
+ *
+ * real		{integer}\.{integer}{exponent}
+ * fixed_point		{integer}\.{integer}
+ * exponent        [Ee]([+-]?){integer}
+ * integer         {digit}((_?{digit})*)
+ */
+real64_t extract_real_value(symbol_c *sym, bool *overflow = NULL) {
   std::string str = "";
   char *endptr;
   real_c * real_sym;
-  uint64_t ret;
+  real64_t ret;
 
   if ((real_sym = dynamic_cast<real_c *>(sym)) == NULL) ERROR;
-  for(unsigned int i = 3; i < strlen(real_sym->value); i++)
+  for(unsigned int i = 0; i < strlen(real_sym->value); i++)
     if (real_sym->value[i] != '_') str += real_sym->value[i];
     
   errno = 0; // since strtoXX() may legally return 0, we must set errno to 0 to detect errors correctly!
@@ -159,7 +173,10 @@
   #else 
     #error Could not determine which data type is being used for real64_t (defined in absyntax.hh). Aborting!
   #endif
-  if (errno != 0) ERROR;
+  if (overflow != NULL)
+    *overflow = (errno == ERANGE);
+  if ((errno != 0) && (errno != ERANGE)) 
+    ERROR;
 
   return ret;
 }
--- a/absyntax_utils/absyntax_utils.hh	Sun Jun 10 15:54:10 2012 +0100
+++ b/absyntax_utils/absyntax_utils.hh	Sun Jun 10 21:47:15 2012 +0100
@@ -58,7 +58,7 @@
 /* extract the value of an integer/hex_integer/real from an integer_c/hex_integer_c/real_c symbol !! */
 long long extract_integer_value(symbol_c *sym);
 uint64_t  extract_hex_value    (symbol_c *sym);
-real64_t  extract_real_value   (symbol_c *sym);
+real64_t  extract_real_value   (symbol_c *sym, bool *overflow);
   
 /* A symbol table with all globally declared functions... */
 extern function_declaration_c null_symbol1;
--- a/stage3/constant_folding.cc	Sun Jun 10 15:54:10 2012 +0100
+++ b/stage3/constant_folding.cc	Sun Jun 10 21:47:15 2012 +0100
@@ -393,7 +393,9 @@
 /* B 1.2.1 - Numeric Literals */
 /******************************/
 void *constant_folding_c::visit(real_c *symbol) {
-	NEW_CVALUE(real64, symbol);	SET_CVALUE(real64, symbol, extract_real_value(symbol));
+	bool overflow;
+	NEW_CVALUE(real64, symbol);	SET_CVALUE(real64, symbol, extract_real_value(symbol, &overflow));
+	if (overflow) SET_OVFLOW(real64, symbol);
 	return NULL;
 }