]> gcc.gnu.org Git - gcc.git/commitdiff
compiler, runtime: Check make int64 args for overflow.
authorIan Lance Taylor <ian@gcc.gnu.org>
Wed, 8 Feb 2012 06:18:41 +0000 (06:18 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Wed, 8 Feb 2012 06:18:41 +0000 (06:18 +0000)
From-SVN: r183994

gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/runtime.def
libgo/runtime/chan.c
libgo/runtime/go-make-slice.c
libgo/runtime/go-new-map.c

index f906b2206eaa856c495121f640bac9877111702d..395a37547dd8b08f0c3e4ddba703c32d25510e76 100644 (file)
@@ -7744,6 +7744,10 @@ Builtin_call_expression::lower_make()
       return Expression::make_error(this->location());
     }
 
+  bool have_big_args = false;
+  Type* uintptr_type = Type::lookup_integer_type("uintptr");
+  int uintptr_bits = uintptr_type->integer_type()->bits();
+
   ++parg;
   Expression* len_arg;
   if (parg == args->end())
@@ -7767,6 +7771,9 @@ Builtin_call_expression::lower_make()
          this->report_error(_("bad size for make"));
          return Expression::make_error(this->location());
        }
+      if (len_arg->type()->integer_type() != NULL
+         && len_arg->type()->integer_type()->bits() > uintptr_bits)
+       have_big_args = true;
       ++parg;
     }
 
@@ -7779,6 +7786,9 @@ Builtin_call_expression::lower_make()
          this->report_error(_("bad capacity when making slice"));
          return Expression::make_error(this->location());
        }
+      if (cap_arg->type()->integer_type() != NULL
+         && cap_arg->type()->integer_type()->bits() > uintptr_bits)
+       have_big_args = true;
       ++parg;
     }
 
@@ -7801,16 +7811,26 @@ Builtin_call_expression::lower_make()
   if (is_slice)
     {
       if (cap_arg == NULL)
-       call = Runtime::make_call(Runtime::MAKESLICE1, loc, 2, type_arg,
-                                 len_arg);
+       call = Runtime::make_call((have_big_args
+                                  ? Runtime::MAKESLICE1BIG
+                                  : Runtime::MAKESLICE1),
+                                 loc, 2, type_arg, len_arg);
       else
-       call = Runtime::make_call(Runtime::MAKESLICE2, loc, 3, type_arg,
-                                 len_arg, cap_arg);
+       call = Runtime::make_call((have_big_args
+                                  ? Runtime::MAKESLICE2BIG
+                                  : Runtime::MAKESLICE2),
+                                 loc, 3, type_arg, len_arg, cap_arg);
     }
   else if (is_map)
-    call = Runtime::make_call(Runtime::MAKEMAP, loc, 2, type_arg, len_arg);
+    call = Runtime::make_call((have_big_args
+                              ? Runtime::MAKEMAPBIG
+                              : Runtime::MAKEMAP),
+                             loc, 2, type_arg, len_arg);
   else if (is_chan)
-    call = Runtime::make_call(Runtime::MAKECHAN, loc, 2, type_arg, len_arg);
+    call = Runtime::make_call((have_big_args
+                              ? Runtime::MAKECHANBIG
+                              : Runtime::MAKECHAN),
+                             loc, 2, type_arg, len_arg);
   else
     go_unreachable();
 
