aboutsummaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorEd Smith-Rowland <3dw4rd@verizon.net>2013-06-29 03:41:58 +0000
committerEdward Smith-Rowland <emsr@gcc.gnu.org>2013-06-29 03:41:58 +0000
commitc865f9238ac6e835eb0e86f72cdd07b8064df21f (patch)
tree30b4ba2a69beb74bae477e5c0f92613b0eee4ae5 /libcpp
parentefc58ac54877a0d0fcc82a269e8791343465a6dc (diff)
downloadgcc-c865f9238ac6e835eb0e86f72cdd07b8064df21f.zip
gcc-c865f9238ac6e835eb0e86f72cdd07b8064df21f.tar.gz
gcc-c865f9238ac6e835eb0e86f72cdd07b8064df21f.tar.bz2
lex.c (lex_raw_string(), [...]): Constrain suffixes treated as concatenated literal and macro to just the...
libcpp: 2013-06-28 Ed Smith-Rowland <3dw4rd@verizon.net> * lex.c (lex_raw_string(), lex_string()): Constrain suffixes treated as concatenated literal and macro to just the patterns found in inttypes.h; (is_macro()): New. gcc/cp: 2013-06-28 Ed Smith-Rowland <3dw4rd@verizon.net> * cp-tree.h (UDLIT_OP_ANSI_PREFIX): Remove space. * parser.c (cp_parser_operator()): Parse user-defined string literal as literal operator. gcc/testsuite: 2013-06-28 Ed Smith-Rowland <3dw4rd@verizon.net> * g++.dg/cpp0x/udlit-nospace-neg.C: Adjust. * g++.dg/cpp1y/udlit-enc-prefix-neg.C: New. * g++.dg/cpp1y/udlit-userdef-string.C: New. * g++.dg/cpp1y/complex_literals.h: New. From-SVN: r200563
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog6
-rw-r--r--libcpp/lex.c59
2 files changed, 45 insertions, 20 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index ca29119..0cf9100 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,9 @@
+2013-06-28 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ * lex.c (lex_raw_string(), lex_string()): Constrain suffixes treated
+ as concatenated literal and macro to just the patterns found in
+ inttypes.h; (is_macro()): New.
+
2013-06-24 Dehao Chen <dehao@google.com>
* files.c (_cpp_stack_include): Fix the highest_location when header
diff --git a/libcpp/lex.c b/libcpp/lex.c
index 3e59d40..022d310 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -1334,6 +1334,33 @@ bufring_append (cpp_reader *pfile, const uchar *base, size_t len,
*last_buff_p = last_buff;
}
+
+/* Returns true if a macro has been defined.
+ This might not work if compile with -save-temps,
+ or preprocess separately from compilation. */
+
+static bool
+is_macro(cpp_reader *pfile, const uchar *base)
+{
+ const uchar *cur = base;
+ if (! ISIDST (*cur))
+ return false;
+ unsigned int hash = HT_HASHSTEP (0, *cur);
+ ++cur;
+ while (ISIDNUM (*cur))
+ {
+ hash = HT_HASHSTEP (hash, *cur);
+ ++cur;
+ }
+ hash = HT_HASHFINISH (hash, cur - base);
+
+ cpp_hashnode *result = CPP_HASHNODE (ht_lookup_with_hash (pfile->hash_table,
+ base, cur - base, hash, HT_NO_INSERT));
+
+ return !result ? false : (result->type == NT_MACRO);
+}
+
+
/* Lexes a raw string. The stored string contains the spelling, including
double quotes, delimiter string, '(' and ')', any leading
'L', 'u', 'U' or 'u8' and 'R' modifier. It returns the type of the
@@ -1556,22 +1583,18 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
if (CPP_OPTION (pfile, user_literals))
{
- /* According to C++11 [lex.ext]p10, a ud-suffix not starting with an
- underscore is ill-formed. Since this breaks programs using macros
- from inttypes.h, we generate a warning and treat the ud-suffix as a
- separate preprocessing token. This approach is under discussion by
- the standards committee, and has been adopted as a conforming
- extension by other front ends such as clang.
- A special exception is made for the suffix 's' which will be
- standardized as a user-defined literal suffix for strings. */
- if (ISALPHA (*cur) && *cur != 's')
+ /* If a string format macro, say from inttypes.h, is placed touching
+ a string literal it could be parsed as a C++11 user-defined string
+ literal thus breaking the program.
+ Try to identify macros with is_macro. A warning is issued. */
+ if (is_macro (pfile, cur))
{
/* Raise a warning, but do not consume subsequent tokens. */
if (CPP_OPTION (pfile, warn_literal_suffix))
cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX,
token->src_loc, 0,
"invalid suffix on literal; C++11 requires "
- "a space between literal and identifier");
+ "a space between literal and string macro");
}
/* Grab user defined literal suffix. */
else if (ISIDST (*cur))
@@ -1689,22 +1712,18 @@ lex_string (cpp_reader *pfile, cpp_token *token, const uchar *base)
if (CPP_OPTION (pfile, user_literals))
{
- /* According to C++11 [lex.ext]p10, a ud-suffix not starting with an
- underscore is ill-formed. Since this breaks programs using macros
- from inttypes.h, we generate a warning and treat the ud-suffix as a
- separate preprocessing token. This approach is under discussion by
- the standards committee, and has been adopted as a conforming
- extension by other front ends such as clang.
- A special exception is made for the suffix 's' which will be
- standardized as a user-defined literal suffix for strings. */
- if (ISALPHA (*cur) && *cur != 's')
+ /* If a string format macro, say from inttypes.h, is placed touching
+ a string literal it could be parsed as a C++11 user-defined string
+ literal thus breaking the program.
+ Try to identify macros with is_macro. A warning is issued. */
+ if (is_macro (pfile, cur))
{
/* Raise a warning, but do not consume subsequent tokens. */
if (CPP_OPTION (pfile, warn_literal_suffix))
cpp_warning_with_line (pfile, CPP_W_LITERAL_SUFFIX,
token->src_loc, 0,
"invalid suffix on literal; C++11 requires "
- "a space between literal and identifier");
+ "a space between literal and string macro");
}
/* Grab user defined literal suffix. */
else if (ISIDST (*cur))