summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authoremsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-29 03:41:58 +0000
committeremsr <emsr@138bc75d-0d04-0410-961f-82ee72b054a4>2013-06-29 03:41:58 +0000
commit4e8832f33d8484eadac7687afac102d71def6d2d (patch)
tree30b4ba2a69beb74bae477e5c0f92613b0eee4ae5 /libcpp
parent90535e971b72cdc094c20d3625fb5d1527a07c17 (diff)
downloadgcc-4e8832f33d8484eadac7687afac102d71def6d2d.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@200563 138bc75d-0d04-0410-961f-82ee72b054a4
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 ca29119c953..0cf9100cf62 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 3e59d40d32e..022d31016e2 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))