summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authoremsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-10 00:08:49 +0000
committeremsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4>2012-11-10 00:08:49 +0000
commit2dd006369c22f7affef6c7082e3671cba988468d (patch)
tree6f4eb9fb1a2dfd8c43e78bcc98930f16138e78c4 /libcpp
parentec745a53793f0eec84eabfc3b93cb12ba1e4916f (diff)
downloadgcc-2dd006369c22f7affef6c7082e3671cba988468d.tar.gz
Implement a flag -fext-numeric-literals that allows control of whether GNU
numeric suffix extensions are parsed or passed to C++ as user-defined literals. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193382 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog12
-rw-r--r--libcpp/expr.c118
-rw-r--r--libcpp/include/cpplib.h10
-rw-r--r--libcpp/init.c1
4 files changed, 86 insertions, 55 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 4bd0b26aa5e..4f78ecf761c 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 cd6e7d4eca6..df8d96553fd 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 a58454e9839..72415f0348a 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 81b66df57e5..ebe51c76c86 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. */