diff options
author | Jakub Jelinek <jakub@redhat.com> | 2006-01-01 00:45:58 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2006-01-01 00:45:58 +0100 |
commit | d09e893f10b6bb8bea9eafce9fd3f008f9cb5027 (patch) | |
tree | ce308977cf7e39a7110238524fc15f921883e86a /libcpp/directives.c | |
parent | 2984956b2f436d4be9d85777a4d4ba1ea00a208a (diff) | |
download | gcc-d09e893f10b6bb8bea9eafce9fd3f008f9cb5027.zip gcc-d09e893f10b6bb8bea9eafce9fd3f008f9cb5027.tar.gz gcc-d09e893f10b6bb8bea9eafce9fd3f008f9cb5027.tar.bz2 |
re PR c++/25294 (Bogus "unterminated comment" error from #pragma comment)
PR c++/25294
* directives.c (do_pragma): If pragma line ends with multi-line
block comment, end the saved deferred pragma string before that
comment. Handle embedded '\0' chars on the pragma line.
* gcc.dg/pragma-pack-3.c: New test.
* g++.dg/parse/pragma3.C: New test.
From-SVN: r109201
Diffstat (limited to 'libcpp/directives.c')
-rw-r--r-- | libcpp/directives.c | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/libcpp/directives.c b/libcpp/directives.c index 7159f07..2de65fb 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -1,6 +1,7 @@ /* CPP Library. (Directive handling.) Copyright (C) 1986, 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 + Free Software Foundation, Inc. Contributed by Per Bothner, 1994-95. Based on CCCP program by Paul Rubin, June 1986 Adapted to ANSI C, Richard Stallman, Jan 1987 @@ -1280,15 +1281,59 @@ do_pragma (cpp_reader *pfile) /* Squirrel away the pragma text. Pragmas are newline-terminated. */ const uchar *line_end; - uchar *s; + uchar *s, c, cc; cpp_string body; cpp_token *ptok; - line_end = ustrchr (line_start, '\n'); + for (line_end = line_start; (c = *line_end) != '\n'; line_end++) + if (c == '"' || c == '\'') + { + /* Skip over string literal. */ + do + { + cc = *++line_end; + if (cc == '\\' && line_end[1] != '\n') + line_end++; + else if (cc == '\n') + { + line_end--; + break; + } + } + while (cc != c); + } + else if (c == '/') + { + if (line_end[1] == '*') + { + /* Skip over C block comment, unless it is multi-line. + When encountering multi-line block comment, terminate + the pragma token right before that block comment. */ + const uchar *le = line_end + 2; + while (*le != '\n') + if (*le++ == '*' && *le == '/') + { + line_end = le; + break; + } + if (line_end < le) + break; + } + else if (line_end[1] == '/' + && (CPP_OPTION (pfile, cplusplus_comments) + || cpp_in_system_header (pfile))) + { + line_end += 2; + while (*line_end != '\n') + line_end++; + break; + } + } body.len = (line_end - line_start) + 1; s = _cpp_unaligned_alloc (pfile, body.len + 1); - memcpy (s, line_start, body.len); + memcpy (s, line_start, body.len - 1); + s[body.len - 1] = '\n'; s[body.len] = '\0'; body.text = s; |