diff mbox

wide-int, c front end

Message ID EA75EC17-247E-45D9-B98F-45EEB98D815D@comcast.net
State New
Headers show

Commit Message

Mike Stump Nov. 23, 2013, 7:20 p.m. UTC
Richi has asked the we break the wide-int patch so that the individual port and front end maintainers can review their parts without have to go through the entire patch.    This patch covers the c front end.

Ok?
c:
	* c-decl.c
	(check_bitfield_type_and_width): Use TYPE_SIGN.
	(finish_enum): Use wide-int interfaces.
	* c-parser.c
	(c_parser_cilk_clause_vectorlength): Use wide-int interfaces.
	* c-typeck.c
	(build_c_cast): Use wide-int interfaces.
	(set_nonincremental_init_from_string): Likewise.
	(c_tree_equal): Likewise.


c-family:
	* c-ada-spec.c: Include wide-int.h.
	(ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX): Remove.
	(dump_generic_ada_node): Use wide-int interfaces.
	* c-common.c: Include wide-int-print.h.
	(shorten_compare): Use wide-int interfaces.
	(pointer_int_sum): Likewise.
	(c_common_nodes_and_builtins): Use make_int_cst.
	(match_case_to_enum_1): Use tree_fits_uhwi_p and tree_fits_shwi_p.
	(handle_alloc_size_attribute): Use wide-int interfaces.
	(get_nonnull_operand): Likewise.
	* c-format.c
	(get_constant): Use tree_fits_uhwi_p.
	* c-lex.c: Include wide-int.h.
	(narrowest_unsigned_type): Take a widest_int rather than two
	HOST_WIDE_INTs.
	(narrowest_signed_type): Likewise.
	(interpret_integer): Update accordingly.  Use wide-int interfaces.
	(lex_charconst): Use wide-int interfaces.
	* c-pretty-print.c: Include wide-int.h.
	(pp_c_integer_constant): Use wide-int interfaces.
	* cilk.c
	(declare_one_free_variable): Use INT_CST_LT instead of
	INT_CST_LT_UNSIGNED.

Comments

Joseph Myers Nov. 25, 2013, 4:45 p.m. UTC | #1
On Sat, 23 Nov 2013, Mike Stump wrote:

> Richi has asked the we break the wide-int patch so that the individual 
> port and front end maintainers can review their parts without have to go 
> through the entire patch.  This patch covers the c front end.
> 
> Ok?

OK.
diff mbox

Patch

diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 1724c74..e194d28 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -29,21 +29,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "cpplib.h"
 #include "c-pragma.h"
 #include "cpp-id-data.h"
