diff mbox

[pph] Add support for line table streaming with includes (issue4908051)

Message ID 20110819000816.11B1F1C35C9@gchare.mtv.corp.google.com
State New
Headers show

Commit Message

Gab Charette Aug. 19, 2011, 12:08 a.m. UTC
Before this patch the line_table was not identical to the non-pph line_table.

The child references patch just recently made this worst.

We had a design problem where we need to load the line_table entries for the main file before the child's entries. However we need to load the bindings of the child before the parent's...

So the only solution is to do both in parallel, using the linemap output to write a reference to an include to be loaded recursively during the streaming in of the line_table of the parent.

This also allows us to store less information per pph! Only the line_table entries specifically defined in a pph are needed, referenced pph headers' entries are skipped and injected recursively when streaming in!

One important change is that it was easier to stream in the line_table and includes first, before replaying the identifiers, is that a problem in the type of syntax we wanted to support?? (i.e. in this model we can't rely on tokens defined in the main file to affect things defined in its pph children).

The line_table is now almost perfectly identical in pph and non-pph (I scanned it in the debugger after parsing p4eabi.cc which is the hardest mix of line_table entries I found). The only reason it still differs is that we load some included headers twice, where as the non-pph skips it the second time, this is a known current issue so I didn't bother working around it in the line_table streaming implementation.

This fixes the asm diff in p4eabi.cc
It also affects the line number of some expected failures (I think those are now the "correct" line numbers for the builtins that we are failing on).

Tested on x64 with bootstrap and pph regression testing.

Cheers,
Gab

2011-08-18  Gabriel Charette  <gchare@google.com>

	gcc/cp/ChangeLog.pph
	* pph-streamer-in.c (pph_in_includes): Remove.
	(pph_in_linetable_marker): New.
	(pph_in_line_table_and_includes): Renamed from
	pph_in_and_merge_line_table.
	Now handles line_table and includes input in parallel.
	Now returns source_location corresponding to line 1 / col 0
	of the header currently loaded as pph.
	(pph_read_file_1): Read line_table and includes before replaying
	tokens. Use location returned by pph_in_line_table_and_includes
	as forced token location for replayed tokens.
	* pph-streamer-out.c (pph_out_includes): Remove.
	(pph_out_linetable_marker): New.
	(pph_filename_eq_ignoring_path): New.
	(pph_get_next_include): New.
	(pph_out_line_table_and_includes): Renamed from pph_out_line_table.
	Now handles output of both the line_table and includes references
	in parallel.
	(pph_write_file): Write out line_table and includes before
	identifiers.
	* pph-streamer.h (enum pph_linetable_marker): New.
	* pph.c (pph_include_handler): Add hack to mimic
	line_table->highest_location behaviour in _cpp_stack_include used
	by the non-pph compiler.

	gcc/testsuite/ChangeLog.pph
	* g++.dg/pph/p4eabi1.cc: Remove asm xdiff.
	* g++.dg/pph/x4keyed.cc: Changed line info for expected failure.
	* g++.dg/pph/x7rtti.cc: Changed line info for expected failures.


--
This patch is available for review at http://codereview.appspot.com/4908051
diff mbox

Patch

diff --git a/gcc/cp/pph-streamer-in.c b/gcc/cp/pph-streamer-in.c
index 4666ace..a3a3566 100644
--- a/gcc/cp/pph-streamer-in.c
+++ b/gcc/cp/pph-streamer-in.c
@@ -1281,27 +1281,6 @@  pph_in_symtab (pph_stream *stream)
 }
 
 
-/* Read all the images included by STREAM.  */
-
-static void
-pph_in_includes (pph_stream *stream)
-{
-  unsigned i, num;
-
-  pph_reading_includes++;
-
-  num = pph_in_uint (stream);
-  for (i = 0; i < num; i++)
-    {
-      const char *include_name = pph_in_string (stream);
-      pph_stream *include = pph_read_file (include_name);
-      pph_add_include (include, false);
-    }
-
-  pph_reading_includes--;
-}
-
-
 /* Read a linenum_type from STREAM.  */
 
 static inline linenum_type
@@ -1320,6 +1299,20 @@  pph_in_source_location (pph_stream *stream)
 }
 
 
