Bug 683975 - Need infra for developer contributed compilers. r=rail.
authorRafael Ávila de Espíndola <respindola@mozilla.com>
Fri, 20 Jan 2012 11:19:51 -0500
changeset 86229 8c71c2afb684111572f99c884682677041dab9ee
parent 86228 408ab9247ef1684867b51914ca5540c935d366f1
child 86230 a262cdf67c8274bb1e72b32af7e1d310c1031155
push id805
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 18:17:35 +0000
treeherdermozilla-aurora@6fb3bf232436 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrail
bugs683975
milestone12.0a1
Bug 683975 - Need infra for developer contributed compilers. r=rail. A small update: *) Add the patches that I forgot on the first patch. *) Just patch binutils to have a deterministic ar. *) Bootstrap and install the linker too.
build/unix/build-toolchain/binutils-deterministic.patch
build/unix/build-toolchain/build-gcc.py
build/unix/build-toolchain/det-ar.sh
build/unix/build-toolchain/plugin_finish_decl.diff
build/unix/build-toolchain/pr49911.diff
build/unix/build-toolchain/r159628-r163231-r171807.patch
new file mode 100644
--- /dev/null
+++ b/build/unix/build-toolchain/binutils-deterministic.patch
@@ -0,0 +1,22 @@
+diff -ru a/binutils/ar.c b/binutils/ar.c
+--- a/binutils/ar.c	2011-03-16 04:35:58.000000000 -0400
++++ b/binutils/ar.c	2012-01-19 15:44:46.211226017 -0500
+@@ -98,7 +98,7 @@
+ /* Operate in deterministic mode: write zero for timestamps, uids,
+    and gids for archive members and the archive symbol table, and write
+    consistent file modes.  */
+-int deterministic = 0;
++int deterministic = TRUE;
+ 
+ /* Nonzero means it's the name of an existing member; position new or moved
+    files with respect to this one.  */
+@@ -634,9 +634,6 @@
+       if (newer_only && operation != replace)
+ 	fatal (_("`u' is only meaningful with the `r' option."));
+ 
+-      if (newer_only && deterministic)
+-	fatal (_("`u' is not meaningful with the `D' option."));
+-
+       if (postype != pos_default)
+ 	posname = argv[arg_index++];
+ 
--- a/build/unix/build-toolchain/build-gcc.py
+++ b/build/unix/build-toolchain/build-gcc.py
@@ -35,22 +35,16 @@ def patch(patch, plevel, srcdir):
 
 def build_package(package_source_dir, package_build_dir, configure_args):
     os.mkdir(package_build_dir)
     run_in(package_build_dir,
            ["%s/configure" % package_source_dir] + configure_args)
     run_in(package_build_dir, ["make", "-j8"])
     run_in(package_build_dir, ["make", "install"])
 
-def build_binutils(base_dir, binutils_inst_dir):
-    binutils_build_dir = base_dir + '/binutils_build'
-    build_package(binutils_source_dir, binutils_build_dir,
-                  ["--prefix=%s" % binutils_inst_dir])
-
-# FIXME: factor this with build_binutils
 def build_tar(base_dir, tar_inst_dir):
     tar_build_dir = base_dir + '/tar_build'
     build_package(tar_source_dir, tar_build_dir,
                   ["--prefix=%s" % tar_inst_dir])
 
 def build_one_stage(env, stage_dir):
     old_env = os.environ.copy()
     os.environ.update(env)
@@ -66,20 +60,25 @@ def build_one_stage(env, stage_dir):
                   ["--prefix=%s" % lib_inst_dir, "--disable-shared",
                    "--with-gmp=%s" % lib_inst_dir])
     mpc_build_dir = stage_dir + '/mpc'
     build_package(mpc_source_dir, mpc_build_dir,
                   ["--prefix=%s" % lib_inst_dir, "--disable-shared",
                    "--with-gmp=%s" % lib_inst_dir,
                    "--with-mpfr=%s" % lib_inst_dir])
 
