OSDN Git Service

PR c++/25294
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 31 Dec 2005 23:45:58 +0000 (23:45 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 31 Dec 2005 23:45:58 +0000 (23:45 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@109201 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/parse/pragma3.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/pragma-pack-3.c [new file with mode: 0644]
libcpp/ChangeLog
libcpp/directives.c

index a3accaf..e953e00 100644 (file)
@@ -1,3 +1,9 @@
+2006-01-01  Jakub Jelinek  <jakub@redhat.com>
+
+       PR c++/25294
+       * gcc.dg/pragma-pack-3.c: New test.
+       * g++.dg/parse/pragma3.C: New test.
+
 2005-12-30  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>
 
        PR middle-end/24827
diff --git a/gcc/testsuite/g++.dg/parse/pragma3.C b/gcc/testsuite/g++.dg/parse/pragma3.C
new file mode 100644 (file)
index 0000000..36d7a8c
--- /dev/null
@@ -0,0 +1,26 @@
+// PR c++/25294
+// { dg-do run }
+
+extern "C" void abort (void);
+
+struct S
+{
+  char a[3];
+#pragma pack(1) /* A block comment
+                  that ends on the next line.  */
+  struct T
+  {
+    char b;
+    int c;
+  } d;
+#pragma pack /*/ */ () // C++ comment
+  int e;
+} s;
+
+int
+main ()
+{
+  if (sizeof (int) == 4 && sizeof (s) != 12)
+    abort ();
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pragma-pack-3.c b/gcc/testsuite/gcc.dg/pragma-pack-3.c
new file mode 100644 (file)
index 0000000..e276bd0
--- /dev/null
@@ -0,0 +1,27 @@
+/* PR c++/25294 */
+/* { dg-options "-std=gnu99" } */
+/* { dg-do run } */
+
+extern void abort (void);
+
+struct S
+{
+  char a[3];
+#pragma pack(1) /* A block comment
+                  that ends on the next line.  */
+  struct T
+  {
+    char b;
+    int c;
+  } d;
+#pragma pack /*/ */ () // C++ comment
+  int e;
+} s;
+
+int
+main ()
+{
+  if (sizeof (int) == 4 && sizeof (s) != 12)
+    abort ();
+  return 0;
+}
index e21ea6d..b2f0c9a 100644 (file)
@@ -1,3 +1,10 @@
+2006-01-01  Jakub Jelinek  <jakub@redhat.com>
+
+       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.
+
 2005-12-22  Volker Reichelt  <reichelt@igpm.rwth-aachen.de>
 
        PR c++/23333
index 7159f07..2de65fb 100644 (file)
@@ -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;