+/* Read a line table marker from STREAM.  */
+
+static inline enum pph_linetable_marker
+pph_in_linetable_marker (pph_stream *stream)
+{
+  enum pph_linetable_marker m =
+    (enum pph_linetable_marker) pph_in_uchar (stream);
+  gcc_assert (m == PPH_LINETABLE_ENTRY
+	      || m == PPH_LINETABLE_REFERENCE
+	      || m == PPH_LINETABLE_END);
+  return m;
+}
+
+
 /* Read a line_map from STREAM into LM.  */
 
 static void
@@ -1343,47 +1336,102 @@  pph_in_line_map (pph_stream *stream, struct line_map *lm)
 }
 
 
-/* Read the line_table from STREAM and merge it in LINETAB.  */
+/* Read the line_table from STREAM and merge it in LINETAB.  At the same time
+   load includes in the order they were originally included by loading them at
+   the point they were referenced in the line_table.
 
-static void
-pph_in_and_merge_line_table (pph_stream *stream, struct line_maps *linetab)
+   Returns the source_location of line 1 / col 0 for this include.
+
+   FIXME pph: The line_table is now identical to the non-pph line_table, the
+   only problem is that we load line_table entries twice for headers that are
+   re-included and are #ifdef guarded; thus shouldn't be replayed.  This is
+   a known current issue, so I didn't bother working around it here for now.  */
+
+static source_location
+pph_in_line_table_and_includes (pph_stream *stream, struct line_maps *linetab)
 {
-  unsigned int ix, pph_used, old_depth;
+  unsigned int old_depth;
+  bool first;
+  int includer_ix = -1;
+  unsigned int used_before = linetab->used;
   int entries_offset = linetab->used - PPH_NUM_IGNORED_LINE_TABLE_ENTRIES;
+  enum pph_linetable_marker next_lt_marker = pph_in_linetable_marker (stream);
 
-  pph_used = pph_in_uint (stream);
+  pph_reading_includes++;
 
-  for (ix = 0; ix < pph_used; ix++, linetab->used++)
+  for (first = true; next_lt_marker != PPH_LINETABLE_END;
+       next_lt_marker = pph_in_linetable_marker (stream))
     {
-      struct line_map *lm;
+      if (next_lt_marker == PPH_LINETABLE_REFERENCE)
+	{
+	  int old_loc_offset;
+	  const char *include_name = pph_in_string (stream);
+	  source_location prev_start_loc = pph_in_source_location (stream);
+	  pph_stream *include;
+
+	  gcc_assert (!first);
+
+	  linetab->highest_location = (prev_start_loc - 1) + pph_loc_offset;
+
+	  old_loc_offset = pph_loc_offset;
 
-      linemap_ensure_extra_space_available (linetab);
+	  include = pph_read_file (include_name);
+	  pph_add_include (include, false);
 
-      lm = &linetab->maps[linetab->used];
+	  pph_loc_offset = old_loc_offset;
+	}
+      else
+	{
+	  struct line_map *lm;
 
-      pph_in_line_map (stream, lm);
+	  linemap_ensure_extra_space_available (linetab);
 
-      if (ix == 0)
-        {
-          pph_loc_offset = (linetab->highest_location + 1) - lm->start_location;
+	  lm = &linetab->maps[linetab->used];
 
-          /* When parsing the pph the header itself wasn't included by anything,
-             now it's included by the C file we are currently compiling.  */
-          gcc_assert(lm->included_from == -1);
-          lm->included_from = linetab->used - 1;
-        }
+	  pph_in_line_map (stream, lm);
 
-      /* For the other entries in the pph's line_table which were included_from
-         another entry, reflect their included_from to the new position of the
-         entry which they were included from.  */
-      else if (lm->included_from != -1)
-        lm->included_from += entries_offset;
+	  if (first)
+	    {
+	      first = false;
+
+	      pph_loc_offset = (linetab->highest_location + 1)
+		               - lm->start_location;
 
-      gcc_assert (lm->included_from < (int) linetab->used);
+	      includer_ix = linetab->used - 1;
 
-      lm->start_location += pph_loc_offset;
+	      gcc_assert(lm->included_from == -1);
+	    }
+
+	  gcc_assert (includer_ix != -1);
+
+	  /* When parsing the pph: the header itself wasn't included by
+	    anything, now it's included by the file just before it in
+	    the current include tree.  */
+	  if (lm->included_from == -1)
+	    lm->included_from = includer_ix;
+	  /* For the other entries in the pph's line_table which were included
+	     from another entry, reflect their included_from to the new position
+	     of the entry which they were included from.  */
+	  else
+	    lm->included_from += entries_offset;
+
+	  gcc_assert (lm->included_from < (int) linetab->used);
+
+	  lm->start_location += pph_loc_offset;
+
+	  linetab->used++;
+	}
     }
 
+  pph_reading_includes--;
+
+  {
+    /* FIXME pph: streaming this int is only needed for assertion, should be
+       wrapped in a #ifdef and only enabled if asserts are on.  */
+    unsigned int expected_in = pph_in_uint (stream);
+    gcc_assert (linetab->used - used_before == expected_in);
+  }
+
   linetab->highest_location = pph_loc_offset + pph_in_uint (stream);
   linetab->highest_line = pph_loc_offset + pph_in_uint (stream);
 
@@ -1399,6 +1447,8 @@  pph_in_and_merge_line_table (pph_stream *stream, struct line_maps *linetab)
   old_depth = linetab->depth++;
   linemap_add (linetab, LC_LEAVE, 0, NULL, 0);
   gcc_assert (linetab->depth == old_depth);
+
+  return linetab->maps[used_before].start_location;
 }
 
 
