[gcc] 4.8.0-0.13

Jakub Jelinek jakub at fedoraproject.org
Fri Feb 15 19:18:15 UTC 2013


commit 225104138d78e81361e456aee14ba1cb74410475
Author: Jakub Jelinek <jakub at redhat.com>
Date:   Fri Feb 15 20:17:57 2013 +0100

    4.8.0-0.13

 .gitignore               |    1 +
 gcc.spec                 |   23 ++-
 gcc48-asan-fix.patch     |  211 ++++++++++++++++--
 gcc48-asan-speedup.patch |  535 ++++++++++++++++++++++++++++++++++++++++++++++
 gcc48-pr54117.patch      |  425 ++++++++++++++++---------------------
 gcc48-pr56111.patch      |   97 ---------
 gcc48-pr56224.patch      |   81 -------
 sources                  |    2 +-
 8 files changed, 921 insertions(+), 454 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index cee0202..57f0aa9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -61,3 +61,4 @@
 /gcc-4.8.0-20130208.tar.bz2
 /gcc-4.8.0-20130211.tar.bz2
 /gcc-4.8.0-20130213.tar.bz2
+/gcc-4.8.0-20130215.tar.bz2
diff --git a/gcc.spec b/gcc.spec
index d99a626..bfab4b8 100644
--- a/gcc.spec
+++ b/gcc.spec
@@ -1,9 +1,9 @@
-%global DATE 20130213
-%global SVNREV 196031
+%global DATE 20130215
+%global SVNREV 196084
 %global gcc_version 4.8.0
 # Note, gcc_release must be integer, if you want to add suffixes to
 # %{release}, append them after %{gcc_release} on Release: line.
-%global gcc_release 0.12
+%global gcc_release 0.13
 %global _unpackaged_files_terminate_build 0
 %global multilib_64_archs sparc64 ppc64 s390x x86_64
 %ifarch %{ix86} x86_64 ia64 ppc ppc64 alpha
@@ -196,8 +196,7 @@ Patch12: gcc48-no-add-needed.patch
 Patch13: gcc48-pr55608.patch
 Patch14: gcc48-asan-fix.patch
 Patch15: gcc48-pr54117.patch
-Patch16: gcc48-pr56111.patch
-Patch17: gcc48-pr56224.patch
+Patch16: gcc48-asan-speedup.patch
 
 Patch1000: fastjar-0.97-segfault.patch
 Patch1001: fastjar-0.97-len1.patch
@@ -752,8 +751,7 @@ package or when debugging this package.
 %patch13 -p0 -b .pr55608~
 %patch14 -p0 -b .asan-fix~
 %patch15 -p0 -b .pr54117~
-%patch16 -p0 -b .pr56111~
-%patch17 -p0 -b .pr56224~
+%patch16 -p0 -b .asan-speedup~
 
 %if 0%{?_enable_debug_packages}
 cat > split-debuginfo.sh <<\EOF
@@ -2977,6 +2975,17 @@ fi
 %{_prefix}/libexec/gcc/%{gcc_target_platform}/%{gcc_version}/plugin
 
 %changelog
+* Fri Feb 15 2013 Jakub Jelinek <jakub at redhat.com> 4.8.0-0.13
+- updated from trunk
+  - PRs bootstrap/56327, c++/52026, c++/54922, c++/55003, c++/55220,
+	c++/55223, c++/55232, c++/55582, c++/55670, c++/55680, c++/56323,
+	c++/56343, fortran/53818, fortran/56224, fortran/56318,
+	libstdc++/56111, lto/50494, target/55431, target/55941,
+	testsuite/56138
+- asan fixes (PR sanitizer/56330)
+- asan speedup - use 0x7fff8000 shadow offset instead of 1LL << 44 on
+  x86_64
+
 * Wed Feb 13 2013 Jakub Jelinek <jakub at redhat.com> 4.8.0-0.12
 - updated from trunk
   - PRs c++/55710, c++/55879, c++/55993, c++/56135, c++/56155, c++/56285,
diff --git a/gcc48-asan-fix.patch b/gcc48-asan-fix.patch
index dfe6f2b..3bc7852 100644
--- a/gcc48-asan-fix.patch
+++ b/gcc48-asan-fix.patch
@@ -1,31 +1,196 @@
-2013-02-12  Dodji Seketeli  <dodji at redhat.com>
+2013-02-15  Jakub Jelinek  <jakub at redhat.com>
 
-	* asan.c (instrument_builtin_call):  Really put the length of the
-	second source argument into src1_len.
+	PR sanitizer/56330
+	* asan.c (get_mem_refs_of_builtin_call): Fix up indentation.
+	(instrument_mem_region_access): Create conditional even when
+	the start has been already instrumented.  Don't record
+	conditional instrumentation in the hash table.  Update *iter
+	after second build_check_stmt call.
+	(instrument_builtin_call): For consistency test != NULL_TREE
+	in all start checks.
 
-	* c-c++-common/asan/memcmp-2.c: New test.
+	* c-c++-common/asan/no-redundant-instrumentation-1.c: Pass
+	3 instead of sizeof (tab) - 1 as last argument.
+	* c-c++-common/asan/pr56330.c: New test.
 