+    tool_inst_dir = stage_dir + '/inst'
+
+    binutils_build_dir = stage_dir + '/binutils'
+    build_package(binutils_source_dir, binutils_build_dir,
+                  ["--prefix=%s" % tool_inst_dir])
+
     gcc_build_dir = stage_dir + '/gcc'
-    gcc_inst_dir = stage_dir + '/inst'
     build_package(gcc_source_dir, gcc_build_dir,
-                  ["--prefix=%s" % gcc_inst_dir,
+                  ["--prefix=%s" % tool_inst_dir,
                    "--enable-__cxa_atexit",
                    "--with-gmp=%s" % lib_inst_dir,
                    "--with-mpfr=%s" % lib_inst_dir,
                    "--with-mpc=%s" % lib_inst_dir,
                    "--enable-languages=c,c++",
                    "--disable-bootstrap"])
     os.environ.clear()
     os.environ.update(old_env)
@@ -129,39 +128,37 @@ tar_source_dir  = build_source_dir('tar-
 mpc_source_dir  = build_source_dir('mpc-', mpc_version)
 mpfr_source_dir = build_source_dir('mpfr-', mpfr_version)
 gmp_source_dir  = build_source_dir('gmp-', gmp_version)
 gcc_source_dir  = build_source_dir('gcc-', gcc_version)
 
 if not os.path.exists(source_dir):
     os.mkdir(source_dir)
     extract(binutils_source_tar, source_dir)
+    patch('binutils-deterministic.patch', 1, binutils_source_dir)
     extract(tar_source_tar, source_dir)
     extract(mpc_source_tar, source_dir)
     extract(mpfr_source_tar, source_dir)
     extract(gmp_source_tar, source_dir)
     extract(gcc_source_tar, source_dir)
     patch('plugin_finish_decl.diff', 0, gcc_source_dir)
     patch('pr49911.diff', 1, gcc_source_dir)
     patch('r159628-r163231-r171807.patch', 1, gcc_source_dir)
 
 if os.path.exists(build_dir):
     shutil.rmtree(build_dir)
 os.mkdir(build_dir)
 
-tools_inst_dir = build_dir + '/tools_inst'
-build_binutils(build_dir, tools_inst_dir)
-build_tar(build_dir, tools_inst_dir)
-
-os.environ["AR"] = os.path.realpath('det-ar.sh')
-os.environ["MOZ_AR"] = tools_inst_dir + '/bin/ar'
-os.environ["RANLIB"] = "true"
+tar_inst_dir = build_dir + '/tar_inst'
+build_tar(build_dir, tar_inst_dir)
 
 stage1_dir = build_dir + '/stage1'
 build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir)
 
-stage1_gcc_inst_dir = stage1_dir + '/inst'
+stage1_tool_inst_dir = stage1_dir + '/inst'
 stage2_dir = build_dir + '/stage2'
-build_one_stage({"CC"  : stage1_gcc_inst_dir + "/bin/gcc",
-                 "CXX" : stage1_gcc_inst_dir + "/bin/g++"}, stage2_dir)
+build_one_stage({"CC"     : stage1_tool_inst_dir + "/bin/gcc",
+                 "CXX"    : stage1_tool_inst_dir + "/bin/g++",
+                 "AR"     : stage1_tool_inst_dir + "/bin/ar",
+                 "RANLIB" : "true" })
 
-build_tar_package(tools_inst_dir + "/bin/tar",
+build_tar_package(tar_inst_dir + "/bin/tar",
                   "toolchain.tar", stage2_dir, "inst")
deleted file mode 100755
--- a/build/unix/build-toolchain/det-ar.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-
-shift
-echo $MOZ_AR "crD" "$@"
-exec $MOZ_AR "crD" "$@"
new file mode 100644
--- /dev/null
+++ b/build/unix/build-toolchain/plugin_finish_decl.diff
@@ -0,0 +1,179 @@
+Index: gcc/doc/plugins.texi
+===================================================================
+--- gcc/doc/plugins.texi	(revision 162126)
++++ gcc/doc/plugins.texi	(working copy)
+@@ -144,6 +144,7 @@
+ @{
+   PLUGIN_PASS_MANAGER_SETUP,    /* To hook into pass manager.  */
+   PLUGIN_FINISH_TYPE,           /* After finishing parsing a type.  */
++  PLUGIN_FINISH_DECL,           /* After finishing parsing a declaration. */
+   PLUGIN_FINISH_UNIT,           /* Useful for summary processing.  */
+   PLUGIN_PRE_GENERICIZE,        /* Allows to see low level AST in C and C++ frontends.  */
+   PLUGIN_FINISH,                /* Called before GCC exits.  */
+Index: gcc/plugin.def
+===================================================================
+--- gcc/plugin.def	(revision 162126)
++++ gcc/plugin.def	(working copy)
+@@ -24,6 +24,9 @@
+ /* After finishing parsing a type.  */
+ DEFEVENT (PLUGIN_FINISH_TYPE)
+ 
++/* After finishing parsing a declaration. */
++DEFEVENT (PLUGIN_FINISH_DECL)
++
+ /* Useful for summary processing.  */
+ DEFEVENT (PLUGIN_FINISH_UNIT)
+ 
+Index: gcc/testsuite/g++.dg/plugin/plugin.exp
+===================================================================
+--- gcc/testsuite/g++.dg/plugin/plugin.exp	(revision 162126)
++++ gcc/testsuite/g++.dg/plugin/plugin.exp	(working copy)
+@@ -51,7 +51,8 @@
+     { pragma_plugin.c pragma_plugin-test-1.C } \
+     { selfassign.c self-assign-test-1.C self-assign-test-2.C self-assign-test-3.C } \
+     { dumb_plugin.c dumb-plugin-test-1.C } \
+-    { header_plugin.c header-plugin-test.C } ]
++    { header_plugin.c header-plugin-test.C } \
++    { decl_plugin.c decl-plugin-test.C } ]
+ 
+ foreach plugin_test $plugin_test_list {
+     # Replace each source file with its full-path name
+Index: gcc/testsuite/g++.dg/plugin/decl-plugin-test.C
+===================================================================
+--- gcc/testsuite/g++.dg/plugin/decl-plugin-test.C	(revision 0)
++++ gcc/testsuite/g++.dg/plugin/decl-plugin-test.C	(revision 0)
+@@ -0,0 +1,32 @@
++
++
++extern int global; // { dg-warning "Decl Global global" }
++int global_array[] = { 1, 2, 3 }; // { dg-warning "Decl Global global_array" }
++
++int takes_args(int arg1, int arg2)
++{
++  int local = arg1 + arg2 + global; // { dg-warning "Decl Local local" }
++  return local + 1;
++}
++
++int global = 12; // { dg-warning "Decl Global global" }
++
++struct test_str {
++  int field; // { dg-warning "Decl Field field" }
++};
++
++class test_class {
++  int class_field1; // { dg-warning "Decl Field class_field1" }
++  int class_field2; // { dg-warning "Decl Field class_field2" }
++
++  test_class() // { dg-warning "Decl Function test_class" }
++    : class_field1(0), class_field2(0)
++  {}
++
++  void swap_fields(int bias) // { dg-warning "Decl Function swap_fields" }
++  {
++    int temp = class_field1 + bias; // { dg-warning "Decl Local temp" }
++    class_field1 = class_field2 - bias;
++    class_field2 = temp;
++  }
++};
+Index: gcc/testsuite/g++.dg/plugin/decl_plugin.c
+===================================================================
+--- gcc/testsuite/g++.dg/plugin/decl_plugin.c	(revision 0)
++++ gcc/testsuite/g++.dg/plugin/decl_plugin.c	(revision 0)
+@@ -0,0 +1,51 @@
++/* A plugin example that shows which declarations are caught by FINISH_DECL */
++
++#include "gcc-plugin.h"
++#include <stdlib.h>
++#include "config.h"
++#include "system.h"
++#include "coretypes.h"
++#include "tree.h"
++#include "tree-pass.h"
++#include "intl.h"
++
++int plugin_is_GPL_compatible;
++
++/* Callback function to invoke after GCC finishes a declaration. */
++
++void plugin_finish_decl (void *event_data, void *data)
++{
++  tree decl = (tree) event_data;
++
++  const char *kind = NULL;
++  switch (TREE_CODE(decl)) {
++  case FUNCTION_DECL:
++    kind = "Function"; break;
++  case PARM_DECL:
++    kind = "Parameter"; break;
++  case VAR_DECL:
++    if (DECL_CONTEXT(decl) != NULL)
++      kind = "Local";
++    else
++      kind = "Global";
++    break;
++  case FIELD_DECL:
++    kind = "Field"; break;
++  default:
++    kind = "Unknown";
++  }
++
++  warning (0, G_("Decl %s %s"),
++           kind, IDENTIFIER_POINTER (DECL_NAME (decl)));
++}
++
++int
++plugin_init (struct plugin_name_args *plugin_info,
++             struct plugin_gcc_version *version)
++{
++  const char *plugin_name = plugin_info->base_name;
++
++  register_callback (plugin_name, PLUGIN_FINISH_DECL,
++                     plugin_finish_decl, NULL);
++  return 0;
++}
+Index: gcc/cp/decl.c
+===================================================================
+--- gcc/cp/decl.c	(revision 162126)
++++ gcc/cp/decl.c	(working copy)
+@@ -5967,6 +5967,8 @@
+   /* If this was marked 'used', be sure it will be output.  */
+   if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
+     mark_decl_referenced (decl);
++
++  invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+ }
+ 
+ /* Returns a declaration for a VAR_DECL as if:
+Index: gcc/c-decl.c
+===================================================================
+--- gcc/c-decl.c	(revision 162126)
++++ gcc/c-decl.c	(working copy)
+@@ -4392,6 +4392,8 @@
+       && DECL_INITIAL (decl) == NULL_TREE)
+     warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wc___compat,
+ 		"uninitialized const %qD is invalid in C++", decl);
++
++  invoke_plugin_callbacks (PLUGIN_FINISH_DECL, decl);
+ }
+ 
+ /* Given a parsed parameter declaration, decode it into a PARM_DECL.  */
+Index: gcc/plugin.c
+===================================================================
+--- gcc/plugin.c	(revision 162126)
++++ gcc/plugin.c	(working copy)
+@@ -400,6 +400,7 @@
+ 	  }
+       /* Fall through.  */
+       case PLUGIN_FINISH_TYPE:
++      case PLUGIN_FINISH_DECL:
+       case PLUGIN_START_UNIT:
+       case PLUGIN_FINISH_UNIT:
+       case PLUGIN_PRE_GENERICIZE:
+@@ -481,6 +482,7 @@
+ 	gcc_assert (event < event_last);
+       /* Fall through.  */
+       case PLUGIN_FINISH_TYPE:
++      case PLUGIN_FINISH_DECL:
+       case PLUGIN_START_UNIT:
+       case PLUGIN_FINISH_UNIT:
+       case PLUGIN_PRE_GENERICIZE:
new file mode 100644
--- /dev/null
+++ b/build/unix/build-toolchain/pr49911.diff
@@ -0,0 +1,274 @@
+diff -ru gcc-4.5.2/gcc/double-int.c gcc-4.5.2-new/gcc/double-int.c
+--- gcc-4.5.2/gcc/double-int.c	2009-11-25 05:55:54.000000000 -0500
++++ gcc-4.5.2-new/gcc/double-int.c	2011-11-29 10:20:27.625583810 -0500
+@@ -296,7 +296,12 @@
+ tree
+ double_int_to_tree (tree type, double_int cst)
+ {
+-  cst = double_int_ext (cst, TYPE_PRECISION (type), TYPE_UNSIGNED (type));
++  /* Size types *are* sign extended.  */
++  bool sign_extended_type = (!TYPE_UNSIGNED (type)
++			     || (TREE_CODE (type) == INTEGER_TYPE
++				 && TYPE_IS_SIZETYPE (type)));
++
++  cst = double_int_ext (cst, TYPE_PRECISION (type), !sign_extended_type);
+ 
+   return build_int_cst_wide (type, cst.low, cst.high);
+ }
+diff -ru gcc-4.5.2/gcc/tree.c gcc-4.5.2-new/gcc/tree.c
+--- gcc-4.5.2/gcc/tree.c	2010-07-07 11:24:27.000000000 -0400
++++ gcc-4.5.2-new/gcc/tree.c	2011-11-29 10:20:27.626583813 -0500
+@@ -9750,7 +9750,7 @@
+ tree
+ upper_bound_in_type (tree outer, tree inner)
+ {
+-  unsigned HOST_WIDE_INT lo, hi;
++  double_int high;
+   unsigned int det = 0;
+   unsigned oprec = TYPE_PRECISION (outer);
+   unsigned iprec = TYPE_PRECISION (inner);
+@@ -9797,18 +9797,18 @@
+   /* Compute 2^^prec - 1.  */
+   if (prec <= HOST_BITS_PER_WIDE_INT)
+     {
+-      hi = 0;
+-      lo = ((~(unsigned HOST_WIDE_INT) 0)
++      high.high = 0;
++      high.low = ((~(unsigned HOST_WIDE_INT) 0)
+ 	    >> (HOST_BITS_PER_WIDE_INT - prec));
+     }
+   else
+     {
+-      hi = ((~(unsigned HOST_WIDE_INT) 0)
++      high.high = ((~(unsigned HOST_WIDE_INT) 0)
+ 	    >> (2 * HOST_BITS_PER_WIDE_INT - prec));
+-      lo = ~(unsigned HOST_WIDE_INT) 0;
++      high.low = ~(unsigned HOST_WIDE_INT) 0;
+     }
+ 
+-  return build_int_cst_wide (outer, lo, hi);
++  return double_int_to_tree (outer, high);
+ }
+ 
+ /* Returns the smallest value obtainable by casting something in INNER type to
+diff -ru gcc-4.5.2/gcc/tree-vrp.c gcc-4.5.2-new/gcc/tree-vrp.c
+--- gcc-4.5.2/gcc/tree-vrp.c	2010-06-14 11:23:31.000000000 -0400
++++ gcc-4.5.2-new/gcc/tree-vrp.c	2011-11-29 10:20:27.628583820 -0500
+@@ -127,10 +127,10 @@
+ static inline tree
+ vrp_val_max (const_tree type)
+ {
+-  if (!INTEGRAL_TYPE_P (type))
+-    return NULL_TREE;
++  if (INTEGRAL_TYPE_P (type))
++    return upper_bound_in_type (CONST_CAST_TREE (type), CONST_CAST_TREE (type));
+ 
+-  return TYPE_MAX_VALUE (type);
++  return NULL_TREE;
+ }
+ 
+ /* Return the minimum value for TYPE.  */
+@@ -138,10 +138,10 @@
+ static inline tree
+ vrp_val_min (const_tree type)
+ {
+-  if (!INTEGRAL_TYPE_P (type))
+-    return NULL_TREE;
++  if (INTEGRAL_TYPE_P (type))
++    return lower_bound_in_type (CONST_CAST_TREE (type), CONST_CAST_TREE (type));
+ 
+-  return TYPE_MIN_VALUE (type);
++  return NULL_TREE;
+ }
+ 
+ /* Return whether VAL is equal to the maximum value of its type.  This
+@@ -539,7 +539,7 @@
+   set_value_range (vr, VR_RANGE, zero,
+ 		   (overflow_infinity
+ 		    ? positive_overflow_infinity (type)
+-		    : TYPE_MAX_VALUE (type)),
++		    : vrp_val_max (type)),
+ 		   vr->equiv);
+ }
+ 
+@@ -1595,7 +1595,7 @@
+     }
+   else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
+     {
+-      min = TYPE_MIN_VALUE (type);
++      min = vrp_val_min (type);
+ 
+       if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
+ 	max = limit;
+@@ -1630,7 +1630,7 @@
+     }
+   else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
+     {
+-      max = TYPE_MAX_VALUE (type);
++      max = vrp_val_max (type);
+ 
+       if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
+ 	min = limit;
+@@ -2047,11 +2047,11 @@
+ 	  || code == ROUND_DIV_EXPR)
+ 	return (needs_overflow_infinity (TREE_TYPE (res))
+ 		? positive_overflow_infinity (TREE_TYPE (res))
+-		: TYPE_MAX_VALUE (TREE_TYPE (res)));
++		: vrp_val_max (TREE_TYPE (res)));
+       else
+ 	return (needs_overflow_infinity (TREE_TYPE (res))
+ 		? negative_overflow_infinity (TREE_TYPE (res))
+-		: TYPE_MIN_VALUE (TREE_TYPE (res)));
++		: vrp_val_min (TREE_TYPE (res)));
+     }
+ 
+   return res;
+@@ -2750,8 +2750,8 @@
+ 	  && TYPE_PRECISION (inner_type) < TYPE_PRECISION (outer_type))
+ 	{
+ 	  vr0.type = VR_RANGE;
+-	  vr0.min = TYPE_MIN_VALUE (inner_type);
+-	  vr0.max = TYPE_MAX_VALUE (inner_type);
++	  vr0.min = vrp_val_min (inner_type);
++	  vr0.max = vrp_val_max (inner_type);
+ 	}
+ 
+       /* If VR0 is a constant range or anti-range and the conversion is
+@@ -2836,7 +2836,7 @@
+ 	    }
+ 	}
+       else
+-	min = TYPE_MIN_VALUE (type);
++	min = vrp_val_min (type);
+ 
+       if (is_positive_overflow_infinity (vr0.min))
+ 	max = negative_overflow_infinity (type);
+@@ -2855,7 +2855,7 @@
+ 	    }
+ 	}
+       else
+-	max = TYPE_MIN_VALUE (type);
++	max = vrp_val_min (type);
+     }
+   else if (code == NEGATE_EXPR
+ 	   && TYPE_UNSIGNED (type))
+@@ -2897,7 +2897,7 @@
+       else if (!vrp_val_is_min (vr0.min))
+ 	min = fold_unary_to_constant (code, type, vr0.min);
+       else if (!needs_overflow_infinity (type))
+-	min = TYPE_MAX_VALUE (type);
++	min = vrp_val_max (type);
+       else if (supports_overflow_infinity (type))
+ 	min = positive_overflow_infinity (type);
+       else
+@@ -2911,7 +2911,7 @@
+       else if (!vrp_val_is_min (vr0.max))
+ 	max = fold_unary_to_constant (code, type, vr0.max);
+       else if (!needs_overflow_infinity (type))
+-	max = TYPE_MAX_VALUE (type);
++	max = vrp_val_max (type);
+       else if (supports_overflow_infinity (type)
+ 	       /* We shouldn't generate [+INF, +INF] as set_value_range
+ 		  doesn't like this and ICEs.  */
+@@ -2941,7 +2941,7 @@
+ 	         TYPE_MIN_VALUE, remember -TYPE_MIN_VALUE = TYPE_MIN_VALUE.  */
+ 	      if (TYPE_OVERFLOW_WRAPS (type))
+ 		{
+-		  tree type_min_value = TYPE_MIN_VALUE (type);
++		  tree type_min_value = vrp_val_min (type);
+ 
+ 		  min = (vr0.min != type_min_value
+ 			 ? int_const_binop (PLUS_EXPR, type_min_value,
+@@ -2953,7 +2953,7 @@
+ 		  if (overflow_infinity_range_p (&vr0))
+ 		    min = negative_overflow_infinity (type);
+ 		  else
+-		    min = TYPE_MIN_VALUE (type);
++		    min = vrp_val_min (type);
+ 		}
+ 	    }
+ 	  else
+@@ -2974,7 +2974,7 @@
+ 		    }
+ 		}
+ 	      else
+-		max = TYPE_MAX_VALUE (type);
++		max = vrp_val_max (type);
+ 	    }
+ 	}
+ 
+@@ -3258,11 +3258,11 @@
+   if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
+     tmin = lower_bound_in_type (type, type);
+   else
+-    tmin = TYPE_MIN_VALUE (type);
++    tmin = vrp_val_min (type);
+   if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
+     tmax = upper_bound_in_type (type, type);
+   else
+-    tmax = TYPE_MAX_VALUE (type);
++    tmax = vrp_val_max (type);
+ 
+   if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
+     {
+@@ -4146,8 +4146,8 @@
+   if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
+       && INTEGRAL_TYPE_P (TREE_TYPE (val)))
+     {
+-      tree min = TYPE_MIN_VALUE (TREE_TYPE (val));
+-      tree max = TYPE_MAX_VALUE (TREE_TYPE (val));
++      tree min = vrp_val_min (TREE_TYPE (val));
++      tree max = vrp_val_max (TREE_TYPE (val));
+ 
+       if (comp_code == GT_EXPR
+ 	  && (!max
+@@ -6426,13 +6426,13 @@
+ 		 VARYING.  Same if the previous max value was invalid for
+ 		 the type and we'd end up with vr_result.min > vr_result.max.  */
+ 	      if (vrp_val_is_max (vr_result.max)
+-		  || compare_values (TYPE_MIN_VALUE (TREE_TYPE (vr_result.min)),
++		  || compare_values (vrp_val_min (TREE_TYPE (vr_result.min)),
+ 				     vr_result.max) > 0)
+ 		goto varying;
+ 
+ 	      if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
+ 		  || !vrp_var_may_overflow (lhs, phi))
+-		vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
++		vr_result.min = vrp_val_min (TREE_TYPE (vr_result.min));
+ 	      else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
+ 		vr_result.min =
+ 		  negative_overflow_infinity (TREE_TYPE (vr_result.min));
+@@ -6448,13 +6448,13 @@
+ 		 VARYING.  Same if the previous min value was invalid for
+ 		 the type and we'd end up with vr_result.max < vr_result.min.  */
+ 	      if (vrp_val_is_min (vr_result.min)
+-		  || compare_values (TYPE_MAX_VALUE (TREE_TYPE (vr_result.max)),
++		  || compare_values (vrp_val_max (TREE_TYPE (vr_result.max)),
+ 				     vr_result.min) < 0)
+ 		goto varying;
+ 
+ 	      if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
+ 		  || !vrp_var_may_overflow (lhs, phi))
+-		vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
++		vr_result.max = vrp_val_max (TREE_TYPE (vr_result.max));
+ 	      else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
+ 		vr_result.max =
+ 		  positive_overflow_infinity (TREE_TYPE (vr_result.max));
+@@ -6782,7 +6782,7 @@
+     {
+       /* This should not be negative infinity; there is no overflow
+ 	 here.  */
+-      min = TYPE_MIN_VALUE (TREE_TYPE (op0));
++      min = vrp_val_min (TREE_TYPE (op0));
+ 
+       max = op1;
+       if (cond_code == LT_EXPR && !is_overflow_infinity (max))
+@@ -6797,7 +6797,7 @@
+     {
+       /* This should not be positive infinity; there is no overflow
+ 	 here.  */
+-      max = TYPE_MAX_VALUE (TREE_TYPE (op0));
++      max = vrp_val_max (TREE_TYPE (op0));
+ 
+       min = op1;
+       if (cond_code == GT_EXPR && !is_overflow_infinity (min))
new file mode 100644
--- /dev/null
+++ b/build/unix/build-toolchain/r159628-r163231-r171807.patch
@@ -0,0 +1,98 @@
+diff -ru gcc-4.5.2/libstdc++-v3/include/bits/stl_pair.h gcc-4.5.2-new/libstdc++-v3/include/bits/stl_pair.h
+--- gcc-4.5.2/libstdc++-v3/include/bits/stl_pair.h	2010-06-10 06:26:14.000000000 -0400
++++ gcc-4.5.2-new/libstdc++-v3/include/bits/stl_pair.h	2011-11-29 10:25:51.203597393 -0500
+@@ -88,6 +88,8 @@
+       : first(__a), second(__b) { }
+ 
+ #ifdef __GXX_EXPERIMENTAL_CXX0X__
++      pair(const pair&) = default;
++
+       // DR 811.
+       template<class _U1, class = typename
+ 	       std::enable_if<std::is_convertible<_U1, _T1>::value>::type>
+@@ -131,6 +133,15 @@
+ 
+       template<class _U1, class _U2>
+         pair&
++        operator=(const pair<_U1, _U2>& __p)
++	{
++	  first = __p.first;
++	  second = __p.second;
++	  return *this;
++	}
++
++      template<class _U1, class _U2>
++        pair&
+         operator=(pair<_U1, _U2>&& __p)
+ 	{
+ 	  first = std::move(__p.first);
+diff -ru gcc-4.5.2/libstdc++-v3/include/bits/stl_queue.h gcc-4.5.2-new/libstdc++-v3/include/bits/stl_queue.h
+--- gcc-4.5.2/libstdc++-v3/include/bits/stl_queue.h	2010-02-04 13:20:34.000000000 -0500
++++ gcc-4.5.2-new/libstdc++-v3/include/bits/stl_queue.h	2011-11-29 10:26:22.511695475 -0500
+@@ -1,6 +1,6 @@
+ // Queue implementation -*- C++ -*-
+ 
+-// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
++// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ // Free Software Foundation, Inc.
+ //
+ // This file is part of the GNU ISO C++ Library.  This library is free
+@@ -137,16 +137,6 @@
+       explicit
+       queue(_Sequence&& __c = _Sequence())
+       : c(std::move(__c)) { }
+-
+-      queue(queue&& __q)
+-      : c(std::move(__q.c)) { }
+-
+-      queue&
+-      operator=(queue&& __q)
+-      {
+-	c = std::move(__q.c);
+-	return *this;
+-      }
+ #endif
+ 
+       /**
+@@ -451,17 +441,6 @@
+ 	  c.insert(c.end(), __first, __last);
+ 	  std::make_heap(c.begin(), c.end(), comp);
+ 	}
+-
+-      priority_queue(priority_queue&& __pq)
+-      : c(std::move(__pq.c)), comp(std::move(__pq.comp)) { }
+-
+-      priority_queue&
+-      operator=(priority_queue&& __pq)
+-      {
+-	c = std::move(__pq.c);
+-	comp = std::move(__pq.comp);
+-	return *this;
+-      }
+ #endif
+ 
+       /**
+diff -ru gcc-4.5.2/libstdc++-v3/libsupc++/exception_ptr.h gcc-4.5.2-new/libstdc++-v3/libsupc++/exception_ptr.h
+--- gcc-4.5.2/libstdc++-v3/libsupc++/exception_ptr.h	2009-11-09 17:09:30.000000000 -0500
++++ gcc-4.5.2-new/libstdc++-v3/libsupc++/exception_ptr.h	2011-11-29 10:26:10.878659023 -0500
+@@ -129,7 +129,7 @@
+       operator==(const exception_ptr&, const exception_ptr&) throw() 
+       __attribute__ ((__pure__));
+ 
+-      const type_info*
++      const class type_info*
+       __cxa_exception_type() const throw() __attribute__ ((__pure__));
+     };
+ 
+diff -ru gcc-4.5.2/libstdc++-v3/libsupc++/nested_exception.h gcc-4.5.2-new/libstdc++-v3/libsupc++/nested_exception.h
+--- gcc-4.5.2/libstdc++-v3/libsupc++/nested_exception.h	2010-02-18 12:20:16.000000000 -0500
++++ gcc-4.5.2-new/libstdc++-v3/libsupc++/nested_exception.h	2011-11-29 10:26:10.879659026 -0500
+@@ -119,7 +119,7 @@
+   // with a type that has an accessible nested_exception base.
+   template<typename _Ex>
+     inline void
+-    __throw_with_nested(_Ex&& __ex, const nested_exception* = 0)
++    __throw_with_nested(_Ex&& __ex, const nested_exception*)
+     { throw __ex; }
+ 
+   template<typename _Ex>