@@ -1419,8 +1469,10 @@  pph_read_file_1 (pph_stream *stream)
   if (flag_pph_debug >= 1)
     fprintf (pph_logfile, "PPH: Reading %s\n", stream->name);
 
-  /* Read all the images included by STREAM.  */
-  pph_in_includes (stream);
+  /* Read in STREAM's line table and merge it in the current line table.
+     At the same time, read in includes in the order they were originally
+     read.  */
+  cpp_token_replay_loc = pph_in_line_table_and_includes (stream, line_table);
 
   /* Read all the identifiers and pre-processor symbols in the global
      namespace.  */
@@ -1433,16 +1485,12 @@  pph_read_file_1 (pph_stream *stream)
                              bad_use->before_str, bad_use->after_str);
 
   /* Re-instantiate all the pre-processor symbols defined by STREAM.  Force
-     their source_location to column 0 of the line the include occured on,
-     this avoids shifting all of the line_table's location as we would by adding
-     locations which wouldn't be there in the non-pph compile; thus working
-     towards an identical line_table in pph and non-pph.  */
-  cpp_token_replay_loc = linemap_position_for_column (line_table, 0);
+     their source_location to line 1 / column 0 of the file they were included
+     in.  This avoids shifting all of the line_table's locations as we would by
+     adding locations which wouldn't be there in the non-pph compile; thus
+     working towards an identical line_table in pph and non-pph.  */
   cpp_lt_replay (parse_in, &idents_used, &cpp_token_replay_loc);
 
-  /* Read in STREAM's line table and merge it in the current line table.  */
-  pph_in_and_merge_line_table (stream, line_table);
-
   /* Read the bindings from STREAM and merge them with the current bindings.  */
   pph_in_scope_chain (stream);
 
diff --git a/gcc/cp/pph-streamer-out.c b/gcc/cp/pph-streamer-out.c
index 1b84cc3..d744570 100644
--- a/gcc/cp/pph-streamer-out.c
+++ b/gcc/cp/pph-streamer-out.c
@@ -1142,21 +1142,6 @@  pph_out_symtab (pph_stream *stream)
 }
 
 
-/* Emit the list of all the PPH files included by STREAM.  */
-
-static void
-pph_out_includes (pph_stream *stream)
-{
-  unsigned i;
-  pph_stream *include;
-
-  pph_out_uint (stream, VEC_length (pph_stream_ptr,
-	                            stream->encoder.w.includes));
-  FOR_EACH_VEC_ELT (pph_stream_ptr, stream->encoder.w.includes, i, include)
-    pph_out_string (stream, include->name);
-}
-
-
 /* Emit linenum_type LN to STREAM.  */
 
 static inline void
@@ -1175,6 +1160,16 @@  pph_out_source_location (pph_stream *stream, source_location sl)
 }
 
 
