diff options
Diffstat (limited to 'libcpp')
| -rw-r--r-- | libcpp/ChangeLog | 12 | ||||
| -rw-r--r-- | libcpp/expr.c | 118 | ||||
| -rw-r--r-- | libcpp/include/cpplib.h | 10 | ||||
| -rw-r--r-- | libcpp/init.c | 1 | 
4 files changed, 86 insertions, 55 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 4bd0b26..4f78ecf 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,15 @@ +2012-11-09  Ed Smith-Rowland  <3dw4rd@verizon.net> + +	PR c++/54413 +	* include/cpplib.h (cpp_interpret_float_suffix): Add cpp_reader* arg. +	(cpp_interpret_int_suffix): Add cpp_reader* arg. +	* init.c (cpp_create_reader): Iitialize new flags. +	* expr.c (interpret_float_suffix): Use new flags. +	(cpp_interpret_float_suffix): Add cpp_reader* arg. +	(interpret_int_suffix): Use new flags. +	(cpp_interpret_int_suffix): Add cpp_reader* arg. +	(cpp_classify_number): Adjust calls to interpret_x_suffix. +  2012-10-23  Ian Bolton  <ian.bolton@arm.com>  	    Jim MacArthur  <jim.macarthur@arm.com>  	    Marcus Shawcroft  <marcus.shawcroft@arm.com> diff --git a/libcpp/expr.c b/libcpp/expr.c index cd6e7d4..df8d965 100644 --- a/libcpp/expr.c +++ b/libcpp/expr.c @@ -61,8 +61,8 @@ static cpp_num append_digit (cpp_num, int, int, size_t);  static cpp_num parse_defined (cpp_reader *);  static cpp_num eval_token (cpp_reader *, const cpp_token *, source_location);  static struct op *reduce (cpp_reader *, struct op *, enum cpp_ttype); -static unsigned int interpret_float_suffix (const uchar *, size_t); -static unsigned int interpret_int_suffix (const uchar *, size_t); +static unsigned int interpret_float_suffix (cpp_reader *, const uchar *, size_t); +static unsigned int interpret_int_suffix (cpp_reader *, const uchar *, size_t);  static void check_promotion (cpp_reader *, const struct op *);  /* Token type abuse to create unary plus and minus operators.  */ @@ -87,7 +87,7 @@ static void check_promotion (cpp_reader *, const struct op *);     length LEN, possibly zero.  Returns 0 for an invalid suffix, or a     flag vector describing the suffix.  */  static unsigned int -interpret_float_suffix (const uchar *s, size_t len) +interpret_float_suffix (cpp_reader *pfile, const uchar *s, size_t len)  {    size_t flags;    size_t f, d, l, w, q, i; @@ -115,55 +115,58 @@ interpret_float_suffix (const uchar *s, size_t len)        }      } -  /* Recognize a fixed-point suffix.  */ -  if (len != 0) -    switch (s[len-1]) -      { -      case 'k': case 'K': flags = CPP_N_ACCUM; break; -      case 'r': case 'R': flags = CPP_N_FRACT; break; -      default: break; -      } - -  /* Continue processing a fixed-point suffix.  The suffix is case -     insensitive except for ll or LL.  Order is significant.  */ -  if (flags) +  if (CPP_OPTION (pfile, ext_numeric_literals))      { -      if (len == 1) -	return flags; -      len--; +      /* Recognize a fixed-point suffix.  */ +      if (len != 0) +	switch (s[len-1]) +	  { +	  case 'k': case 'K': flags = CPP_N_ACCUM; break; +	  case 'r': case 'R': flags = CPP_N_FRACT; break; +	  default: break; +	  } -      if (*s == 'u' || *s == 'U') +      /* Continue processing a fixed-point suffix.  The suffix is case +	 insensitive except for ll or LL.  Order is significant.  */ +      if (flags)  	{ -	  flags |= CPP_N_UNSIGNED;  	  if (len == 1)  	    return flags;  	  len--; -	  s++; -        } -      switch (*s) -      { -      case 'h': case 'H': -	if (len == 1) -	  return flags |= CPP_N_SMALL; -	break; -      case 'l': -	if (len == 1) -	  return flags |= CPP_N_MEDIUM; -	if (len == 2 && s[1] == 'l') -	  return flags |= CPP_N_LARGE; -	break; -      case 'L': -	if (len == 1) -	  return flags |= CPP_N_MEDIUM; -	if (len == 2 && s[1] == 'L') -	  return flags |= CPP_N_LARGE; -	break; -      default: -	break; -      } -      /* Anything left at this point is invalid.  */ -      return 0; +	  if (*s == 'u' || *s == 'U') +	    { +	      flags |= CPP_N_UNSIGNED; +	      if (len == 1) +		return flags; +	      len--; +	      s++; +            } + +	  switch (*s) +	  { +	  case 'h': case 'H': +	    if (len == 1) +	      return flags |= CPP_N_SMALL; +	    break; +	  case 'l': +	    if (len == 1) +	      return flags |= CPP_N_MEDIUM; +	    if (len == 2 && s[1] == 'l') +	      return flags |= CPP_N_LARGE; +	    break; +	  case 'L': +	    if (len == 1) +	      return flags |= CPP_N_MEDIUM; +	    if (len == 2 && s[1] == 'L') +	      return flags |= CPP_N_LARGE; +	    break; +	  default: +	    break; +	  } +	  /* Anything left at this point is invalid.  */ +	  return 0; +	}      }    /* In any remaining valid suffix, the case and order don't matter.  */ @@ -184,6 +187,12 @@ interpret_float_suffix (const uchar *s, size_t len)    if (f + d + l + w + q > 1 || i > 1)      return 0; +  if (i && !CPP_OPTION (pfile, ext_numeric_literals)) +    return 0; + +  if ((w || q) && !CPP_OPTION (pfile, ext_numeric_literals)) +    return 0; +    return ((i ? CPP_N_IMAGINARY : 0)  	  | (f ? CPP_N_SMALL :  	     d ? CPP_N_MEDIUM : @@ -194,16 +203,16 @@ interpret_float_suffix (const uchar *s, size_t len)  /* Return the classification flags for a float suffix.  */  unsigned int -cpp_interpret_float_suffix (const char *s, size_t len) +cpp_interpret_float_suffix (cpp_reader *pfile, const char *s, size_t len)  { -  return interpret_float_suffix ((const unsigned char *)s, len); +  return interpret_float_suffix (pfile, (const unsigned char *)s, len);  }  /* Subroutine of cpp_classify_number.  S points to an integer suffix     of length LEN, possibly zero. Returns 0 for an invalid suffix, or a     flag vector describing the suffix.  */  static unsigned int -interpret_int_suffix (const uchar *s, size_t len) +interpret_int_suffix (cpp_reader *pfile, const uchar *s, size_t len)  {    size_t u, l, i; @@ -227,6 +236,9 @@ interpret_int_suffix (const uchar *s, size_t len)    if (l > 2 || u > 1 || i > 1)      return 0; +  if (i && !CPP_OPTION (pfile, ext_numeric_literals)) +    return 0; +    return ((i ? CPP_N_IMAGINARY : 0)  	  | (u ? CPP_N_UNSIGNED : 0)  	  | ((l == 0) ? CPP_N_SMALL @@ -235,9 +247,9 @@ interpret_int_suffix (const uchar *s, size_t len)  /* Return the classification flags for an int suffix.  */  unsigned int -cpp_interpret_int_suffix (const char *s, size_t len) +cpp_interpret_int_suffix (cpp_reader *pfile, const char *s, size_t len)  { -  return interpret_int_suffix ((const unsigned char *)s, len); +  return interpret_int_suffix (pfile, (const unsigned char *)s, len);  }  /* Return the string type corresponding to the the input user-defined string @@ -455,7 +467,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,    /* The suffix may be for decimal fixed-point constants without exponent.  */    if (radix != 16 && float_flag == NOT_FLOAT)      { -      result = interpret_float_suffix (str, limit - str); +      result = interpret_float_suffix (pfile, str, limit - str);        if ((result & CPP_N_FRACT) || (result & CPP_N_ACCUM))  	{  	  result |= CPP_N_FLOATING; @@ -519,7 +531,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,  	SYNTAX_ERROR_AT (virtual_location,  			 "hexadecimal floating constants require an exponent"); -      result = interpret_float_suffix (str, limit - str); +      result = interpret_float_suffix (pfile, str, limit - str);        if (result == 0)  	{  	  if (CPP_OPTION (pfile, user_literals)) @@ -573,7 +585,7 @@ cpp_classify_number (cpp_reader *pfile, const cpp_token *token,      }    else      { -      result = interpret_int_suffix (str, limit - str); +      result = interpret_int_suffix (pfile, str, limit - str);        if (result == 0)  	{  	  if (CPP_OPTION (pfile, user_literals)) diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index a58454e..72415f0 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -431,6 +431,10 @@ struct cpp_options       ud-suffix which does not beging with an underscore.  */    unsigned char warn_literal_suffix; +  /* Nonzero means interpret imaginary, fixed-point, or other gnu extension +     literal number suffixes as user-defined literal number suffixes.  */ +  unsigned char ext_numeric_literals; +    /* Holds the name of the target (execution) character set.  */    const char *narrow_charset; @@ -854,10 +858,12 @@ extern unsigned cpp_classify_number (cpp_reader *, const cpp_token *,  				     const char **, source_location);  /* Return the classification flags for a float suffix.  */ -extern unsigned int cpp_interpret_float_suffix (const char *, size_t); +extern unsigned int cpp_interpret_float_suffix (cpp_reader *, const char *, +						size_t);  /* Return the classification flags for an int suffix.  */ -extern unsigned int cpp_interpret_int_suffix (const char *, size_t); +extern unsigned int cpp_interpret_int_suffix (cpp_reader *, const char *, +					      size_t);  /* Evaluate a token classified as category CPP_N_INTEGER.  */  extern cpp_num cpp_interpret_integer (cpp_reader *, const cpp_token *, diff --git a/libcpp/init.c b/libcpp/init.c index 81b66df..ebe51c7 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -182,6 +182,7 @@ cpp_create_reader (enum c_lang lang, cpp_hash_table *table,    CPP_OPTION (pfile, track_macro_expansion) = 2;    CPP_OPTION (pfile, warn_normalize) = normalized_C;    CPP_OPTION (pfile, warn_literal_suffix) = 1; +  CPP_OPTION (pfile, ext_numeric_literals) = 1;    /* Default CPP arithmetic to something sensible for the host for the       benefit of dumb users like fix-header.  */  | 