-
-/* Adapted from hwint.h to use the Ada prefix.  */
-#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
-# if HOST_BITS_PER_WIDE_INT == 64
-#  define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
-     "16#%" HOST_LONG_FORMAT "x%016" HOST_LONG_FORMAT "x#"
-# else
-#  define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
-     "16#%" HOST_LONG_FORMAT "x%08" HOST_LONG_FORMAT "x#"
-# endif
-#else
-  /* We can assume that 'long long' is at least 64 bits.  */
-# define ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX \
-    "16#%" HOST_LONG_LONG_FORMAT "x%016" HOST_LONG_LONG_FORMAT "x#"
-#endif /* HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG */
+#include "wide-int.h"
 
 /* Local functions, macros and variables.  */
 static int dump_generic_ada_node (pretty_printer *, tree, tree, int, int,
@@ -2211,19 +2197,18 @@  dump_generic_ada_node (pretty_printer *buffer, tree node, tree type, int spc,
 	pp_unsigned_wide_integer (buffer, tree_to_uhwi (node));
       else
 	{
-	  tree val = node;
-	  unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (val);
-	  HOST_WIDE_INT high = TREE_INT_CST_HIGH (val);
-
-	  if (tree_int_cst_sgn (val) < 0)
+	  wide_int val = node;
+	  int i;
+	  if (wi::neg_p (val))
 	    {
 	      pp_minus (buffer);
-	      high = ~high + !low;
-	      low = -low;
+	      val = -val;
 	    }
 	  sprintf (pp_buffer (buffer)->digit_buffer,
-		   ADA_HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-		   (unsigned HOST_WIDE_INT) high, low);
+		   "16#%" HOST_LONG_FORMAT "x", val.elt (val.get_len () - 1));
+	  for (i = val.get_len () - 2; i <= 0; i--)
+	    sprintf (pp_buffer (buffer)->digit_buffer,
+		     HOST_WIDE_INT_PRINT_PADDED_HEX, val.elt (i));
 	  pp_string (buffer, pp_buffer (buffer)->digit_buffer);
 	}
       break;
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 97f33c1..e5e9389 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -51,6 +51,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "target-def.h"
 #include "gimple.h"
 #include "gimplify.h"
+#include "wide-int-print.h"
 
 cpp_reader *parse_in;		/* Declared in c-pragma.h.  */
 
@@ -4117,9 +4118,12 @@  shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
 	{
 	  /* Convert primop1 to target type, but do not introduce
 	     additional overflow.  We know primop1 is an int_cst.  */
-	  primop1 = force_fit_type_double (*restype_ptr,
-					   tree_to_double_int (primop1),
-					   0, TREE_OVERFLOW (primop1));
+	  primop1 = force_fit_type (*restype_ptr,
+				    wide_int::from
+				      (primop1,
+				       TYPE_PRECISION (*restype_ptr),
+				       TYPE_SIGN (TREE_TYPE (primop1))),
+				    0, TREE_OVERFLOW (primop1));
 	}
       if (type != *restype_ptr)
 	{
@@ -4127,20 +4131,10 @@  shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
 	  maxval = convert (*restype_ptr, maxval);
 	}
 
-      if (unsignedp && unsignedp0)
-	{
-	  min_gt = INT_CST_LT_UNSIGNED (primop1, minval);
-	  max_gt = INT_CST_LT_UNSIGNED (primop1, maxval);
-	  min_lt = INT_CST_LT_UNSIGNED (minval, primop1);
-	  max_lt = INT_CST_LT_UNSIGNED (maxval, primop1);
-	}
-      else
-	{
-	  min_gt = INT_CST_LT (primop1, minval);
-	  max_gt = INT_CST_LT (primop1, maxval);
-	  min_lt = INT_CST_LT (minval, primop1);
-	  max_lt = INT_CST_LT (maxval, primop1);
-	}
+      min_gt = INT_CST_LT (primop1, minval);
+      max_gt = INT_CST_LT (primop1, maxval);
+      min_lt = INT_CST_LT (minval, primop1);
+      max_lt = INT_CST_LT (maxval, primop1);
 
       val = 0;
       /* This used to be a switch, but Genix compiler can't handle that.  */
@@ -4431,8 +4425,7 @@  pointer_int_sum (location_t loc, enum tree_code resultcode,
 			      convert (TREE_TYPE (intop), size_exp), 1);
     intop = convert (sizetype, t);
     if (TREE_OVERFLOW_P (intop) && !TREE_OVERFLOW (t))
-      intop = build_int_cst_wide (TREE_TYPE (intop), TREE_INT_CST_LOW (intop),
-				  TREE_INT_CST_HIGH (intop));
+      intop = wide_int_to_tree (TREE_TYPE (intop), intop);
   }
 
   /* Create the sum or difference.  */
@@ -5490,7 +5483,7 @@  c_common_nodes_and_builtins (void)
   }
 
   /* This node must not be shared.  */
-  void_zero_node = make_node (INTEGER_CST);
+  void_zero_node = make_int_cst (1, 1);
   TREE_TYPE (void_zero_node) = void_type_node;
 
   void_list_node = build_void_list_node ();
@@ -5701,7 +5694,7 @@  c_common_nodes_and_builtins (void)
 
   /* Create the built-in __null node.  It is important that this is
      not shared.  */
-  null_node = make_node (INTEGER_CST);
+  null_node = make_int_cst (1, 1);
   TREE_TYPE (null_node) = c_common_type_for_size (POINTER_SIZE, 0);
 
   /* Since builtin_types isn't gc'ed, don't export these nodes.  */