+/* Emit line table MARKER to STREAM.  */
+
+static inline void
+pph_out_linetable_marker (pph_stream *stream, enum pph_linetable_marker marker)
+{
+  gcc_assert (marker == (enum pph_linetable_marker)(unsigned char) marker);
+  pph_out_uchar (stream, marker);
+}
+
+
 /* Emit all information contained in LM to STREAM.  */
 
 static void
@@ -1195,22 +1190,82 @@  pph_out_line_map (pph_stream *stream, struct line_map *lm)
 }
 
 
-/* Emit the required line_map entry and some properties in LINETAB to STREAM,
-   ignoring builtin and command-line entries.  */
+/* Compare filenames of a header and it's potentially corresponding pph file,
+   stripping the path passed in and the extension. Returns true if HEADER_PATH
+   and PPH_PATH end with the same filename. We expect HEADER_PATH to end in .h
+   and PPH_PATH to end in .pph.
+
+   FIXME pph: We should not need to do this if we handled include paths
+   correctly, but for now the linemap holds full paths and the stream's includes
+   list only holds the include name.  Also, the stream's includes hold pph
+   filenames where as the line_table as header filenames.  */
+
+static bool
+pph_filename_eq_ignoring_path (const char *header_path, const char *pph_path)
+{
+  const char *header_name = header_path, *pph_name = pph_path;
+
+  /* Strip the path, only keeping the filenames.  */
+  for (; *header_path; header_path++)
+    if (*header_path == '/')
+      header_name = header_path + 1;
+
+  for (; *pph_path; pph_path++)
+    if (*pph_path == '/')
+      pph_name = pph_path + 1;
+
+  gcc_assert (*header_name && *pph_name);
+
+  /* Validate that filenames are equal ignoring the extension.  */
+  do {
+    if (*header_name != *pph_name)
+      return false;
+
+    header_name++;
+    pph_name++;
+  } while (*header_name != '.');
+
+  /* Validate that the remaining extensions are as we expect.  */
+  gcc_assert (strcmp (header_name, ".h") == 0);
+  gcc_assert (strcmp (pph_name, ".pph") == 0);
+
+  return true;
+}
+
+
+/* Return the *NEXT_INCLUDE_IX'th pph_stream in STREAM's list of includes.
+   Returns NULL if we have read all includes.  */
+
+static inline pph_stream *
+pph_get_next_include (pph_stream *stream, unsigned int *next_incl_ix)
+{
+  if (*next_incl_ix < VEC_length (pph_stream_ptr, stream->encoder.w.includes))
+    return VEC_index (pph_stream_ptr, stream->encoder.w.includes,
+	              (*next_incl_ix)++);
+  else
+    return NULL;
+}
+
+
+/* Emit the required line_map entry (those directly related to this include)
+   and some properties in LINETAB to STREAM, ignoring builtin and command-line
+   entries.  We will write references to our direct includes children and skip
+   their actual line_map entries (unless they are non-pph children in which case
+   we have to write out their line_map entries as well).  We assume
+   stream->encoder.w.includes contains the pph headers included in the same
+   order they are seen in the line_table.  */
 
 static void