index 57d509006c32b5da20845118268c895a8b43e8a1..7dda5398cfb3356ba17af862cc680964218254a2 100644 (file)
@@ -72,10 +72,16 @@ DEF_GO_RUNTIME(STRING_TO_INT_ARRAY, "__go_string_to_int_array",
 DEF_GO_RUNTIME(MAKESLICE1, "__go_make_slice1", P2(TYPE, UINTPTR), R1(SLICE))
 DEF_GO_RUNTIME(MAKESLICE2, "__go_make_slice2", P3(TYPE, UINTPTR, UINTPTR),
               R1(SLICE))
+DEF_GO_RUNTIME(MAKESLICE1BIG, "__go_make_slice1_big", P2(TYPE, UINT64),
+              R1(SLICE))
+DEF_GO_RUNTIME(MAKESLICE2BIG, "__go_make_slice2_big", P3(TYPE, UINT64, UINT64),
+              R1(SLICE))
 
 
 // Make a map.
 DEF_GO_RUNTIME(MAKEMAP, "__go_new_map", P2(MAPDESCRIPTOR, UINTPTR), R1(MAP))
+DEF_GO_RUNTIME(MAKEMAPBIG, "__go_new_map_big", P2(MAPDESCRIPTOR, UINT64),
+              R1(MAP))
 
 // Build a map from a composite literal.
 DEF_GO_RUNTIME(CONSTRUCT_MAP, "__go_construct_map",
@@ -116,6 +122,7 @@ DEF_GO_RUNTIME(MAPITERNEXT, "runtime.mapiternext", P1(MAPITER), R0())
 
 // Make a channel.
 DEF_GO_RUNTIME(MAKECHAN, "__go_new_channel", P2(TYPE, UINTPTR), R1(CHAN))
+DEF_GO_RUNTIME(MAKECHANBIG, "__go_new_channel_big", P2(TYPE, UINT64), R1(CHAN))
 
 // Get the length of a channel (the number of unread values).
 DEF_GO_RUNTIME(CHAN_LEN, "__go_chan_len", P1(CHAN), R1(INT))
index a246992c60b4111e50789b663bda62b3855686b0..4fc2d60365958aca9b711097d927aa5b4800dc47 100644 (file)
@@ -130,6 +130,12 @@ __go_new_channel(ChanType *t, uintptr hint)
        return runtime_makechan_c(t, hint);
 }
 
+Hchan*
+__go_new_channel_big(ChanType *t, uint64 hint)
+{
+       return runtime_makechan_c(t, hint);
+}
+
 /*
  * generic single channel send/recv
  * if the bool pointer is nil,
index 765e7c021b7cdaaa3c0080b7319a1e6ec50983a6..42b412c772b000b2b033d2e537c8ae7ef0645768 100644 (file)
@@ -57,3 +57,27 @@ __go_make_slice1 (const struct __go_type_descriptor *td, uintptr_t len)
 {
   return __go_make_slice2 (td, len, len);
 }
+
+struct __go_open_array
+__go_make_slice2_big (const struct __go_type_descriptor *td, uint64_t len,
+                     uint64_t cap)
+{
+  uintptr_t slen;
+  uintptr_t scap;
+
+  slen = (uintptr_t) len;
+  if ((uint64_t) slen != len)
+    runtime_panicstring ("makeslice: len out of range");
+
+  scap = (uintptr_t) cap;
+  if ((uint64_t) scap != cap)
+    runtime_panicstring ("makeslice: cap out of range");
+
+  return __go_make_slice2 (td, slen, scap);
+}
+
+struct __go_open_array
+__go_make_slice1_big (const struct __go_type_descriptor *td, uint64_t len)
+{
+  return __go_make_slice2_big (td, len, len);
+}
index 288e1883f9d4f0296e4bed72b5694699430bba54..eef71ddf47c4120a049086b3bde1d0e7f53127e2 100644 (file)
@@ -125,3 +125,17 @@ __go_new_map (const struct __go_map_descriptor *descriptor, uintptr_t entries)
   __builtin_memset (ret->__buckets, 0, entries * sizeof (void *));
   return ret;
 }
+
+/* Allocate a new map when the argument to make is a large type.  */
+
+struct __go_map *
+__go_new_map_big (const struct __go_map_descriptor *descriptor,
+                 uint64_t entries)
+{
+  uintptr_t sentries;
+
+  sentries = (uintptr_t) entries;
+  if ((uint64_t) sentries != entries)
+    runtime_panicstring ("map size out of range");
+  return __go_new_map (descriptor, sentries);
+}
This page took 0.088268 seconds and 5 git commands to generate.