@@ -6079,22 +6072,14 @@  c_add_case_label (location_t loc, splay_tree cases, tree cond, tree orig_type,
 static void
 match_case_to_enum_1 (tree key, tree type, tree label)
 {
-  char buf[2 + 2*HOST_BITS_PER_WIDE_INT/4 + 1];
-
-  /* ??? Not working too hard to print the double-word value.
-     Should perhaps be done with %lwd in the diagnostic routines?  */
-  if (TREE_INT_CST_HIGH (key) == 0)
-    snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_UNSIGNED,
-	      TREE_INT_CST_LOW (key));
-  else if (!TYPE_UNSIGNED (type)
-	   && TREE_INT_CST_HIGH (key) == -1
-	   && TREE_INT_CST_LOW (key) != 0)
-    snprintf (buf, sizeof (buf), "-" HOST_WIDE_INT_PRINT_UNSIGNED,
-	      -TREE_INT_CST_LOW (key));
+  char buf[WIDE_INT_PRINT_BUFFER_SIZE];
+
+  if (tree_fits_uhwi_p (key))
+    print_dec (key, buf, UNSIGNED);
+  else if (tree_fits_shwi_p (key))
+    print_dec (key, buf, SIGNED);
   else
-    snprintf (buf, sizeof (buf), HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-	      (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (key),
-	      (unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (key));
+    print_hex (key, buf);
 
   if (TYPE_NAME (type) == 0)
     warning_at (DECL_SOURCE_LOCATION (CASE_LABEL (label)),
@@ -8020,9 +8005,8 @@  handle_alloc_size_attribute (tree *node, tree ARG_UNUSED (name), tree args,
       tree position = TREE_VALUE (args);
 
       if (TREE_CODE (position) != INTEGER_CST
-	  || TREE_INT_CST_HIGH (position)
-	  || TREE_INT_CST_LOW (position) < 1
-	  || TREE_INT_CST_LOW (position) > arg_count )
+	  || wi::ltu_p (position, 1)
+	  || wi::gtu_p (position, arg_count))
 	{
 	  warning (OPT_Wattributes,
 	           "alloc_size parameter outside range");
@@ -8783,13 +8767,14 @@  check_nonnull_arg (void * ARG_UNUSED (ctx), tree param,
 static bool
 get_nonnull_operand (tree arg_num_expr, unsigned HOST_WIDE_INT *valp)
 {
-  /* Verify the arg number is a constant.  */
-  if (TREE_CODE (arg_num_expr) != INTEGER_CST
-      || TREE_INT_CST_HIGH (arg_num_expr) != 0)
+  /* Verify the arg number is a small constant.  */
+  if (tree_fits_uhwi_p (arg_num_expr))
+    {
+      *valp = TREE_INT_CST_LOW (arg_num_expr);
+      return true;
+    }
+  else
     return false;
-
-  *valp = TREE_INT_CST_LOW (arg_num_expr);
-  return true;
 }
 
 /* Handle a "nothrow" attribute; arguments as in
diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c
index 0552c84..b99e281 100644
--- a/gcc/c-family/c-format.c
+++ b/gcc/c-family/c-format.c
@@ -227,7 +227,7 @@  check_format_string (tree fntype, unsigned HOST_WIDE_INT format_num,
 static bool
 get_constant (tree expr, unsigned HOST_WIDE_INT *value, int validated_p)
 {
-  if (TREE_CODE (expr) != INTEGER_CST || TREE_INT_CST_HIGH (expr) != 0)
+  if (!tree_fits_uhwi_p (expr))
     {
       gcc_assert (!validated_p);
       return false;
diff --git a/gcc/c-family/c-lex.c b/gcc/c-family/c-lex.c
index 85fa426..4594a5a 100644
--- a/gcc/c-family/c-lex.c
+++ b/gcc/c-family/c-lex.c
@@ -35,6 +35,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "splay-tree.h"
 #include "debug.h"
 #include "target.h"
+#include "wide-int.h"
 
 /* We may keep statistics about how long which files took to compile.  */
 static int header_time, body_time;
@@ -49,9 +50,9 @@  static tree interpret_float (const cpp_token *, unsigned int, const char *,
 			     enum overflow_type *);
 static tree interpret_fixed (const cpp_token *, unsigned int);
 static enum integer_type_kind narrowest_unsigned_type
-	(unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
+	(const widest_int &, unsigned int);
 static enum integer_type_kind narrowest_signed_type
-	(unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT, unsigned int);
+	(const widest_int &, unsigned int);
 static enum cpp_ttype lex_string (const cpp_token *, tree *, bool, bool);
 static tree lex_charconst (const cpp_token *);
 static void update_header_times (const char *);
@@ -527,9 +528,7 @@  c_lex_with_flags (tree *value, location_t *loc, unsigned char *cpp_flags,
    there isn't one.  */
 
 static enum integer_type_kind
-narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
-			 unsigned HOST_WIDE_INT high,
-			 unsigned int flags)
+narrowest_unsigned_type (const widest_int &val, unsigned int flags)
 {
   int itk;
 
@@ -548,9 +547,7 @@  narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
 	continue;
       upper = TYPE_MAX_VALUE (integer_types[itk]);
 
-      if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
-	  || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
-	      && TREE_INT_CST_LOW (upper) >= low))
+      if (wi::geu_p (wi::to_widest (upper), val))
 	return (enum integer_type_kind) itk;
     }
 
@@ -559,8 +556,7 @@  narrowest_unsigned_type (unsigned HOST_WIDE_INT low,
 
 /* Ditto, but narrowest signed type.  */
 static enum integer_type_kind
-narrowest_signed_type (unsigned HOST_WIDE_INT low,
-		       unsigned HOST_WIDE_INT high, unsigned int flags)
+narrowest_signed_type (const widest_int &val, unsigned int flags)
 {
   int itk;
 
@@ -571,7 +567,6 @@  narrowest_signed_type (unsigned HOST_WIDE_INT low,
   else
     itk = itk_long_long;
 
-
   for (; itk < itk_none; itk += 2 /* skip signed types */)
     {
       tree upper;
@@ -580,9 +575,7 @@  narrowest_signed_type (unsigned HOST_WIDE_INT low,
 	continue;
       upper = TYPE_MAX_VALUE (integer_types[itk]);
 
-      if ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) > high
-	  || ((unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (upper) == high
-	      && TREE_INT_CST_LOW (upper) >= low))
+      if (wi::geu_p (wi::to_widest (upper), val))
 	return (enum integer_type_kind) itk;
     }
 
@@ -597,6 +590,7 @@  interpret_integer (const cpp_token *token, unsigned int flags,
   tree value, type;
   enum integer_type_kind itk;
   cpp_num integer;
+  HOST_WIDE_INT ival[3];
 
   *overflow = OT_NONE;
 
@@ -604,18 +598,23 @@  interpret_integer (const cpp_token *token, unsigned int flags,
   if (integer.overflow)
     *overflow = OT_OVERFLOW;
 
+  ival[0] = integer.low;
+  ival[1] = integer.high;
+  ival[2] = 0;
+  widest_int wval = widest_int::from_array (ival, 3);
+
   /* The type of a constant with a U suffix is straightforward.  */
   if (flags & CPP_N_UNSIGNED)
-    itk = narrowest_unsigned_type (integer.low, integer.high, flags);
+    itk = narrowest_unsigned_type (wval, flags);
   else
     {
       /* The type of a potentially-signed integer constant varies
 	 depending on the base it's in, the standard in use, and the
 	 length suffixes.  */
       enum integer_type_kind itk_u
-	= narrowest_unsigned_type (integer.low, integer.high, flags);
+	= narrowest_unsigned_type (wval, flags);
       enum integer_type_kind itk_s
-	= narrowest_signed_type (integer.low, integer.high, flags);
+	= narrowest_signed_type (wval, flags);
 
       /* In both C89 and C99, octal and hex constants may be signed or
 	 unsigned, whichever fits tighter.  We do not warn about this
@@ -667,7 +666,7 @@  interpret_integer (const cpp_token *token, unsigned int flags,
 	   : "integer constant is too large for %<long%> type");
     }
 
-  value = build_int_cst_wide (type, integer.low, integer.high);
+  value = wide_int_to_tree (type, wval);
 
   /* Convert imaginary to a complex type.  */
   if (flags & CPP_N_IMAGINARY)
@@ -1165,9 +1164,9 @@  lex_charconst (const cpp_token *token)
   /* Cast to cppchar_signed_t to get correct sign-extension of RESULT
      before possibly widening to HOST_WIDE_INT for build_int_cst.  */
   if (unsignedp || (cppchar_signed_t) result >= 0)
-    value = build_int_cst_wide (type, result, 0);
+    value = build_int_cst (type, result);
   else
-    value = build_int_cst_wide (type, (cppchar_signed_t) result, -1);
+    value = build_int_cst (type, (cppchar_signed_t) result);
 
   return value;
 }
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index d1b5880..bd3b381 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -30,6 +30,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "tree-pretty-print.h"
 #include "tree-iterator.h"
 #include "diagnostic.h"
+#include "wide-int-print.h"
 
 /* The pretty-printer code is primarily designed to closely follow
    (GNU) C and C++ grammars.  That is to be contrasted with spaghetti
@@ -923,16 +924,14 @@  pp_c_integer_constant (c_pretty_printer *pp, tree i)
     pp_unsigned_wide_integer (pp, tree_to_uhwi (i));
   else
     {
-      unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (i);
-      HOST_WIDE_INT high = TREE_INT_CST_HIGH (i);
-      if (tree_int_cst_sgn (i) < 0)
+      wide_int wi = i;
+
+      if (wi::lt_p (i, 0, TYPE_SIGN (TREE_TYPE (i))))
 	{
 	  pp_minus (pp);
-	  high = ~high + !low;
-	  low = -low;
+	  wi = -wi;
 	}
-      sprintf (pp_buffer (pp)->digit_buffer, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
-	       (unsigned HOST_WIDE_INT) high, (unsigned HOST_WIDE_INT) low);
+      print_hex (wi, pp_buffer (pp)->digit_buffer);
       pp_string (pp, pp_buffer (pp)->digit_buffer);
     }
   if (TYPE_UNSIGNED (type))
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index 894a352..a663c45 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -665,8 +665,7 @@  declare_one_free_variable (const void *var0, void **map0,
 
   /* Maybe promote to int.  */
   if (INTEGRAL_TYPE_P (var_type) && COMPLETE_TYPE_P (var_type)
-      && INT_CST_LT_UNSIGNED (TYPE_SIZE (var_type),
-			      TYPE_SIZE (integer_type_node)))
+      && INT_CST_LT (TYPE_SIZE (var_type), TYPE_SIZE (integer_type_node)))
     arg_type = integer_type_node;
   else
     arg_type = var_type;
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 4125bd9..d2d54b0 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -4843,8 +4843,8 @@  check_bitfield_type_and_width (tree *type, tree *width, tree orig_name)
     {
       struct lang_type *lt = TYPE_LANG_SPECIFIC (*type);
       if (!lt
-	  || w < tree_int_cst_min_precision (lt->enum_min, TYPE_UNSIGNED (*type))
-	  || w < tree_int_cst_min_precision (lt->enum_max, TYPE_UNSIGNED (*type)))
+	  || w < tree_int_cst_min_precision (lt->enum_min, TYPE_SIGN (*type))
+	  || w < tree_int_cst_min_precision (lt->enum_max, TYPE_SIGN (*type)))
 	warning (0, "%qs is narrower than values of its type", name);
     }
 }
@@ -7565,7 +7565,8 @@  finish_enum (tree enumtype, tree values, tree attributes)
 {
   tree pair, tem;
   tree minnode = 0, maxnode = 0;
-  int precision, unsign;
+  int precision;
+  signop sign;
   bool toplevel = (file_scope == current_scope);
   struct lang_type *lt;
 
@@ -7592,13 +7593,13 @@  finish_enum (tree enumtype, tree values, tree attributes)
      as one of the integral types - the narrowest one that fits, except
      that normally we only go as narrow as int - and signed iff any of
      the values are negative.  */
-  unsign = (tree_int_cst_sgn (minnode) >= 0);
-  precision = MAX (tree_int_cst_min_precision (minnode, unsign),
-		   tree_int_cst_min_precision (maxnode, unsign));
+  sign = (tree_int_cst_sgn (minnode) >= 0) ? UNSIGNED : SIGNED;
+  precision = MAX (tree_int_cst_min_precision (minnode, sign),
+		   tree_int_cst_min_precision (maxnode, sign));
 
   if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
     {
-      tem = c_common_type_for_size (precision, unsign);
+      tem = c_common_type_for_size (precision, sign == UNSIGNED ? 1 : 0);
       if (tem == NULL)
 	{
 	  warning (0, "enumeration values exceed range of largest integer");
@@ -7606,7 +7607,7 @@  finish_enum (tree enumtype, tree values, tree attributes)
 	}
     }
   else
-    tem = unsign ? unsigned_type_node : integer_type_node;
+    tem = sign == UNSIGNED ? unsigned_type_node : integer_type_node;
 
   TYPE_MIN_VALUE (enumtype) = TYPE_MIN_VALUE (tem);
   TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index ea3aa9a..d08d1d0 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -13380,7 +13380,7 @@  c_parser_cilk_clause_vectorlength (c_parser *parser, tree clauses)
       || !TREE_CONSTANT (expr)
       || !INTEGRAL_TYPE_P (TREE_TYPE (expr)))
     error_at (loc, "vectorlength must be an integer constant");
-  else if (exact_log2 (TREE_INT_CST_LOW (expr)) == -1)
+  else if (wi::exact_log2 (expr) == -1)
     error_at (loc, "vectorlength must be a power of 2");
   else
     {
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 8e74b7b..7a0d664 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -47,6 +47,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "c-family/c-objc.h"
 #include "c-family/c-common.h"
 #include "c-family/c-ubsan.h"
+#include "wide-int.h"
 
 /* Possible cases of implicit bad conversions.  Used to select
    diagnostic messages in convert_for_assignment.  */
@@ -5098,9 +5099,7 @@  build_c_cast (location_t loc, tree type, tree expr)
 	    }
 	  else if (TREE_OVERFLOW (value))
 	    /* Reset VALUE's overflow flags, ensuring constant sharing.  */
-	    value = build_int_cst_wide (TREE_TYPE (value),
-					TREE_INT_CST_LOW (value),
-					TREE_INT_CST_HIGH (value));
+	    value = wide_int_to_tree (TREE_TYPE (value), value);
 	}
     }
 
@@ -8013,20 +8012,20 @@  set_nonincremental_init_from_string (tree str,
     {
       if (wchar_bytes == 1)
 	{
-	  val[1] = (unsigned char) *p++;
-	  val[0] = 0;
+	  val[0] = (unsigned char) *p++;
+	  val[1] = 0;
 	}
       else
 	{
-	  val[0] = 0;
 	  val[1] = 0;
+	  val[0] = 0;
 	  for (byte = 0; byte < wchar_bytes; byte++)
 	    {
 	      if (BYTES_BIG_ENDIAN)
 		bitpos = (wchar_bytes - byte - 1) * charwidth;
 	      else
 		bitpos = byte * charwidth;
-	      val[bitpos < HOST_BITS_PER_WIDE_INT]
+	      val[bitpos % HOST_BITS_PER_WIDE_INT]
 		|= ((unsigned HOST_WIDE_INT) ((unsigned char) *p++))
 		   << (bitpos % HOST_BITS_PER_WIDE_INT);
 	    }
@@ -8037,24 +8036,26 @@  set_nonincremental_init_from_string (tree str,
 	  bitpos = ((wchar_bytes - 1) * charwidth) + HOST_BITS_PER_CHAR;
 	  if (bitpos < HOST_BITS_PER_WIDE_INT)
 	    {
-	      if (val[1] & (((HOST_WIDE_INT) 1) << (bitpos - 1)))
+	      if (val[0] & (((HOST_WIDE_INT) 1) << (bitpos - 1)))
 		{
-		  val[1] |= ((HOST_WIDE_INT) -1) << bitpos;
-		  val[0] = -1;
+		  val[0] |= ((HOST_WIDE_INT) -1) << bitpos;
+		  val[1] = -1;
 		}
 	    }
 	  else if (bitpos == HOST_BITS_PER_WIDE_INT)
 	    {
-	      if (val[1] < 0)
-		val[0] = -1;
+	      if (val[0] < 0)
+		val[1] = -1;
 	    }
-	  else if (val[0] & (((HOST_WIDE_INT) 1)
+	  else if (val[1] & (((HOST_WIDE_INT) 1)
 			     << (bitpos - 1 - HOST_BITS_PER_WIDE_INT)))
-	    val[0] |= ((HOST_WIDE_INT) -1)
+	    val[1] |= ((HOST_WIDE_INT) -1)
 		      << (bitpos - HOST_BITS_PER_WIDE_INT);
 	}
 
-      value = build_int_cst_wide (type, val[1], val[0]);
+      value = wide_int_to_tree (type,
+				wide_int::from_array (val, 2,
+						      HOST_BITS_PER_WIDE_INT * 2));
       add_pending_init (purpose, value, NULL_TREE, true,
                         braced_init_obstack);
     }
@@ -12257,8 +12258,7 @@  c_tree_equal (tree t1, tree t2)
   switch (code1)
     {
     case INTEGER_CST:
-      return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2)
-	&& TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2);
+      return wi::eq_p (t1, t2);
 
     case REAL_CST:
       return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2));