-pph_out_line_table (pph_stream *stream, struct line_maps *linetab)
+pph_out_line_table_and_includes (pph_stream *stream, struct line_maps *linetab)
 {
-  unsigned int ix;
+  unsigned int ix, next_incl_ix = 0;
+  pph_stream *current_include;
 
   /* Any #include should have been fully parsed and exited at this point.  */
   gcc_assert (linetab->depth == 0);
 
-  /* Only output used as the number of line_map entries we actually output.  */
-  pph_out_uint (stream, linetab->used - PPH_NUM_IGNORED_LINE_TABLE_ENTRIES);
+  current_include = pph_get_next_include (stream, &next_incl_ix);
 
-  /* Output all the non-ignored line_map entries.
-     Special casing the first one.  */
   for (ix = PPH_NUM_IGNORED_LINE_TABLE_ENTRIES; ix < linetab->used; ix++)
     {
       struct line_map *lm = &linetab->maps[ix];
@@ -1226,12 +1281,58 @@  pph_out_line_table (pph_stream *stream, struct line_maps *linetab)
           lm->reason = LC_ENTER;
         }
 
-      pph_out_line_map (stream, lm);
-
+      /* If this is an entry from a pph header, only output reference.  */
+      if (current_include != NULL
+	  && pph_filename_eq_ignoring_path (lm->to_file, current_include->name))
+	{
+	  int includer_level;
+
+	  gcc_assert (lm->reason == LC_ENTER);
+	  gcc_assert (lm->included_from != -1);
+
+	  pph_out_linetable_marker (stream, PPH_LINETABLE_REFERENCE);
+	  pph_out_string (stream, current_include->name);
+
+	  /* We also need to output the start_location to simulate the correct
+	      highest_location on the way in.  */
+	  pph_out_source_location (stream, lm->start_location);
+
+	  /* Potentially lm could be included from a header other then the main
+	      one if a textual include includes a pph header (i.e. we can't
+	      simply rely on going back to included_from == -1).  */
+	  includer_level = INCLUDED_FROM (linetab, lm)->included_from;
+
+	  /* Skip all other linemap entries up to and including the LC_LEAVE
+	      from the referenced header back to the one including it.  */
+	  while (linetab->maps[++ix].included_from != includer_level)
+	    /* We should always leave this loop before the end of the
+		current line_table entries.  */
+	    gcc_assert (ix < linetab->used);
+
+	  current_include = pph_get_next_include (stream, &next_incl_ix);
+	}
+      else
+	{
+	  pph_out_linetable_marker (stream, PPH_LINETABLE_ENTRY);
+	  pph_out_line_map (stream, lm);
+	}
+
+      /* Restore changes made to first entry above if needed.  */
       if (ix == PPH_NUM_IGNORED_LINE_TABLE_ENTRIES)
-        lm->reason = LC_RENAME;
+	lm->reason = LC_RENAME;
     }
 
+  pph_out_linetable_marker (stream, PPH_LINETABLE_END);
+
+  /* FIXME pph: only needed for assertion on the way in, should be wrapped in a
+     #ifdef and only enabled if asserts are on.  */
+  pph_out_uint (stream, linetab->used - PPH_NUM_IGNORED_LINE_TABLE_ENTRIES);
+
+  /* Every pph header included should have been seen and skipped in the
+     line_table streaming above.  */
+  gcc_assert (next_incl_ix == VEC_length (pph_stream_ptr,
+					  stream->encoder.w.includes));
+
   pph_out_source_location (stream, linetab->highest_location);
   pph_out_source_location (stream, linetab->highest_line);
 
@@ -1248,18 +1349,14 @@  pph_write_file (pph_stream *stream)
   if (flag_pph_debug >= 1)
     fprintf (pph_logfile, "PPH: Writing %s\n", pph_out_file);
 
-  /* Emit the list of PPH files included by STREAM.  These files will
-     be read and instantiated before any of the content in STREAM.  */
-  pph_out_includes (stream);
+  /* Emit the line table entries and references to our direct includes.   */
+  pph_out_line_table_and_includes (stream, line_table);
 
   /* Emit all the identifiers and pre-processor symbols in the global
      namespace.  */
   idents_used = cpp_lt_capture (parse_in);
   pph_out_identifiers (stream, &idents_used);
 
-  /* Emit the line table entries.  */
-  pph_out_line_table (stream, line_table);
-
   /* Emit the bindings for the global namespace.  */
   pph_out_scope_chain (stream);
   if (flag_pph_dump_tree)
diff --git a/gcc/cp/pph-streamer.h b/gcc/cp/pph-streamer.h
index 7842f1f..4a1f9eb 100644
--- a/gcc/cp/pph-streamer.h
+++ b/gcc/cp/pph-streamer.h
@@ -63,6 +63,21 @@  enum pph_symtab_marker {
   PPH_SYMTAB_DECL
 };
 
+/* Line table markers. We only stream line table entries from the parent header
+   file, other entries are referred to by the name of the file which is then
+   loaded as an include at the correct point in time.  */
+enum pph_linetable_marker {
+
+  /* A regular line_map entry in the line_table.  */
+  PPH_LINETABLE_ENTRY = 0x01,
+
+  /* A reference to another header to be loaded at this point.  */
+  PPH_LINETABLE_REFERENCE,
+
+  /* Marks the end of the line_map entries.  */
+  PPH_LINETABLE_END
+};
+
 /* Number of sections in a PPH file.  FIXME, currently only one section
    is supported.  To add more, it will also be necessary to handle
    section names in pph_get_section_data and pph_free_section_data.  */