---- gcc/asan.c
-+++ gcc/asan.c
-@@ -1764,7 +1764,7 @@ instrument_builtin_call (gimple_stmt_iterator *iter)
- 
-       if (get_mem_refs_of_builtin_call (call,
- 					&src0, &src0_len, &src0_is_store,
--					&src1, &src0_len, &src1_is_store,
-+					&src1, &src1_len, &src1_is_store,
- 					&dest, &dest_len, &dest_is_store,
- 					&dest_is_deref))
- 	{
---- gcc/testsuite/c-c++-common/asan/memcmp-2.c
-+++ gcc/testsuite/c-c++-common/asan/memcmp-2.c
-@@ -0,0 +1,10 @@
+--- gcc/asan.c.jj	2013-02-14 14:45:01.428038792 +0100
++++ gcc/asan.c	2013-02-15 09:37:18.614963383 +0100
+@@ -747,20 +747,17 @@ get_mem_refs_of_builtin_call (const gimp
+ 
+       got_reference_p = true;
+     }
+-    else
+-      {
+-	if (dest)
+-	  {
+-	    dst->start = dest;
+-	    dst->access_size = access_size;
+-	    *dst_len = NULL_TREE;
+-	    *dst_is_store = is_store;
+-	    *dest_is_deref = true;
+-	    got_reference_p = true;
+-	  }
+-      }
++  else if (dest)
++    {
++      dst->start = dest;
++      dst->access_size = access_size;
++      *dst_len = NULL_TREE;
++      *dst_is_store = is_store;
++      *dest_is_deref = true;
++      got_reference_p = true;
++    }
+ 
+-    return got_reference_p;
++  return got_reference_p;
+ }
+ 
+ /* Return true iff a given gimple statement has been instrumented.
+@@ -1535,8 +1532,15 @@ instrument_mem_region_access (tree base,
+ 
+   /* If the beginning of the memory region has already been
+      instrumented, do not instrument it.  */
+-  if (has_mem_ref_been_instrumented (base, 1))
+-    goto after_first_instrumentation;
++  bool start_instrumented = has_mem_ref_been_instrumented (base, 1);
++
++  /* If the end of the memory region has already been instrumented, do
++     not instrument it. */
++  tree end = asan_mem_ref_get_end (base, len);
++  bool end_instrumented = has_mem_ref_been_instrumented (end, 1);
++
++  if (start_instrumented && end_instrumented)
++    return;
+ 
+   if (!is_gimple_constant (len))
+     {
+@@ -1565,34 +1569,36 @@ instrument_mem_region_access (tree base,
+       gsi = gsi_start_bb (then_bb);
+     }
+ 
+-  /* Instrument the beginning of the memory region to be accessed,
+-     and arrange for the rest of the intrumentation code to be
+-     inserted in the then block *after* the current gsi.  */
+-  build_check_stmt (location, base, &gsi, /*before_p=*/true, is_store, 1);
+-
+-  if (then_bb)
+-    /* We are in the case where the length of the region is not
+-       constant; so instrumentation code is being generated in the
+-       'then block' of the 'if (len != 0) condition.  Let's arrange
+-       for the subsequent instrumentation statements to go in the
+-       'then block'.  */
+-    gsi = gsi_last_bb (then_bb);
+-  else
+-    *iter = gsi;
+-
+-  update_mem_ref_hash_table (base, 1);
++  if (!start_instrumented)
++    {
++      /* Instrument the beginning of the memory region to be accessed,
++	 and arrange for the rest of the intrumentation code to be
++	 inserted in the then block *after* the current gsi.  */
++      build_check_stmt (location, base, &gsi, /*before_p=*/true, is_store, 1);
++
++      if (then_bb)
++	/* We are in the case where the length of the region is not
++	   constant; so instrumentation code is being generated in the
++	   'then block' of the 'if (len != 0) condition.  Let's arrange
++	   for the subsequent instrumentation statements to go in the
++	   'then block'.  */
++	gsi = gsi_last_bb (then_bb);
++      else
++        {
++          *iter = gsi;
++	  /* Don't remember this access as instrumented, if length
++	     is unknown.  It might be zero and not being actually
++	     instrumented, so we can't rely on it being instrumented.  */
++          update_mem_ref_hash_table (base, 1);
++	}
++    }
+ 
+- after_first_instrumentation:
++  if (end_instrumented)
++    return;
+ 
+   /* We want to instrument the access at the end of the memory region,
+      which is at (base + len - 1).  */
+ 
+-  /* If the end of the memory region has already been instrumented, do
+-     not instrument it. */
+-  tree end = asan_mem_ref_get_end (base, len);
+-  if (has_mem_ref_been_instrumented (end, 1))
+-    return;
+-
+   /* offset = len - 1;  */
+   len = unshare_expr (len);
+   tree offset;
+@@ -1640,7 +1646,10 @@ instrument_mem_region_access (tree base,
+   gimple_set_location (region_end, location);
+   gimple_seq_add_stmt_without_update (&seq, region_end);
+   gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
+-  gsi_prev (&gsi);
++  if (!start_instrumented || then_bb == NULL)
++    gsi_prev (&gsi);
++  else
++    gsi = gsi_last_bb (then_bb);
+ 
+   /* _2 = _1 + offset;  */
+   region_end =
+@@ -1655,7 +1664,10 @@ instrument_mem_region_access (tree base,
+   build_check_stmt (location, gimple_assign_lhs (region_end),
+ 		    &gsi, /*before_p=*/false, is_store, 1);
+ 
+-  update_mem_ref_hash_table (end, 1);
++  if (then_bb == NULL)
++    update_mem_ref_hash_table (end, 1);
++
++  *iter = gsi_for_stmt (gsi_stmt (*iter));
+ }
+ 
+ /* Instrument the call (to the builtin strlen function) pointed to by
+@@ -1783,7 +1795,7 @@ instrument_builtin_call (gimple_stmt_ite
+ 	    }
+ 	  else if (src0_len || src1_len || dest_len)
+ 	    {
+-	      if (src0.start)
++	      if (src0.start != NULL_TREE)
+ 		instrument_mem_region_access (src0.start, src0_len,
+ 					      iter, loc, /*is_store=*/false);
+ 	      if (src1.start != NULL_TREE)
+--- gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c.jj	2013-02-13 11:53:41.000000000 +0100
++++ gcc/testsuite/c-c++-common/asan/no-redundant-instrumentation-1.c	2013-02-15 09:51:47.485080706 +0100
+@@ -45,7 +45,7 @@ test1 ()
+   /* There are 2 calls to __builtin___asan_report_store1 and 2 calls
+      to __builtin___asan_report_load1 to instrument the store to
+      (subset of) the memory region of tab.  */
+-  __builtin_memcpy (&tab[1], foo, sizeof (tab) - 1);
++  __builtin_memcpy (&tab[1], foo, 3);
+ 
+   /* This should not generate a __builtin___asan_report_load1 because
+      the reference to tab[1] has been already instrumented above.  */
+--- gcc/testsuite/c-c++-common/asan/pr56330.c.jj	2013-02-15 09:43:19.293845146 +0100
++++ gcc/testsuite/c-c++-common/asan/pr56330.c	2013-02-15 09:42:58.000000000 +0100
+@@ -0,0 +1,23 @@
++/* PR sanitizer/56330 */
 +/* { dg-do compile } */
 +
-+int
-+foo ()
++char e[200];
++
++struct S
 +{
-+  char s0[5] = {0};
-+  char s1[5] = {1};
++  char a[100];
++  char b[100];
++} s;
 +
-+  return __builtin_memcmp (s0, s1, 2);
++void
++foo (void)
++{
++  __builtin_memcmp (s.a, e, 100);
++  __builtin_memcmp (s.a, e, 200);
++}
++
++void
++bar (int *a, char *b, char *c)
++{
++  __builtin_memmove (c, b, a[b[0]]);
 +}
diff --git a/gcc48-asan-speedup.patch b/gcc48-asan-speedup.patch
new file mode 100644
index 0000000..b7a33f3
--- /dev/null
+++ b/gcc48-asan-speedup.patch
@@ -0,0 +1,535 @@
+2013-02-15  Jakub Jelinek  <jakub at redhat.com>
+
+	* config/i386/i386.c: Use 0x7fff8000 as asan_shadow_offset on x86_64
+	linux.
+
+	* All source files: Merge from upstream.
+
+--- gcc/config/i386/i386.c.jj	2013-02-13 17:04:34.000000000 +0100
++++ gcc/config/i386/i386.c	2013-02-15 13:27:47.674832994 +0100
+@@ -5436,7 +5436,8 @@ ix86_legitimate_combined_insn (rtx insn)
+ static unsigned HOST_WIDE_INT
+ ix86_asan_shadow_offset (void)
+ {
+-  return TARGET_LP64 ? (HOST_WIDE_INT_1 << 44)
++  return TARGET_LP64 ? (TARGET_MACHO ? (HOST_WIDE_INT_1 << 44)
++				     : HOST_WIDE_INT_C (0x7fff8000))
+ 		     : (HOST_WIDE_INT_1 << 29);
+ }
+ 
+--- libsanitizer/sanitizer_common/sanitizer_internal_defs.h.jj	2013-02-13 11:53:43.403336342 +0100
++++ libsanitizer/sanitizer_common/sanitizer_internal_defs.h	2013-02-15 13:24:17.410033137 +0100
+@@ -29,7 +29,7 @@
+ # define SANITIZER_SUPPORTS_WEAK_HOOKS 0
+ #endif
+ 
+-// __has_feature
++// GCC does not understand __has_feature
+ #if !defined(__has_feature)
+ # define __has_feature(x) 0
+ #endif
+--- libsanitizer/sanitizer_common/sanitizer_linux.cc.jj	2013-02-13 11:53:43.402336347 +0100
++++ libsanitizer/sanitizer_common/sanitizer_linux.cc	2013-02-15 13:24:17.410033137 +0100
+@@ -232,6 +232,21 @@ const char *GetEnv(const char *name) {
+   return 0;  // Not found.
+ }
+ 
++#ifdef __GLIBC__
++
++extern "C" {
++  extern void *__libc_stack_end;
++}
++
++static void GetArgsAndEnv(char ***argv, char ***envp) {
++  uptr *stack_end = (uptr *)__libc_stack_end;
++  int argc = *stack_end;
++  *argv = (char**)(stack_end + 1);
++  *envp = (char**)(stack_end + argc + 2);
++}
++
++#else  // __GLIBC__
++
+ static void ReadNullSepFileToArray(const char *path, char ***arr,
+                                    int arr_size) {
+   char *buff;
+@@ -251,11 +266,17 @@ static void ReadNullSepFileToArray(const
+   (*arr)[count] = 0;
+ }
+ 
++static void GetArgsAndEnv(char ***argv, char ***envp) {
++  static const int kMaxArgv = 2000, kMaxEnvp = 2000;
++  ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
++  ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
++}
++
++#endif  // __GLIBC__
++
+ void ReExec() {
+-  static const int kMaxArgv = 100, kMaxEnvp = 1000;
+   char **argv, **envp;
+-  ReadNullSepFileToArray("/proc/self/cmdline", &argv, kMaxArgv);
+-  ReadNullSepFileToArray("/proc/self/environ", &envp, kMaxEnvp);
++  GetArgsAndEnv(&argv, &envp);
+   execve(argv[0], argv, envp);
+ }
+ 
+--- libsanitizer/asan/asan_internal.h.jj	2013-02-13 11:53:44.377330938 +0100
++++ libsanitizer/asan/asan_internal.h	2013-02-15 13:24:17.412033319 +0100
+@@ -52,7 +52,7 @@
+ 
+ #define ASAN_POSIX (ASAN_LINUX || ASAN_MAC)
+ 
+-#if __has_feature(address_sanitizer)
++#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+ # error "The AddressSanitizer run-time should not be"
+         " instrumented by AddressSanitizer"
+ #endif
+--- libsanitizer/asan/asan_mac.cc.jj	2013-02-13 11:53:44.397330832 +0100
++++ libsanitizer/asan/asan_mac.cc	2013-02-15 13:24:17.412033319 +0100
+@@ -104,7 +104,24 @@ void MaybeReexec() {
+     _NSGetExecutablePath(program_name, &buf_size);
+     // Ok to use setenv() since the wrappers don't depend on the value of
+     // asan_inited.
+-    setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
++    if (dyld_insert_libraries) {
++      // Append the runtime dylib name to the existing value of
++      // DYLD_INSERT_LIBRARIES.
++      uptr old_env_len = internal_strlen(dyld_insert_libraries);
++      uptr fname_len = internal_strlen(info.dli_fname);
++      LowLevelAllocator allocator_for_env;
++      char *new_env =
++          (char*)allocator_for_env.Allocate(old_env_len + fname_len + 2);
++      internal_strncpy(new_env, dyld_insert_libraries, old_env_len);
++      new_env[old_env_len] = ':';
++      // Copy fname_len and add a trailing zero.
++      internal_strncpy(new_env + old_env_len + 1, info.dli_fname,
++                       fname_len + 1);
++      setenv(kDyldInsertLibraries, new_env, /*overwrite*/1);
++    } else {
++      // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name.
++      setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0);
++    }
+     if (flags()->verbosity >= 1) {
+       Report("exec()-ing the program with\n");
+       Report("%s=%s\n", kDyldInsertLibraries, info.dli_fname);
+--- libsanitizer/asan/asan_mapping.h.jj	2013-02-13 17:04:34.680198753 +0100
++++ libsanitizer/asan/asan_mapping.h	2013-02-15 13:26:25.846301749 +0100
+@@ -1,7 +1,5 @@
+ //===-- asan_mapping.h ------------------------------------------*- C++ -*-===//
+ //
+-//                     The LLVM Compiler Infrastructure
+-//
+ // This file is distributed under the University of Illinois Open Source
+ // License. See LICENSE.TXT for details.
+ //
+@@ -18,6 +16,37 @@
+ 
+ // The full explanation of the memory mapping could be found here:
+ // http://code.google.com/p/address-sanitizer/wiki/AddressSanitizerAlgorithm
++//
++// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
++// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
++// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
++// || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap  ||
++// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
++// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
++//
++// When SHADOW_OFFSET is zero (-pie):
++// || `[0x100000000000, 0x7fffffffffff]` || HighMem    ||
++// || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||
++// || `[0x000000040000, 0x01ffffffffff]` || ShadowGap  ||
++//
++// Special case when something is already mapped between
++// 0x003000000000 and 0x004000000000 (e.g. when prelink is installed):
++// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem    ||
++// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
++// || `[0x004000000000, 0x02008fff6fff]` || ShadowGap3 ||
++// || `[0x003000000000, 0x003fffffffff]` || MidMem     ||
++// || `[0x00087fff8000, 0x002fffffffff]` || ShadowGap2 ||
++// || `[0x00067fff8000, 0x00087fff7fff]` || MidShadow  ||
++// || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap  ||
++// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow  ||
++// || `[0x000000000000, 0x00007fff7fff]` || LowMem     ||
++//
++// Default Linux/i386 mapping:
++// || `[0x40000000, 0xffffffff]` || HighMem    ||
++// || `[0x28000000, 0x3fffffff]` || HighShadow ||
++// || `[0x24000000, 0x27ffffff]` || ShadowGap  ||
++// || `[0x20000000, 0x23ffffff]` || LowShadow  ||
++// || `[0x00000000, 0x1fffffff]` || LowMem     ||
+ 
+ #if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1
+ extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale;
+@@ -36,7 +65,11 @@ extern SANITIZER_INTERFACE_ATTRIBUTE upt
+ #   if defined(__powerpc64__)
+ #    define SHADOW_OFFSET (1ULL << 41)
+ #   else
+-#    define SHADOW_OFFSET (1ULL << 44)
++#    if ASAN_MAC
++#     define SHADOW_OFFSET (1ULL << 44)
++#    else
++#     define SHADOW_OFFSET 0x7fff8000ULL
++#    endif
+ #   endif
+ #  endif
+ # endif
+@@ -57,49 +90,105 @@ extern SANITIZER_INTERFACE_ATTRIBUTE upt
+ #define kHighShadowBeg  MEM_TO_SHADOW(kHighMemBeg)
+ #define kHighShadowEnd  MEM_TO_SHADOW(kHighMemEnd)
+ 
++# define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
++# define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
++
+ // With the zero shadow base we can not actually map pages starting from 0.
+ // This constant is somewhat arbitrary.
+ #define kZeroBaseShadowStart (1 << 18)
+ 
+ #define kShadowGapBeg   (kLowShadowEnd ? kLowShadowEnd + 1 \
+                                        : kZeroBaseShadowStart)
+-#define kShadowGapEnd   (kHighShadowBeg - 1)
++#define kShadowGapEnd   ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)
++
++#define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)
++#define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)
++
++#define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)
++#define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)
++
++#define DO_ASAN_MAPPING_PROFILE 0  // Set to 1 to profile the functions below.
++
++#if DO_ASAN_MAPPING_PROFILE
++# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;
++#else
++# define PROFILE_ASAN_MAPPING()
++#endif
++
++// If 1, all shadow boundaries are constants.
++// Don't set to 1 other than for testing.
++#define ASAN_FIXED_MAPPING 0
+ 
+ namespace __asan {
+ 
++extern uptr AsanMappingProfile[];
++
++#if ASAN_FIXED_MAPPING
++// Fixed mapping for 64-bit Linux. Mostly used for performance comparison
++// with non-fixed mapping. As of r175253 (Feb 2013) the performance
++// difference between fixed and non-fixed mapping is below the noise level.
++static uptr kHighMemEnd = 0x7fffffffffffULL;
++static uptr kMidMemBeg =    0x3000000000ULL;
++static uptr kMidMemEnd =    0x3fffffffffULL;
++#else
+ SANITIZER_INTERFACE_ATTRIBUTE
+-extern uptr kHighMemEnd;  // Initialized in __asan_init.
++extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;  // Initialized in __asan_init.
++#endif
+ 
+ static inline bool AddrIsInLowMem(uptr a) {
++  PROFILE_ASAN_MAPPING();
+   return a < kLowMemEnd;
+ }
+ 
+ static inline bool AddrIsInLowShadow(uptr a) {
++  PROFILE_ASAN_MAPPING();
+   return a >= kLowShadowBeg && a <= kLowShadowEnd;
+ }
+ 
+ static inline bool AddrIsInHighMem(uptr a) {
++  PROFILE_ASAN_MAPPING();
+   return a >= kHighMemBeg && a <= kHighMemEnd;
+ }
+ 
++static inline bool AddrIsInMidMem(uptr a) {
++  PROFILE_ASAN_MAPPING();
++  return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;
++}
++
+ static inline bool AddrIsInMem(uptr a) {
+-  return AddrIsInLowMem(a) || AddrIsInHighMem(a);
++  PROFILE_ASAN_MAPPING();
++  return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a);
+ }
+ 
+ static inline uptr MemToShadow(uptr p) {
++  PROFILE_ASAN_MAPPING();
+   CHECK(AddrIsInMem(p));
+   return MEM_TO_SHADOW(p);
+ }
+ 
+ static inline bool AddrIsInHighShadow(uptr a) {
+-  return a >= kHighShadowBeg && a <=  kHighMemEnd;
++  PROFILE_ASAN_MAPPING();
++  return a >= kHighShadowBeg && a <= kHighMemEnd;
++}
++
++static inline bool AddrIsInMidShadow(uptr a) {
++  PROFILE_ASAN_MAPPING();
++  return kMidMemBeg && a >= kMidShadowBeg && a <= kMidMemEnd;
+ }
+ 
+ static inline bool AddrIsInShadow(uptr a) {
+-  return AddrIsInLowShadow(a) || AddrIsInHighShadow(a);
++  PROFILE_ASAN_MAPPING();
++  return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
+ }
+ 
+ static inline bool AddrIsInShadowGap(uptr a) {
++  PROFILE_ASAN_MAPPING();
++  if (kMidMemBeg) {
++    if (a <= kShadowGapEnd)
++      return SHADOW_OFFSET == 0 || a >= kShadowGapBeg;
++    return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||
++           (a >= kShadowGap3Beg && a <= kShadowGap3End);
++  }
+   // In zero-based shadow mode we treat addresses near zero as addresses
+   // in shadow gap as well.
+   if (SHADOW_OFFSET == 0)
+@@ -108,10 +197,12 @@ static inline bool AddrIsInShadowGap(upt
+ }
+ 
+ static inline bool AddrIsAlignedByGranularity(uptr a) {
++  PROFILE_ASAN_MAPPING();
+   return (a & (SHADOW_GRANULARITY - 1)) == 0;
+ }
+ 
+ static inline bool AddressIsPoisoned(uptr a) {
++  PROFILE_ASAN_MAPPING();
+   const uptr kAccessSize = 1;
+   u8 *shadow_address = (u8*)MemToShadow(a);
+   s8 shadow_value = *shadow_address;
+@@ -123,6 +214,9 @@ static inline bool AddressIsPoisoned(upt
+   return false;
+ }
+ 
++// Must be after all calls to PROFILE_ASAN_MAPPING().
++static const uptr kAsanMappingProfileSize = __LINE__;
++
+ }  // namespace __asan
+ 
+ #endif  // ASAN_MAPPING_H
+--- libsanitizer/asan/asan_rtl.cc.jj	2013-02-13 17:04:25.688240113 +0100
++++ libsanitizer/asan/asan_rtl.cc	2013-02-15 13:24:17.411033229 +0100
+@@ -25,6 +25,8 @@
+ 
+ namespace __asan {
+ 
++uptr AsanMappingProfile[kAsanMappingProfileSize];
++
+ static void AsanDie() {
+   static atomic_uint32_t num_calls;
+   if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
+@@ -35,8 +37,14 @@ static void AsanDie() {
+     Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
+     SleepForSeconds(flags()->sleep_before_dying);
+   }
+-  if (flags()->unmap_shadow_on_exit)
+-    UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
++  if (flags()->unmap_shadow_on_exit) {
++    if (kMidMemBeg) {
++      UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
++      UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
++    } else {
++      UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
++    }
++  }
+   if (death_callback)
+     death_callback();
+   if (flags()->abort_on_error)
+@@ -161,7 +169,10 @@ void InitializeFlags(Flags *f, const cha
+ int asan_inited;
+ bool asan_init_is_running;
+ void (*death_callback)(void);
+-uptr kHighMemEnd;
++
++#if !ASAN_FIXED_MAPPING
++uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
++#endif
+ 
+ // -------------------------- Misc ---------------- {{{1
+ void ShowStatsAndAbort() {
+@@ -259,9 +270,15 @@ static NOINLINE void force_interface_sym
+ static void asan_atexit() {
+   Printf("AddressSanitizer exit stats:\n");
+   __asan_print_accumulated_stats();
++  // Print AsanMappingProfile.
++  for (uptr i = 0; i < kAsanMappingProfileSize; i++) {
++    if (AsanMappingProfile[i] == 0) continue;
++    Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);
++  }
+ }
+ 
+ static void InitializeHighMemEnd() {
++#if !ASAN_FIXED_MAPPING
+ #if SANITIZER_WORDSIZE == 64
+ # if defined(__powerpc64__)
+   // FIXME:
+@@ -277,6 +294,58 @@ static void InitializeHighMemEnd() {
+ #else  // SANITIZER_WORDSIZE == 32
+   kHighMemEnd = (1ULL << 32) - 1;  // 0xffffffff;
+ #endif  // SANITIZER_WORDSIZE
++#endif  // !ASAN_FIXED_MAPPING
++}
++
++static void ProtectGap(uptr a, uptr size) {
++  CHECK_EQ(a, (uptr)Mprotect(a, size));
++}
++
++static void PrintAddressSpaceLayout() {
++  Printf("|| `[%p, %p]` || HighMem    ||\n",
++         (void*)kHighMemBeg, (void*)kHighMemEnd);
++  Printf("|| `[%p, %p]` || HighShadow ||\n",
++         (void*)kHighShadowBeg, (void*)kHighShadowEnd);
++  if (kMidMemBeg) {
++    Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
++           (void*)kShadowGap3Beg, (void*)kShadowGap3End);
++    Printf("|| `[%p, %p]` || MidMem     ||\n",
++           (void*)kMidMemBeg, (void*)kMidMemEnd);
++    Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
++           (void*)kShadowGap2Beg, (void*)kShadowGap2End);
++    Printf("|| `[%p, %p]` || MidShadow  ||\n",
++           (void*)kMidShadowBeg, (void*)kMidShadowEnd);
++  }
++  Printf("|| `[%p, %p]` || ShadowGap  ||\n",
++         (void*)kShadowGapBeg, (void*)kShadowGapEnd);
++  if (kLowShadowBeg) {
++    Printf("|| `[%p, %p]` || LowShadow  ||\n",
++           (void*)kLowShadowBeg, (void*)kLowShadowEnd);
++    Printf("|| `[%p, %p]` || LowMem     ||\n",
++           (void*)kLowMemBeg, (void*)kLowMemEnd);
++  }
++  Printf("MemToShadow(shadow): %p %p %p %p",
++         (void*)MEM_TO_SHADOW(kLowShadowBeg),
++         (void*)MEM_TO_SHADOW(kLowShadowEnd),
++         (void*)MEM_TO_SHADOW(kHighShadowBeg),
++         (void*)MEM_TO_SHADOW(kHighShadowEnd));
++  if (kMidMemBeg) {
++    Printf(" %p %p",
++           (void*)MEM_TO_SHADOW(kMidShadowBeg),
++           (void*)MEM_TO_SHADOW(kMidShadowEnd));
++  }
++  Printf("\n");
++  Printf("red_zone=%zu\n", (uptr)flags()->redzone);
++  Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
++
++  Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
++  Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
++  Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
++  CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
++  if (kMidMemBeg)
++    CHECK(kMidShadowBeg > kLowShadowEnd &&
++          kMidMemBeg > kMidShadowEnd &&
++          kHighShadowBeg > kMidMemEnd);
+ }
+ 
+ }  // namespace __asan
+@@ -352,49 +421,48 @@ void __asan_init() {
+   ReplaceSystemMalloc();
+   ReplaceOperatorsNewAndDelete();
+ 
+-  if (flags()->verbosity) {
+-    Printf("|| `[%p, %p]` || HighMem    ||\n",
+-           (void*)kHighMemBeg, (void*)kHighMemEnd);
+-    Printf("|| `[%p, %p]` || HighShadow ||\n",
+-           (void*)kHighShadowBeg, (void*)kHighShadowEnd);
+-    Printf("|| `[%p, %p]` || ShadowGap  ||\n",
+-           (void*)kShadowGapBeg, (void*)kShadowGapEnd);
+-    Printf("|| `[%p, %p]` || LowShadow  ||\n",
+-           (void*)kLowShadowBeg, (void*)kLowShadowEnd);
+-    Printf("|| `[%p, %p]` || LowMem     ||\n",
+-           (void*)kLowMemBeg, (void*)kLowMemEnd);
+-    Printf("MemToShadow(shadow): %p %p %p %p\n",
+-           (void*)MEM_TO_SHADOW(kLowShadowBeg),
+-           (void*)MEM_TO_SHADOW(kLowShadowEnd),
+-           (void*)MEM_TO_SHADOW(kHighShadowBeg),
+-           (void*)MEM_TO_SHADOW(kHighShadowEnd));
+-    Printf("red_zone=%zu\n", (uptr)flags()->redzone);
+-    Printf("malloc_context_size=%zu\n", (uptr)flags()->malloc_context_size);
+-
+-    Printf("SHADOW_SCALE: %zx\n", (uptr)SHADOW_SCALE);
+-    Printf("SHADOW_GRANULARITY: %zx\n", (uptr)SHADOW_GRANULARITY);
+-    Printf("SHADOW_OFFSET: %zx\n", (uptr)SHADOW_OFFSET);
+-    CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
++  uptr shadow_start = kLowShadowBeg;
++  if (kLowShadowBeg) shadow_start -= GetMmapGranularity();
++  uptr shadow_end = kHighShadowEnd;
++  bool full_shadow_is_available =
++      MemoryRangeIsAvailable(shadow_start, shadow_end);
++
++#if ASAN_LINUX && defined(__x86_64__) && !ASAN_FIXED_MAPPING
++  if (!full_shadow_is_available) {
++    kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
++    kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x3fffffffffULL : 0;
+   }
++#endif
++
++  if (flags()->verbosity)
++    PrintAddressSpaceLayout();
+ 
+   if (flags()->disable_core) {
+     DisableCoreDumper();
+   }
+ 
+-  uptr shadow_start = kLowShadowBeg;
+-  if (kLowShadowBeg > 0) shadow_start -= GetMmapGranularity();
+-  uptr shadow_end = kHighShadowEnd;
+-  if (MemoryRangeIsAvailable(shadow_start, shadow_end)) {
+-    if (kLowShadowBeg != kLowShadowEnd) {
+-      // mmap the low shadow plus at least one page.
+-      ReserveShadowMemoryRange(kLowShadowBeg - GetMmapGranularity(),
+-                               kLowShadowEnd);
+-    }
++  if (full_shadow_is_available) {
++    // mmap the low shadow plus at least one page at the left.
++    if (kLowShadowBeg)
++      ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
++    // mmap the high shadow.
++    ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
++    // protect the gap.
++    ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
++  } else if (kMidMemBeg &&
++      MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
++      MemoryRangeIsAvailable(kMidMemEnd + 1, shadow_end)) {
++    CHECK(kLowShadowBeg != kLowShadowEnd);
++    // mmap the low shadow plus at least one page at the left.
++    ReserveShadowMemoryRange(shadow_start, kLowShadowEnd);
++    // mmap the mid shadow.
++    ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd);
+     // mmap the high shadow.
+     ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd);
+-    // protect the gap
+-    void *prot = Mprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
+-    CHECK(prot == (void*)kShadowGapBeg);
++    // protect the gaps.
++    ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
++    ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
++    ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
+   } else {
+     Report("Shadow memory range interleaves with an existing memory mapping. "
+            "ASan cannot proceed correctly. ABORTING.\n");
+--- libsanitizer/include/sanitizer/common_interface_defs.h.jj	2013-02-13 11:53:44.531330044 +0100
++++ libsanitizer/include/sanitizer/common_interface_defs.h	2013-02-15 13:24:17.403032450 +0100
+@@ -14,6 +14,11 @@
+ #include <stddef.h>
+ #include <stdint.h>
+ 
++// GCC does not understand __has_feature.
++#if !defined(__has_feature)
++# define __has_feature(x) 0
++#endif
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+--- libsanitizer/include/sanitizer/asan_interface.h.jj	2013-02-13 11:53:44.531330044 +0100
++++ libsanitizer/include/sanitizer/asan_interface.h	2013-02-15 13:24:17.403032450 +0100
+@@ -35,8 +35,8 @@ extern "C" {
+   // (un)poison memory in the same memory region simultaneously.
+   void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
+ 
+-  // User code should use macro instead of functions.
+-#if __has_feature(address_sanitizer)
++// User code should use macros instead of functions.
++#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+ #define ASAN_POISON_MEMORY_REGION(addr, size) \
+   __asan_poison_memory_region((addr), (size))
+ #define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
diff --git a/gcc48-pr54117.patch b/gcc48-pr54117.patch
index b1bad5a..5be2b07 100644
--- a/gcc48-pr54117.patch
+++ b/gcc48-pr54117.patch
@@ -1,263 +1,198 @@
-2013-02-13  Jakub Jelinek  <jakub at redhat.com>
+2013-02-15  Jakub Jelinek  <jakub at redhat.com>
+	    Steven Bosscher  <steven at gcc.gnu.org>
 
 	PR pch/54117
-	Revert
-	2012-07-14  Steven Bosscher  <steven at gcc.gnu.org>
+	* c-opts.c (c_common_post_options): If debug info is enabled
+	and non-dwarf*, refuse to load PCH files and when writing PCH
+	file warn.
 
-	* toplev.c (init_asm_output): Open asm_out_file in 'w' mode.
+	* lib/dg-pch.exp (pch-init, pch-finish,
+	check_effective_target_pch_supported_debug): New procs.
+	(dg-flags-pch): If $pch_unsupported, make tests UNSUPPORTED.
+	Likewise if $pch_unsupported_debug and $flags include -g.
+	Skip FAILs about missing *.gch file if $pch_unsupported_debug
+	and dg-require-effective-target pch_unsupported_debug.
+	* g++.dg/pch/pch.exp: Call pch-init and pch-finish.
+	* objc.dg/pch/pch.exp: Likewise.
+	* gcc.dg/pch/pch.exp: Likewise.
+	* gcc.dg/pch/valid-1.c: Add dg-require-effective-target
+	pch_unsupported_debug.
+	* gcc.dg/pch/valid-1.hs: Likewise.
+	* gcc.dg/pch/valid-1b.c: Likewise.
+	* gcc.dg/pch/valid-1b.hs: Likewise.
 
-	* c-pch.c (CHECK_NO_ASM_OUT_DURING_PCH): Do not define.
-	Remove code conditional on it.
-
-	2012-07-01  Uros Bizjak  <ubizjak at gmail.com>
-
-	* c-pch.c (c_common_write_pch): Remove unused variables.
-
-	2012-06-21  Steven Bosscher  <steven at gcc.gnu.org>
-
-	* c-common.h (c_common_print_pch_checksum): Remove.
-	* c-pch.c: Do not include output.h.
-	(CHECK_NO_ASM_OUT_DURING_PCH): Define and add FIXME.
-	(asm_out_file): Define iff CHECK_NO_ASM_OUT_DURING_PCH isdefined.
-	(asm_file_startpos): Define iff CHECK_NO_ASM_OUT_DURING_PCH is defined.
-	(struct c_pch_header): Remove.
-	(get_ident): Update gpch version.
-	(pch_init): Do not print executable_checksum to asm_out_file.
-	Do not fail if there is no asm_out_file to read back from.  Set
-	asm_file_startpos only if CHECK_NO_ASM_OUT_DURING_PCH is defined.
-	(c_common_write_pch): Verify that nothing was written to asm_out_file
-	since pch_init was called.  Do not write a c_pch_header, and do not
-	copy from asm_out_file to the PCH.
-	(c_common_read_pch): Do not read a c_pch_header, and do not restore
-	the content of asm_out_file from the PCH.
-	(c_common_print_pch_checksum): Remove.
-	* c-opts.c (c_common_init): Print out executable_checksum directly.
-
---- gcc/toplev.c.jj	2013-02-13 09:29:16.197757222 +0100
-+++ gcc/toplev.c	2013-02-13 11:34:38.855800182 +0100
-@@ -912,7 +912,7 @@ init_asm_output (const char *name)
-       if (!strcmp (asm_file_name, "-"))
- 	asm_out_file = stdout;
-       else
--	asm_out_file = fopen (asm_file_name, "w");
-+	asm_out_file = fopen (asm_file_name, "w+b");
-       if (asm_out_file == 0)
- 	fatal_error ("can%'t open %s for writing: %m", asm_file_name);
-     }
---- gcc/c-family/c-pch.c.jj	2013-02-13 09:29:16.065757956 +0100
-+++ gcc/c-family/c-pch.c	2013-02-13 11:34:45.552761549 +0100
-@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.
- #include "tree.h"
- #include "flags.h"
- #include "c-common.h"
-+#include "output.h" /* for asm_out_file */
- #include "debug.h"
- #include "c-pragma.h"
- #include "ggc.h"
-@@ -67,11 +68,19 @@ struct c_pch_validity
-   size_t target_data_length;
- };
- 
-+struct c_pch_header
-+{
-+  unsigned long asm_size;
-+};
-+
- #define IDENT_LENGTH 8
- 
- /* The file we'll be writing the PCH to.  */
- static FILE *pch_outfile;
- 
-+/* The position in the assembler output file when pch_init was called.  */
-+static long asm_file_startpos;
-+
- static const char *get_ident (void);
+--- gcc/c-family/c-opts.c.jj	2013-02-14 14:45:01.000000000 +0100
++++ gcc/c-family/c-opts.c	2013-02-15 12:44:48.936535118 +0100
+@@ -945,6 +945,16 @@ c_common_post_options (const char **pfil
+ 	 because the default address space slot then can't be used
+ 	 for the output PCH file.  */
+       if (pch_file)
++	{
++	  c_common_no_more_pch ();
++	  /* Only -g0 and -gdwarf* are supported with PCH, for other
++	     debug formats we warn here and refuse to load any PCH files.  */
++	  if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG)
++	    warning (OPT_Wdeprecated,
++		     "the \"%s\" debug format cannot be used with "
++		     "pre-compiled headers", debug_type_names[write_symbols]);
++	}
++      else if (write_symbols != NO_DEBUG && write_symbols != DWARF2_DEBUG)
+ 	c_common_no_more_pch ();
  
- /* Compute an appropriate 8-byte magic number for the PCH file, so that
-@@ -83,7 +92,7 @@ static const char *
- get_ident (void)
- {
-   static char result[IDENT_LENGTH];
--  static const char templ[] = "gpch.014";
-+  static const char templ[] = "gpch.013";
-   static const char c_language_chars[] = "Co+O";
+       /* Yuk.  WTF is this?  I do know ObjC relies on it somewhere.  */
+--- gcc/testsuite/lib/dg-pch.exp.jj	2013-01-11 09:02:39.000000000 +0100
++++ gcc/testsuite/lib/dg-pch.exp	2013-02-15 15:45:53.747855529 +0100
+@@ -16,8 +16,49 @@
  
-   memcpy (result, templ, IDENT_LENGTH);
-@@ -97,7 +106,9 @@ get_ident (void)
- static bool pch_ready_to_save_cpp_state = false;
+ load_lib copy-file.exp
  
- /* Prepare to write a PCH file, if one is being written.  This is
--   called at the start of compilation.  */
-+   called at the start of compilation.
++proc pch-init { args } {
++    global pch_unsupported_debug pch_unsupported
 +
-+   Also, print out the executable checksum if -fverbose-asm is in effect.  */
- 
- void
- pch_init (void)
-@@ -107,6 +118,15 @@ pch_init (void)
-   void *target_validity;
-   static const char partial_pch[] = "gpcWrite";
- 
-+#ifdef ASM_COMMENT_START
-+  if (flag_verbose_asm)
-+    {
-+      fprintf (asm_out_file, "%s ", ASM_COMMENT_START);
-+      c_common_print_pch_checksum (asm_out_file);
-+      fputc ('\n', asm_out_file);
++    if [info exists pch_unsupported_debug] {
++	error "pch-init: pch_unsupported_debug is not empty as expected"
++    }
++    if [info exists pch_unsupported] {
++	error "pch-init: pch_unsupported is not empty as expected"
 +    }
-+#endif
-+
-   if (!pch_file)
-     return;
- 
-@@ -136,6 +156,14 @@ pch_init (void)
-       || fwrite (target_validity, v.target_data_length, 1, f) != 1)
-     fatal_error ("can%'t write to %s: %m", pch_file);
- 
-+  /* We need to be able to re-read the output.  */
-+  /* The driver always provides a valid -o option.  */
-+  if (asm_file_name == NULL
-+      || strcmp (asm_file_name, "-") == 0)
-+    fatal_error ("%qs is not a valid output file", asm_file_name);
-+
-+  asm_file_startpos = ftell (asm_out_file);
-+
-   /* Let the debugging format deal with the PCHness.  */
-   (*debug_hooks->handle_pch) (0);
- 
-@@ -172,6 +200,11 @@ pch_cpp_save_state (void)
- void
- c_common_write_pch (void)
- {
-+  char *buf;
-+  long asm_file_end;
-+  long written;
-+  struct c_pch_header h;
-+
-   timevar_push (TV_PCH_SAVE);
- 
-   targetm.prepare_pch_save ();
-@@ -180,6 +213,34 @@ c_common_write_pch (void)
- 
-   cpp_write_pch_deps (parse_in, pch_outfile);
- 
-+  asm_file_end = ftell (asm_out_file);
-+  h.asm_size = asm_file_end - asm_file_startpos;
-+
-+  if (fwrite (&h, sizeof (h), 1, pch_outfile) != 1)
-+    fatal_error ("can%'t write %s: %m", pch_file);
 +
-+  buf = XNEWVEC (char, 16384);
++    set result [check_compile pchtest object "int i;" "-g -x c-header"]
++    set pch_unsupported_debug \
++	[regexp "debug format cannot be used with pre-compiled headers" \
++		[lindex $result 0]]
 +
-+  if (fseek (asm_out_file, asm_file_startpos, SEEK_SET) != 0)
-+    fatal_error ("can%'t seek in %s: %m", asm_file_name);
++    set pch_unsupported 0
++    if { $pch_unsupported_debug } {
++	verbose -log "pch is unsupported with the debug info format"
 +
-+  for (written = asm_file_startpos; written < asm_file_end; )
-+    {
-+      long size = asm_file_end - written;
-+      if (size > 16384)
-+	size = 16384;
-+      if (fread (buf, size, 1, asm_out_file) != 1)
-+	fatal_error ("can%'t read %s: %m", asm_file_name);
-+      if (fwrite (buf, size, 1, pch_outfile) != 1)
-+	fatal_error ("can%'t write %s: %m", pch_file);
-+      written += size;
-+    }
-+  free (buf);
-+  /* asm_out_file can be written afterwards, so fseek to clear
-+     _IOREAD flag.  */
-+  if (fseek (asm_out_file, 0, SEEK_END) != 0)
-+    fatal_error ("can%'t seek in %s: %m", asm_file_name);
-+
-   gt_pch_save (pch_outfile);
- 
-   timevar_push (TV_PCH_CPP_SAVE);
-@@ -341,6 +402,7 @@ c_common_read_pch (cpp_reader *pfile, co
- 		   int fd, const char *orig_name ATTRIBUTE_UNUSED)
- {
-   FILE *f;
-+  struct c_pch_header h;
-   struct save_macro_data *smd;
-   expanded_location saved_loc;
-   bool saved_trace_includes;
-@@ -357,6 +419,38 @@ c_common_read_pch (cpp_reader *pfile, co
- 
-   cpp_get_callbacks (parse_in)->valid_pch = NULL;
- 
-+  if (fread (&h, sizeof (h), 1, f) != 1)
-+    {
-+      cpp_errno (pfile, CPP_DL_ERROR, "reading");
-+      fclose (f);
-+      goto end;
++	set result [check_compile pchtest object "int i;" "-x c-header"]
++	    set pch_unsupported \
++		[regexp "debug format cannot be used with pre-compiled headers" \
++			[lindex $result 0]]
 +    }
++}
 +
-+  if (!flag_preprocess_only)
-+    {
-+      unsigned long written;
-+      char * buf = XNEWVEC (char, 16384);
++proc pch-finish { args } {
++    global pch_unsupported_debug pch_unsupported
++    unset pch_unsupported_debug
++    unset pch_unsupported
++}
 +
-+      for (written = 0; written < h.asm_size; )
-+	{
-+	  long size = h.asm_size - written;
-+	  if (size > 16384)
-+	    size = 16384;
-+	  if (fread (buf, size, 1, f) != 1
-+	      || fwrite (buf, size, 1, asm_out_file) != 1)
-+	    cpp_errno (pfile, CPP_DL_ERROR, "reading");
-+	  written += size;
-+	}
-+      free (buf);
-+    }
-+  else
-+    {
-+      /* If we're preprocessing, don't write to a NULL
-+	 asm_out_file.  */
-+      if (fseek (f, h.asm_size, SEEK_CUR) != 0)
-+	cpp_errno (pfile, CPP_DL_ERROR, "seeking");
++proc check_effective_target_pch_supported_debug { } {
++    global pch_unsupported_debug
++    if { $pch_unsupported_debug } {
++	return 0
 +    }
++    return 1
++}
 +
-   /* Save the location and then restore it after reading the PCH.  */
-   saved_loc = expand_location (line_table->highest_line);
-   saved_trace_includes = line_table->trace_includes;
-@@ -435,3 +529,14 @@ c_common_pch_pragma (cpp_reader *pfile,
-   close (fd);
- }
- 
-+/* Print out executable_checksum[].  */
+ proc dg-flags-pch { subdir test otherflags options suffix } {
+     global runtests dg-do-what-default
++    global pch_unsupported_debug pch_unsupported
+ 
+     # If we're only testing specific files and this isn't one of them, skip it.
+     if ![runtest_file_p $runtests $test] {
+@@ -35,6 +76,13 @@ proc dg-flags-pch { subdir test otherfla
+     foreach flags $options {
+ 	verbose "Testing $nshort, $otherflags $flags" 1
+ 
++	if { $pch_unsupported != 0 \
++	     || ( $pch_unsupported_debug != 0 && [regexp " -g" " $flags"] ) } {
++	    verbose -log "$nshort unsupported because debug format conflicts with PCH"
++	    unsupported "$nshort $flags"
++	    continue
++	}
 +
-+void
-+c_common_print_pch_checksum (FILE *f)
-+{
-+  int i;
-+  fputs ("Compiler executable checksum: ", f);
-+  for (i = 0; i < 16; i++)
-+    fprintf (f, "%02x", executable_checksum[i]);
-+  putc ('\n', f);
-+}
---- gcc/c-family/c-opts.c.jj	2013-02-13 09:29:16.110757723 +0100
-+++ gcc/c-family/c-opts.c	2013-02-13 11:34:45.551761562 +0100
-@@ -999,13 +999,7 @@ c_common_init (void)
-   cpp_init_iconv (parse_in);
- 
-   if (version_flag)
--    {
--      int i;
--      fputs ("Compiler executable checksum: ", stderr);
--      for (i = 0; i < 16; i++)
--	fprintf (stderr, "%02x", executable_checksum[i]);
--      putc ('\n', stderr);
--    }
-+    c_common_print_pch_checksum (stderr);
- 
-   /* Has to wait until now so that cpplib has its hash table.  */
-   init_pragma ();
---- gcc/c-family/c-common.h.jj	2013-02-13 09:29:16.152757462 +0100
-+++ gcc/c-family/c-common.h	2013-02-13 11:34:45.551761562 +0100
-@@ -1011,6 +1011,7 @@ extern void c_common_read_pch (cpp_reade
- extern void c_common_write_pch (void);
- extern void c_common_no_more_pch (void);
- extern void c_common_pch_pragma (cpp_reader *pfile, const char *);
-+extern void c_common_print_pch_checksum (FILE *f);
- 
- /* In *-checksum.c */
- extern const unsigned char executable_checksum[16];
+ 	# For the header files, the default is to precompile.
+ 	set dg-do-what-default precompile
+ 	catch { file_on_host delete "$bname$suffix" }
+@@ -78,7 +126,8 @@ proc dg-flags-pch { subdir test otherfla
+  		    fail "$nshort $flags assembly comparison"
+ 		}
+ 	    }
+-	} else {
++	} elseif { $pch_unsupported_debug == 0 \
++		   || [llength [grep $test "{\[ \t\]\+dg-require-effective-target\[ \t\]\+pch_supported_debug\[ \t\]\+.*\[ \t\]\+}"]] > 0 } {
+ 	    verbose -log "pch file '$bname$suffix.gch' missing"
+ 	    fail "$nshort $flags"
+ 	    if { !$have_errs } {
+--- gcc/testsuite/g++.dg/pch/pch.exp.jj	2013-01-11 09:02:44.000000000 +0100
++++ gcc/testsuite/g++.dg/pch/pch.exp	2013-02-15 14:53:03.517106464 +0100
+@@ -23,6 +23,7 @@ load_lib dg-pch.exp
+ 
+ # Initialize `dg'.
+ dg-init
++pch-init
+ 
+ set old_dg_do_what_default "${dg-do-what-default}"
+ 
+@@ -36,4 +37,5 @@ foreach test [lsort [glob -nocomplain $s
+ set dg-do-what-default "$old_dg_do_what_default"
+ 
+ # All done.
++pch-finish
+ dg-finish
+--- gcc/testsuite/objc.dg/pch/pch.exp.jj	2013-01-11 09:02:44.000000000 +0100
++++ gcc/testsuite/objc.dg/pch/pch.exp	2013-02-15 14:53:30.063951051 +0100
+@@ -24,8 +24,8 @@ load_lib torture-options.exp
+ 
+ # Initialize `dg'.
+ dg-init
+-
+ torture-init
++pch-init
+ 
+ set-torture-options $DG_TORTURE_OPTIONS
+ 
+@@ -59,5 +59,6 @@ if [istarget "*-*-darwin*" ] {
+ set dg-do-what-default "$old_dg_do_what_default"
+ 
+ # All done.
++pch-finish
+ torture-finish
+ dg-finish
+--- gcc/testsuite/gcc.dg/pch/pch.exp.jj	2013-01-11 09:02:42.000000000 +0100
++++ gcc/testsuite/gcc.dg/pch/pch.exp	2013-02-15 14:11:27.053896809 +0100
+@@ -26,6 +26,7 @@ load_lib torture-options.exp
+ dg-init
+ torture-init
+ set-torture-options $DG_TORTURE_OPTIONS
++pch-init
+ 
+ set old_dg_do_what_default "${dg-do-what-default}"
+ 
+@@ -59,5 +60,6 @@ file delete $testh
+ set dg-do-what-default "$old_dg_do_what_default"
+ 
+ # All done.
++pch-finish
+ torture-finish
+ dg-finish
+--- gcc/testsuite/gcc.dg/pch/valid-1.c.jj	2009-06-08 11:53:48.000000000 +0200
++++ gcc/testsuite/gcc.dg/pch/valid-1.c	2013-02-15 15:19:44.124833259 +0100
+@@ -1,3 +1,4 @@
++/* { dg-require-effective-target pch_supported_debug } */
+ /* { dg-options "-I. -Winvalid-pch -g" } */
+ 
+ #include "valid-1.h"/* { dg-warning "created with -gnone, but used with -g" } */
+--- gcc/testsuite/gcc.dg/pch/valid-1.hs.jj	2008-09-05 12:54:26.000000000 +0200
++++ gcc/testsuite/gcc.dg/pch/valid-1.hs	2013-02-15 15:19:50.686794340 +0100
+@@ -1,3 +1,4 @@
++/* { dg-require-effective-target pch_supported_debug } */
+ /* { dg-options "-I. -Winvalid-pch -g0" } */
+ 
+ extern int x;
+--- gcc/testsuite/gcc.dg/pch/valid-1b.c.jj	2008-09-05 12:54:26.000000000 +0200
++++ gcc/testsuite/gcc.dg/pch/valid-1b.c	2013-02-15 15:19:55.935763631 +0100
+@@ -1,3 +1,4 @@
++/* { dg-require-effective-target pch_supported_debug } */
+ /* { dg-options "-I. -Winvalid-pch -g0" } */
+ 
+ #include "valid-1b.h"
+--- gcc/testsuite/gcc.dg/pch/valid-1b.hs.jj	2008-09-05 12:54:26.000000000 +0200
++++ gcc/testsuite/gcc.dg/pch/valid-1b.hs	2013-02-15 15:20:02.214727794 +0100
+@@ -1,3 +1,4 @@
++/* { dg-require-effective-target pch_supported_debug } */
+ /* { dg-options "-I. -Winvalid-pch -g" } */
+ 
+ extern int x;
diff --git a/sources b/sources
index 2f8b492..032d95c 100644
--- a/sources
+++ b/sources
@@ -1,4 +1,4 @@
 be78a47bd82523250eb3e91646db5b3d  cloog-0.18.0.tar.gz
 2659f09c2e43ef8b7d4406321753f1b2  fastjar-0.97.tar.gz
 bce1586384d8635a76d2f017fb067cd2  isl-0.11.1.tar.bz2
-b69a343c57e805bd5e3c94fdcd7d45b7  gcc-4.8.0-20130213.tar.bz2
+4fa6cbda8e98ae790212c6b7b00fb939  gcc-4.8.0-20130215.tar.bz2


More information about the scm-commits mailing list