summaryrefslogtreecommitdiff
path: root/libcpp
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-21 02:28:03 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2013-07-21 02:28:03 +0000
commitffb840b4125e9678af756f1a902ca0fe7f04bbd0 (patch)
tree6ed6396fa7b067df8a3ff310a4f33ede51228e59 /libcpp
parentaf48db325567f6be664d774d644e790306e13261 (diff)
downloadgcc-ffb840b4125e9678af756f1a902ca0fe7f04bbd0.tar.gz
PR preprocessor/57620
* lex.c (lex_raw_string): Undo phase1 and phase2 transformations between R" and final " rather than only in between R"del( and )del". * c-c++-common/raw-string-2.c (s12, u12, U12, L12): Remove. (main): Don't test {s,u,U,L}12. * c-c++-common/raw-string-13.c: New test. * c-c++-common/raw-string-14.c: New test. * c-c++-common/raw-string-15.c: New test. * c-c++-common/raw-string-16.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201091 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libcpp')
-rw-r--r--libcpp/ChangeLog6
-rw-r--r--libcpp/lex.c191
2 files changed, 124 insertions, 73 deletions
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 9213232aa98..dd107aec089 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,9 @@
+2013-07-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR preprocessor/57620
+ * lex.c (lex_raw_string): Undo phase1 and phase2 transformations
+ between R" and final " rather than only in between R"del( and )del".
+
2013-07-10 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/57824
diff --git a/libcpp/lex.c b/libcpp/lex.c
index fc89bafd81b..ed794d5b004 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -1373,11 +1373,20 @@ static void
lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
const uchar *cur)
{
- const uchar *raw_prefix;
- unsigned int raw_prefix_len = 0;
+ uchar raw_prefix[17];
+ uchar temp_buffer[18];
+ const uchar *orig_base;
+ unsigned int raw_prefix_len = 0, raw_suffix_len = 0;
+ enum raw_str_phase { RAW_STR_PREFIX, RAW_STR, RAW_STR_SUFFIX };
+ raw_str_phase phase = RAW_STR_PREFIX;
enum cpp_ttype type;
size_t total_len = 0;
+ /* Index into temp_buffer during phases other than RAW_STR,
+ during RAW_STR phase 17 to tell BUF_APPEND that nothing should
+ be appended to temp_buffer. */
+ size_t temp_buffer_len = 0;
_cpp_buff *first_buff = NULL, *last_buff = NULL;
+ size_t raw_prefix_start;
_cpp_line_note *note = &pfile->buffer->notes[pfile->buffer->cur_note];
type = (*base == 'L' ? CPP_WSTRING :
@@ -1385,68 +1394,31 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
*base == 'u' ? (base[1] == '8' ? CPP_UTF8STRING : CPP_STRING16)
: CPP_STRING);
- raw_prefix = cur + 1;
- while (raw_prefix_len < 16)
- {
- switch (raw_prefix[raw_prefix_len])
- {
- case ' ': case '(': case ')': case '\\': case '\t':
- case '\v': case '\f': case '\n': default:
- break;
- /* Basic source charset except the above chars. */
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
- case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
- case 's': case 't': case 'u': case 'v': case 'w': case 'x':
- case 'y': case 'z':
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
- case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
- case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
- case 'Y': case 'Z':
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- case '_': case '{': case '}': case '#': case '[': case ']':
- case '<': case '>': case '%': case ':': case ';': case '.':
- case '?': case '*': case '+': case '-': case '/': case '^':
- case '&': case '|': case '~': case '!': case '=': case ',':
- case '"': case '\'':
- raw_prefix_len++;
- continue;
- }
- break;
- }
-
- if (raw_prefix[raw_prefix_len] != '(')
- {
- int col = CPP_BUF_COLUMN (pfile->buffer, raw_prefix + raw_prefix_len)
- + 1;
- if (raw_prefix_len == 16)
- cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, col,
- "raw string delimiter longer than 16 characters");
- else
- cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc, col,
- "invalid character '%c' in raw string delimiter",
- (int) raw_prefix[raw_prefix_len]);
- pfile->buffer->cur = raw_prefix - 1;
- create_literal (pfile, token, base, raw_prefix - 1 - base, CPP_OTHER);
- return;
- }
-
- cur = raw_prefix + raw_prefix_len + 1;
- for (;;)
- {
#define BUF_APPEND(STR,LEN) \
do { \
bufring_append (pfile, (const uchar *)(STR), (LEN), \
&first_buff, &last_buff); \
total_len += (LEN); \
+ if (__builtin_expect (temp_buffer_len < 17, 0) \
+ && (const uchar *)(STR) != base \
+ && (LEN) <= 2) \
+ { \
+ memcpy (temp_buffer + temp_buffer_len, \
+ (const uchar *)(STR), (LEN)); \
+ temp_buffer_len += (LEN); \
+ } \
} while (0);
+ orig_base = base;
+ ++cur;
+ raw_prefix_start = cur - base;
+ for (;;)
+ {
cppchar_t c;
/* If we previously performed any trigraph or line splicing
- transformations, undo them within the body of the raw string. */
+ transformations, undo them in between the opening and closing
+ double quote. */
while (note->pos < cur)
++note;
for (; note->pos == cur; ++note)
@@ -1506,23 +1478,13 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
++note;
goto after_backslash;
}
- /* The ) from ??) could be part of the suffix. */
- else if (type == ')'
- && strncmp ((const char *) cur+1,
- (const char *) raw_prefix,
- raw_prefix_len) == 0
- && cur[raw_prefix_len+1] == '"')
- {
- BUF_APPEND (")", 1);
- base++;
- cur += raw_prefix_len + 2;
- goto break_outer_loop;
- }
else
{
/* Skip the replacement character. */
base = ++cur;
BUF_APPEND (&type, 1);
+ c = type;
+ goto check_c;
}
}
else
@@ -1531,14 +1493,98 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
}
}
c = *cur++;
+ if (__builtin_expect (temp_buffer_len < 17, 0))
+ temp_buffer[temp_buffer_len++] = c;
- if (c == ')'
- && strncmp ((const char *) cur, (const char *) raw_prefix,
- raw_prefix_len) == 0
- && cur[raw_prefix_len] == '"')
+ check_c:
+ if (phase == RAW_STR_PREFIX)
{
- cur += raw_prefix_len + 1;
- break;
+ while (raw_prefix_len < temp_buffer_len)
+ {
+ raw_prefix[raw_prefix_len] = temp_buffer[raw_prefix_len];
+ switch (raw_prefix[raw_prefix_len])
+ {
+ case ' ': case '(': case ')': case '\\': case '\t':
+ case '\v': case '\f': case '\n': default:
+ break;
+ /* Basic source charset except the above chars. */
+ case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+ case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+ case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+ case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+ case 'y': case 'z':
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+ case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+ case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+ case 'Y': case 'Z':
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9':
+ case '_': case '{': case '}': case '#': case '[': case ']':
+ case '<': case '>': case '%': case ':': case ';': case '.':
+ case '?': case '*': case '+': case '-': case '/': case '^':
+ case '&': case '|': case '~': case '!': case '=': case ',':
+ case '"': case '\'':
+ if (raw_prefix_len < 16)
+ {
+ raw_prefix_len++;
+ continue;
+ }
+ break;
+ }
+
+ if (raw_prefix[raw_prefix_len] != '(')
+ {
+ int col = CPP_BUF_COLUMN (pfile->buffer, cur) + 1;
+ if (raw_prefix_len == 16)
+ cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc,
+ col, "raw string delimiter longer "
+ "than 16 characters");
+ else if (raw_prefix[raw_prefix_len] == '\n')
+ cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc,
+ col, "invalid new-line in raw "
+ "string delimiter");
+ else
+ cpp_error_with_line (pfile, CPP_DL_ERROR, token->src_loc,
+ col, "invalid character '%c' in "
+ "raw string delimiter",
+ (int) raw_prefix[raw_prefix_len]);
+ pfile->buffer->cur = orig_base + raw_prefix_start - 1;
+ create_literal (pfile, token, orig_base,
+ raw_prefix_start - 1, CPP_OTHER);
+ if (first_buff)
+ _cpp_release_buff (pfile, first_buff);
+ return;
+ }
+ raw_prefix[raw_prefix_len] = '"';
+ phase = RAW_STR;
+ /* Nothing should be appended to temp_buffer during
+ RAW_STR phase. */
+ temp_buffer_len = 17;
+ break;
+ }
+ continue;
+ }
+ else if (phase == RAW_STR_SUFFIX)
+ {
+ while (raw_suffix_len <= raw_prefix_len
+ && raw_suffix_len < temp_buffer_len
+ && temp_buffer[raw_suffix_len] == raw_prefix[raw_suffix_len])
+ raw_suffix_len++;
+ if (raw_suffix_len > raw_prefix_len)
+ break;
+ if (raw_suffix_len == temp_buffer_len)
+ continue;
+ phase = RAW_STR;
+ /* Nothing should be appended to temp_buffer during
+ RAW_STR phase. */
+ temp_buffer_len = 17;
+ }
+ if (c == ')')
+ {
+ phase = RAW_STR_SUFFIX;
+ raw_suffix_len = 0;
+ temp_buffer_len = 0;
}
else if (c == '\n')
{
@@ -1579,7 +1625,6 @@ lex_raw_string (cpp_reader *pfile, cpp_token *token, const uchar *base,
note = &pfile->buffer->notes[pfile->buffer->cur_note];
}
}
- break_outer_loop:
if (CPP_OPTION (pfile, user_literals))
{