diff --git a/gcc/cp/pph.c b/gcc/cp/pph.c
index 86aacbc..74f48fc 100644
--- a/gcc/cp/pph.c
+++ b/gcc/cp/pph.c
@@ -119,6 +119,10 @@  pph_include_handler (cpp_reader *reader,
   pph_file = query_pph_include_map (name);
   if (pph_file != NULL && !cpp_included_before (reader, name, input_location))
     {
+      /* Hack. We do this to mimic what the non-pph compiler does in
+	_cpp_stack_include as our goal is to have identical line_tables.  */
+      line_table->highest_location--;
+
       pph_read_file (pph_file);
       read_text_file_p = false;
     }
diff --git a/gcc/testsuite/g++.dg/pph/p4eabi1.cc b/gcc/testsuite/g++.dg/pph/p4eabi1.cc
index c7aa1b0..4bf19e6 100644
--- a/gcc/testsuite/g++.dg/pph/p4eabi1.cc
+++ b/gcc/testsuite/g++.dg/pph/p4eabi1.cc
@@ -1,5 +1,4 @@ 
 // { dg-options "-w -fpermissive" }
-// pph asm xdiff 48471
 
 #include "p4eabi1.h"
 
diff --git a/gcc/testsuite/g++.dg/pph/x4keyed.cc b/gcc/testsuite/g++.dg/pph/x4keyed.cc
index ef88e7c..68b30c1 100644
--- a/gcc/testsuite/g++.dg/pph/x4keyed.cc
+++ b/gcc/testsuite/g++.dg/pph/x4keyed.cc
@@ -1,5 +1,5 @@ 
 // { dg-xfail-if "BOGUS" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "x0keyed2.h:11:1: error: redefinition of 'const char _ZTS5keyed ..'" "" { xfail *-*-* } 0 }
+// { dg-bogus "x4keyed.cc:13:1: error: redefinition of 'const char _ZTS5keyed ..'" "" { xfail *-*-* } 0 }
 
 #include "x0keyed1.h"
 #include "x0keyed2.h"
diff --git a/gcc/testsuite/g++.dg/pph/x7rtti.cc b/gcc/testsuite/g++.dg/pph/x7rtti.cc
index 8a6c981..297ebe2 100644
--- a/gcc/testsuite/g++.dg/pph/x7rtti.cc
+++ b/gcc/testsuite/g++.dg/pph/x7rtti.cc
@@ -1,17 +1,17 @@ 
 // { dg-xfail-if "BOGUS" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "x5rtti1.h:13:0: warning: .__STDC_IEC_559_COMPLEX__. redefined .enabled by default." "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti1.h:13:0: warning: .__STDC_ISO_10646__. redefined .enabled by default." "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti1.h:13:0: warning: .__STDC_IEC_559__. redefined .enabled by default." "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:15:32: error: no match for .operator" "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:15:54: error: no match for .operator" "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:16:32: error: no match for .operator" "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:16:54: error: no match for .operator" "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:17:32: error: no match for .operator" "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:17:54: error: no match for .operator" "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:18:32: error: no match for .operator" "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:18:54: error: no match for .operator" "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:19:1: error: redefinition of .const char _ZTS15non_polymorphic ..." "" { xfail *-*-* } 0 }
-// { dg-bogus "x5rtti2.h:19:1: error: redefinition of .const char _ZTS11polymorphic ..." "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:21:0: warning: .__STDC_IEC_559_COMPLEX__. redefined .enabled by default." "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:21:0: warning: .__STDC_ISO_10646__. redefined .enabled by default." "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:21:0: warning: .__STDC_IEC_559__. redefined .enabled by default." "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:24:32: error: no match for .operator" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:24:54: error: no match for .operator" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:25:32: error: no match for .operator" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:25:54: error: no match for .operator" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:26:32: error: no match for .operator" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:26:54: error: no match for .operator" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:27:32: error: no match for .operator" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:27:54: error: no match for .operator" "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:28:1: error: redefinition of .const char _ZTS15non_polymorphic ..." "" { xfail *-*-* } 0 }
+// { dg-bogus "x7rtti.cc:28:1: error: redefinition of .const char _ZTS11polymorphic ..." "" { xfail *-*-* } 0 }
 
 
 //FIXME We should make this a run test.