diff options
Diffstat (limited to 'libcpp/expr.c')
| -rw-r--r-- | libcpp/expr.c | 67 | 
1 files changed, 56 insertions, 11 deletions
diff --git a/libcpp/expr.c b/libcpp/expr.c index 0eb6c13..c009807 100644 --- a/libcpp/expr.c +++ b/libcpp/expr.c @@ -394,6 +394,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,    unsigned int max_digit, result, radix;    enum {NOT_FLOAT = 0, AFTER_POINT, AFTER_EXPON} float_flag;    bool seen_digit; +  bool seen_digit_sep;    if (ud_suffix)      *ud_suffix = NULL; @@ -408,6 +409,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,    max_digit = 0;    radix = 10;    seen_digit = false; +  seen_digit_sep = false;    /* First, interpret the radix.  */    if (*str == '0') @@ -416,16 +418,27 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,        str++;        /* Require at least one hex digit to classify it as hex.  */ -      if ((*str == 'x' || *str == 'X') -	  && (str[1] == '.' || ISXDIGIT (str[1]))) +      if (*str == 'x' || *str == 'X')  	{ -	  radix = 16; -	  str++; +	  if (str[1] == '.' || ISXDIGIT (str[1])) +	    { +	      radix = 16; +	      str++; +	    } +	  else if (DIGIT_SEP (str[1])) +	    SYNTAX_ERROR_AT (virtual_location, +			     "digit separator after base indicator");  	} -      else if ((*str == 'b' || *str == 'B') && (str[1] == '0' || str[1] == '1')) +      else if (*str == 'b' || *str == 'B')  	{ -	  radix = 2; -	  str++; +	  if (str[1] == '0' || str[1] == '1') +	    { +	      radix = 2; +	      str++; +	    } +	  else if (DIGIT_SEP (str[1])) +	    SYNTAX_ERROR_AT (virtual_location, +			     "digit separator after base indicator");  	}      } @@ -436,13 +449,24 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,        if (ISDIGIT (c) || (ISXDIGIT (c) && radix == 16))  	{ +	  seen_digit_sep = false;  	  seen_digit = true;  	  c = hex_value (c);  	  if (c > max_digit)  	    max_digit = c;  	} +      else if (DIGIT_SEP (c)) +	{ +	  if (seen_digit_sep) +	    SYNTAX_ERROR_AT (virtual_location, "adjacent digit separators"); +	  seen_digit_sep = true; +	}        else if (c == '.')  	{ +	  if (seen_digit_sep || DIGIT_SEP (*str)) +	    SYNTAX_ERROR_AT (virtual_location, +			     "digit separator adjacent to decimal point"); +	  seen_digit_sep = false;  	  if (float_flag == NOT_FLOAT)  	    float_flag = AFTER_POINT;  	  else @@ -452,6 +476,9 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,        else if ((radix <= 10 && (c == 'e' || c == 'E'))  	       || (radix == 16 && (c == 'p' || c == 'P')))  	{ +	  if (seen_digit_sep || DIGIT_SEP (*str)) +	    SYNTAX_ERROR_AT (virtual_location, +			     "digit separator adjacent to exponent");  	  float_flag = AFTER_EXPON;  	  break;  	} @@ -463,6 +490,10 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,  	}      } +  if (seen_digit_sep && float_flag != AFTER_EXPON) +    SYNTAX_ERROR_AT (virtual_location, +		     "digit separator outside digit sequence"); +    /* The suffix may be for decimal fixed-point constants without exponent.  */    if (radix != 16 && float_flag == NOT_FLOAT)      { @@ -520,16 +551,28 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,  	  /* Exponent is decimal, even if string is a hex float.  */  	  if (!ISDIGIT (*str)) -	    SYNTAX_ERROR_AT (virtual_location, "exponent has no digits"); - +	    { +	      if (DIGIT_SEP (*str)) +		SYNTAX_ERROR_AT (virtual_location, +				 "digit separator adjacent to exponent"); +	      else +		SYNTAX_ERROR_AT (virtual_location, "exponent has no digits"); +	    }  	  do -	    str++; -	  while (ISDIGIT (*str)); +	    { +	      seen_digit_sep = DIGIT_SEP (*str); +	      str++; +	    } +	  while (ISDIGIT (*str) || DIGIT_SEP (*str));  	}        else if (radix == 16)  	SYNTAX_ERROR_AT (virtual_location,  			 "hexadecimal floating constants require an exponent"); +      if (seen_digit_sep) +	SYNTAX_ERROR_AT (virtual_location, +			 "digit separator outside digit sequence"); +        result = interpret_float_suffix (pfile, str, limit - str);        if (result == 0)  	{ @@ -723,6 +766,8 @@ cpp_interpret_integer (cpp_reader *pfile, const cpp_token *token,  	  if (ISDIGIT (c) || (base == 16 && ISXDIGIT (c)))  	    c = hex_value (c); +	  else if (DIGIT_SEP (c)) +	    continue;  	  else  	    break;  | 
