Change builtin make to runtime call at lowering time.
authorIan Lance Taylor <iant@google.com>
Tue, 14 Jun 2011 05:53:10 +0000 (05:53 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Tue, 14 Jun 2011 05:53:10 +0000 (05:53 +0000)
Use kindNoPointers as 6g does.

* Make-lang.in (go/expressions.o): Depend on $(GO_RUNTIME_H).

From-SVN: r175008

16 files changed:
gcc/go/ChangeLog
gcc/go/Make-lang.in
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/go/gofrontend/runtime.cc
gcc/go/gofrontend/runtime.def
gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h
libgo/Makefile.am
libgo/Makefile.in
libgo/runtime/go-new-channel.c
libgo/runtime/go-new-map.c
libgo/runtime/go-reflect-call.c
libgo/runtime/go-reflect-chan.c
libgo/runtime/go-reflect.c
libgo/runtime/go-type.h

index 11abbbcd42130b1997f8ec735d7a491410ddaa5a..a5e56b14f689f2d7f791db22ed8d8af072c37b99 100644 (file)
@@ -1,3 +1,7 @@
+2011-06-13  Ian Lance Taylor  <iant@google.com>
+
+       * Make-lang.in (go/expressions.o): Depend on $(GO_RUNTIME_H).
+
 2011-06-10  Ian Lance Taylor  <iant@google.com>
 
        * go-gcc.cc: Include "toplev.h".
index 61a0f3c875a2954eff8ec8e8593609860c47e5ec..51760bf510710da13de0710101467a680283b7b4 100644 (file)
@@ -255,7 +255,7 @@ go/expressions.o: go/gofrontend/expressions.cc $(GO_SYSTEM_H) $(TOPLEV_H) \
        intl.h $(TREE_H) $(GIMPLE_H) tree-iterator.h convert.h $(REAL_H) \
        realmpfr.h $(GO_C_H) $(GO_GOGO_H) $(GO_TYPES_H) \
        go/gofrontend/export.h $(GO_IMPORT_H) $(GO_STATEMENTS_H) $(GO_LEX_H) \
-       go/gofrontend/backend.h $(GO_EXPRESSIONS_H)
+       $(GO_RUNTIME_H) go/gofrontend/backend.h $(GO_EXPRESSIONS_H)
 go/go.o: go/gofrontend/go.cc $(GO_SYSTEM_H) $(GO_C_H) $(GO_LEX_H) \
        $(GO_PARSE_H) go/gofrontend/backend.h $(GO_GOGO_H)
 go/go-dump.o: go/gofrontend/go-dump.cc $(GO_SYSTEM_H) $(GO_C_H) \
index 9c6af0b77626574c2a674d84d258bbbeb190d113..bd437c4ce4c8828a72323bcb0eab6d96cc3a9b2b 100644 (file)
@@ -33,6 +33,7 @@ extern "C"
 #include "import.h"
 #include "statements.h"
 #include "lex.h"
+#include "runtime.h"
 #include "backend.h"
 #include "expressions.h"
 
@@ -3592,7 +3593,7 @@ class Unsafe_type_conversion_expression : public Expression
 
   void
   do_determine_type(const Type_context*)
-  { }
+  { this->expr_->determine_type_no_context(); }
 
   Expression*
   do_copy()
@@ -6739,6 +6740,12 @@ class Builtin_call_expression : public Call_expression
   static Type*
   complex_type(Type*);
 
+  Expression*
+  lower_make();
+
+  bool
+  check_int_value(Expression*);
+
   // A pointer back to the general IR structure.  This avoids a global
   // variable, or passing it around everywhere.
   Gogo* gogo_;
@@ -6859,6 +6866,9 @@ Find_call_expression::expression(Expression** pexpr)
 Expression*
 Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, int)
 {
+  if (this->classification() == EXPRESSION_ERROR)
+    return this;
+
   if (this->is_varargs() && this->code_ != BUILTIN_APPEND)
     {
       this->report_error(_("invalid use of %<...%> with builtin function"));
@@ -6885,36 +6895,7 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, int)
        }
     }
   else if (this->code_ == BUILTIN_MAKE)
-    {
-      const Expression_list* args = this->args();
-      if (args == NULL || args->size() < 1)
-       this->report_error(_("not enough arguments"));
-      else
-       {
-         Expression* arg = args->front();
-         if (!arg->is_type_expression())
-           {
-             error_at(arg->location(), "expected type");
-             this->set_is_error();
-           }
-         else
-           {
-             Expression_list* newargs;
-             if (args->size() == 1)
-               newargs = NULL;
-             else
-               {
-                 newargs = new Expression_list();
-                 Expression_list::const_iterator p = args->begin();
-                 ++p;
-                 for (; p != args->end(); ++p)
-                   newargs->push_back(*p);
-               }
-             return Expression::make_make(arg->type(), newargs,
-                                          this->location());
-           }
-       }
-    }
+    return this->lower_make();
   else if (this->is_constant())
     {
       // We can only lower len and cap if there are no function calls
@@ -6999,6 +6980,170 @@ Builtin_call_expression::do_lower(Gogo* gogo, Named_object* function, int)
   return this;
 }
 
+// Lower a make expression.
+
+Expression*
+Builtin_call_expression::lower_make()
+{
+  source_location loc = this->location();
+
+  const Expression_list* args = this->args();
+  if (args == NULL || args->size() < 1)
+    {
+      this->report_error(_("not enough arguments"));
+      return Expression::make_error(this->location());
+    }
+
+  Expression_list::const_iterator parg = args->begin();
+
+  Expression* first_arg = *parg;
+  if (!first_arg->is_type_expression())
+    {
+      error_at(first_arg->location(), "expected type");
+      this->set_is_error();
+      return Expression::make_error(this->location());
+    }
+  Type* type = first_arg->type();
+
+  bool is_slice = false;
+  bool is_map = false;
+  bool is_chan = false;
+  if (type->is_open_array_type())
+    is_slice = true;
+  else if (type->map_type() != NULL)
+    is_map = true;
+  else if (type->channel_type() != NULL)
+    is_chan = true;
+  else
+    {
+      this->report_error(_("invalid type for make function"));
+      return Expression::make_error(this->location());
+    }
+
+  ++parg;
+  Expression* len_arg;
+  if (parg == args->end())
+    {
+      if (is_slice)
+       {
+         this->report_error(_("length required when allocating a slice"));
+         return Expression::make_error(this->location());
+       }
+
+      mpz_t zval;
+      mpz_init_set_ui(zval, 0);
+      len_arg = Expression::make_integer(&zval, NULL, loc);
+      mpz_clear(zval);
+    }
+  else
+    {
+      len_arg = *parg;
+      if (!this->check_int_value(len_arg))
+       {
+         this->report_error(_("bad size for make"));
+         return Expression::make_error(this->location());
+       }
+      ++parg;
+    }
+
+  Expression* cap_arg = NULL;
+  if (is_slice && parg != args->end())
+    {
+      cap_arg = *parg;
+      if (!this->check_int_value(cap_arg))
+       {
+         this->report_error(_("bad capacity when making slice"));
+         return Expression::make_error(this->location());
+       }
+      ++parg;
+    }
+
+  if (parg != args->end())
+    {
+      this->report_error(_("too many arguments to make"));
+      return Expression::make_error(this->location());
+    }
+
+  source_location type_loc = first_arg->location();
+  Expression* type_arg;
+  if (is_slice || is_chan)
+    type_arg = Expression::make_type_descriptor(type, type_loc);
+  else if (is_map)
+    type_arg = Expression::make_map_descriptor(type->map_type(), type_loc);
+  else
+    go_unreachable();
+
+  Expression* call;
+  if (is_slice)
+    {
+      if (cap_arg == NULL)
+       call = Runtime::make_call(Runtime::MAKESLICE1, loc, 2, type_arg,
+                                 len_arg);
+      else
+       call = Runtime::make_call(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);
+  else if (is_chan)
+    call = Runtime::make_call(Runtime::MAKECHAN, loc, 2, type_arg, len_arg);
+  else
+    go_unreachable();
+
+  return Expression::make_unsafe_cast(type, call, loc);
+}
+
+// Return whether an expression has an integer value.  Report an error
+// if not.  This is used when handling calls to the predeclared make
+// function.
+
+bool
+Builtin_call_expression::check_int_value(Expression* e)
+{
+  if (e->type()->integer_type() != NULL)
+    return true;
+
+  // Check for a floating point constant with integer value.
+  mpfr_t fval;
+  mpfr_init(fval);
+
+  Type* dummy;
+  if (e->float_constant_value(fval, &dummy) && mpfr_integer_p(fval))
+    {
+      mpz_t ival;
+      mpz_init(ival);
+
+      bool ok = false;
+
+      mpfr_clear_overflow();
+      mpfr_clear_erangeflag();
+      mpfr_get_z(ival, fval, GMP_RNDN);
+      if (!mpfr_overflow_p()
+         && !mpfr_erangeflag_p()
+         && mpz_sgn(ival) >= 0)
+       {
+         Named_type* ntype = Type::lookup_integer_type("int");
+         Integer_type* inttype = ntype->integer_type();
+         mpz_t max;
+         mpz_init_set_ui(max, 1);
+         mpz_mul_2exp(max, max, inttype->bits() - 1);
+         ok = mpz_cmp(ival, max) < 0;
+         mpz_clear(max);
+       }
+      mpz_clear(ival);
+
+      if (ok)
+       {
+         mpfr_clear(fval);
+         return true;
+       }
+    }
+
+  mpfr_clear(fval);
+
+  return false;
+}
+
 // Return the type of the real or imag functions, given the type of
 // the argument.  We need to map complex to float, complex64 to
 // float32, and complex128 to float64, so it has to be done by name.
@@ -10684,107 +10829,6 @@ Expression::make_allocation(Type* type, source_location location)
   return new Allocation_expression(type, location);
 }
 
-// Implement the builtin function make.
-
-class Make_expression : public Expression
-{
- public:
-  Make_expression(Type* type, Expression_list* args, source_location location)
-    : Expression(EXPRESSION_MAKE, location),
-      type_(type), args_(args)
-  { }
-
- protected:
-  int
-  do_traverse(Traverse* traverse);
-
-  Type*
-  do_type()
-  { return this->type_; }
-
-  void
-  do_determine_type(const Type_context*);
-
-  void
-  do_check_types(Gogo*);
-
-  Expression*
-  do_copy()
-  {
-    return new Make_expression(this->type_, this->args_->copy(),
-                              this->location());
-  }
-
-  tree
-  do_get_tree(Translate_context*);
-
- private:
-  // The type we are making.
-  Type* type_;
-  // The arguments to pass to the make routine.
-  Expression_list* args_;
-};
-
-// Traversal.
-
-int
-Make_expression::do_traverse(Traverse* traverse)
-{
-  if (this->args_ != NULL
-      && this->args_->traverse(traverse) == TRAVERSE_EXIT)
-    return TRAVERSE_EXIT;
-  if (Type::traverse(this->type_, traverse) == TRAVERSE_EXIT)
-    return TRAVERSE_EXIT;
-  return TRAVERSE_CONTINUE;
-}
-
-// Set types of arguments.
-
-void
-Make_expression::do_determine_type(const Type_context*)
-{
-  if (this->args_ != NULL)
-    {
-      Type_context context(Type::lookup_integer_type("int"), false);
-      for (Expression_list::const_iterator pe = this->args_->begin();
-          pe != this->args_->end();
-          ++pe)
-       (*pe)->determine_type(&context);
-    }
-}
-
-// Check types for a make expression.
-
-void
-Make_expression::do_check_types(Gogo*)
-{
-  if (this->type_->channel_type() == NULL
-      && this->type_->map_type() == NULL
-      && (this->type_->array_type() == NULL
-         || this->type_->array_type()->length() != NULL))
-    this->report_error(_("invalid type for make function"));
-  else if (!this->type_->check_make_expression(this->args_, this->location()))
-    this->set_is_error();
-}
-
-// Return a tree for a make expression.
-
-tree
-Make_expression::do_get_tree(Translate_context* context)
-{
-  return this->type_->make_expression_tree(context, this->args_,
-                                          this->location());
-}
-
-// Make a make expression.
-
-Expression*
-Expression::make_make(Type* type, Expression_list* args,
-                     source_location location)
-{
-  return new Make_expression(type, args, location);
-}
-
 // Construct a struct.
 
 class Struct_construction_expression : public Expression
@@ -12771,6 +12815,50 @@ Expression::make_struct_field_offset(Struct_type* type,
   return new Struct_field_offset_expression(type, field);
 }
 
+// An expression which evaluates to a pointer to the map descriptor of
+// a map type.
+
+class Map_descriptor_expression : public Expression
+{
+ public:
+  Map_descriptor_expression(Map_type* type, source_location location)
+    : Expression(EXPRESSION_MAP_DESCRIPTOR, location),
+      type_(type)
+  { }
+
+ protected:
+  Type*
+  do_type()
+  { return Type::make_pointer_type(Map_type::make_map_descriptor_type()); }
+
+  void
+  do_determine_type(const Type_context*)
+  { }
+
+  Expression*
+  do_copy()
+  { return this; }
+
+  tree
+  do_get_tree(Translate_context* context)
+  {
+    return this->type_->map_descriptor_pointer(context->gogo(),
+                                              this->location());
+  }
+
+ private:
+  // The type for which this is the descriptor.
+  Map_type* type_;
+};
+
+// Make a map descriptor expression.
+
+Expression*
+Expression::make_map_descriptor(Map_type* type, source_location location)
+{
+  return new Map_descriptor_expression(type, location);
+}
+
 // An expression which evaluates to the address of an unnamed label.
 
 class Label_addr_expression : public Expression
index 13f4fb419f8684980036f63aa7668594b07dc281..271b1bbbe36e0a41679b5863eb62a807737580dd 100644 (file)
@@ -78,7 +78,6 @@ class Expression
     EXPRESSION_FIELD_REFERENCE,
     EXPRESSION_INTERFACE_FIELD_REFERENCE,
     EXPRESSION_ALLOCATION,
-    EXPRESSION_MAKE,
     EXPRESSION_TYPE_GUARD,
     EXPRESSION_CONVERSION,
     EXPRESSION_UNSAFE_CONVERSION,
@@ -92,6 +91,7 @@ class Expression
     EXPRESSION_TYPE_DESCRIPTOR,
     EXPRESSION_TYPE_INFO,
     EXPRESSION_STRUCT_FIELD_OFFSET,
+    EXPRESSION_MAP_DESCRIPTOR,
     EXPRESSION_LABEL_ADDR
   };
 
@@ -236,10 +236,6 @@ class Expression
   static Expression*
   make_allocation(Type*, source_location);
 
-  // Make a call to the builtin function make.
-  static Expression*
-  make_make(Type*, Expression_list*, source_location);
-
   // Make a type guard expression.
   static Expression*
   make_type_guard(Expression*, Type*, source_location);
@@ -276,8 +272,8 @@ class Expression
   static Receive_expression*
   make_receive(Expression* channel, source_location);
 
-  // Make an expression which evaluates to the type descriptor of a
-  // type.
+  // Make an expression which evaluates to the address of the type
+  // descriptor for TYPE.
   static Expression*
   make_type_descriptor(Type* type, source_location);
 
@@ -304,6 +300,11 @@ class Expression
   static Expression*
   make_struct_field_offset(Struct_type*, const Struct_field*);
 
+  // Make an expression which evaluates to the address of the map
+  // descriptor for TYPE.
+  static Expression*
+  make_map_descriptor(Map_type* type, source_location);
+
   // Make an expression which evaluates to the address of an unnamed
   // label.
   static Expression*
index 204f14751b509e88c1e8afd43db9e1af5bb87dd3..2ecfbf5b15508e07f79a57b45b8be2b7dc9261fa 100644 (file)
@@ -64,6 +64,8 @@ enum Runtime_function_type
   RFT_FUNC_PTR,
   // Pointer to Go type descriptor.
   RFT_TYPE,
+  // Pointer to map descriptor.
+  RFT_MAPDESCRIPTOR,
 
   NUMBER_OF_RUNTIME_FUNCTION_TYPES
 };
@@ -175,6 +177,10 @@ runtime_function_type(Runtime_function_type bft)
        case RFT_TYPE:
          t = Type::make_type_descriptor_ptr_type();
          break;
+
+       case RFT_MAPDESCRIPTOR:
+         t = Type::make_pointer_type(Map_type::make_map_descriptor_type());
+         break;
        }
 
       runtime_function_types[bft] = t;
@@ -225,6 +231,11 @@ convert_to_runtime_function_type(Runtime_function_type bft, Expression* e,
     case RFT_TYPE:
       go_assert(e->type() == Type::make_type_descriptor_ptr_type());
       return e;
+
+    case RFT_MAPDESCRIPTOR:
+      go_assert(e->type()->points_to()
+               == Map_type::make_map_descriptor_type());
+      return e;
     }
 }
 
index 6e7a807a88e3efe6fa7b948664334758cd724fc8..219ccb8bd9021c734bb0e9f30f14727323e48386 100644 (file)
@@ -65,8 +65,14 @@ DEF_GO_RUNTIME(STRING_TO_INT_ARRAY, "__go_string_to_int_array",
               P1(STRING), R1(SLICE))
 
 
+// Make a slice.
+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))
+
+
 // Make a map.
-DEF_GO_RUNTIME(NEW_MAP, "__go_new_map", P2(TYPE, UINTPTR), R1(MAP))
+DEF_GO_RUNTIME(MAKEMAP, "__go_new_map", P2(MAPDESCRIPTOR, UINTPTR), R1(MAP))
 
 // Build a map from a composite literal.
 DEF_GO_RUNTIME(CONSTRUCT_MAP, "__go_construct_map",
@@ -103,7 +109,7 @@ DEF_GO_RUNTIME(MAPITERNEXT, "runtime.mapiternext", P1(MAPITER), R0())
 
 
 // Make a channel.
-DEF_GO_RUNTIME(NEW_CHANNEL, "__go_new_channel", P2(UINTPTR, UINTPTR), R1(CHAN))
+DEF_GO_RUNTIME(MAKECHAN, "__go_new_channel", P2(TYPE, UINTPTR), 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 e19d4f2e7441bf96f8f2035b069a3499e5edd2ef..4b2ceeb4560aedd5b2398f2b63d51b9e919538d0 100644 (file)
@@ -768,68 +768,6 @@ Type::hash_string(const std::string& s, unsigned int h)
   return h;
 }
 
-// Default check for the expression passed to make.  Any type which
-// may be used with make implements its own version of this.
-
-bool
-Type::do_check_make_expression(Expression_list*, source_location)
-{
-  go_unreachable();
-}
-
-// Return whether an expression has an integer value.  Report an error
-// if not.  This is used when handling calls to the predeclared make
-// function.
-
-bool
-Type::check_int_value(Expression* e, const char* errmsg,
-                     source_location location)
-{
-  if (e->type()->integer_type() != NULL)
-    return true;
-
-  // Check for a floating point constant with integer value.
-  mpfr_t fval;
-  mpfr_init(fval);
-
-  Type* dummy;
-  if (e->float_constant_value(fval, &dummy) && mpfr_integer_p(fval))
-    {
-      mpz_t ival;
-      mpz_init(ival);
-
-      bool ok = false;
-
-      mpfr_clear_overflow();
-      mpfr_clear_erangeflag();
-      mpfr_get_z(ival, fval, GMP_RNDN);
-      if (!mpfr_overflow_p()
-         && !mpfr_erangeflag_p()
-         && mpz_sgn(ival) >= 0)
-       {
-         Named_type* ntype = Type::lookup_integer_type("int");
-         Integer_type* inttype = ntype->integer_type();
-         mpz_t max;
-         mpz_init_set_ui(max, 1);
-         mpz_mul_2exp(max, max, inttype->bits() - 1);
-         ok = mpz_cmp(ival, max) < 0;
-         mpz_clear(max);
-       }
-      mpz_clear(ival);
-
-      if (ok)
-       {
-         mpfr_clear(fval);
-         return true;
-       }
-    }
-
-  mpfr_clear(fval);
-
-  error_at(location, "%s", errmsg);
-  return false;
-}
-
 // A hash table mapping unnamed types to the backend representation of
 // those types.
 
@@ -912,16 +850,6 @@ Type::get_btype_without_hash(Gogo* gogo)
   return this->btype_;
 }
 
-// Any type which supports the builtin make function must implement
-// this.
-
-tree
-Type::do_make_expression_tree(Translate_context*, Expression_list*,
-                             source_location)
-{
-  go_unreachable();
-}
-
 // Return a pointer to the type descriptor for this type.
 
 tree
@@ -1366,6 +1294,8 @@ Type::type_descriptor_constructor(Gogo* gogo, int runtime_type_kind,
   Expression_list* vals = new Expression_list();
   vals->reserve(9);
 
+  if (!this->has_pointer())
+    runtime_type_kind |= RUNTIME_TYPE_KIND_NO_POINTERS;
   Struct_field_list::const_iterator p = fields->begin();
   go_assert(p->field_name() == "Kind");
   mpz_t iv;
@@ -4341,43 +4271,6 @@ Array_type::do_hash_for_method(Gogo* gogo) const
   return this->element_type_->hash_for_method(gogo) + 1;
 }
 
-// See if the expression passed to make is suitable.  The first
-// argument is required, and gives the length.  An optional second
-// argument is permitted for the capacity.
-
-bool
-Array_type::do_check_make_expression(Expression_list* args,
-                                    source_location location)
-{
-  go_assert(this->length_ == NULL);
-  if (args == NULL || args->empty())
-    {
-      error_at(location, "length required when allocating a slice");
-      return false;
-    }
-  else if (args->size() > 2)
-    {
-      error_at(location, "too many expressions passed to make");
-      return false;
-    }
-  else
-    {
-      if (!Type::check_int_value(args->front(),
-                                _("bad length when making slice"), location))
-       return false;
-
-      if (args->size() > 1)
-       {
-         if (!Type::check_int_value(args->back(),
-                                    _("bad capacity when making slice"),
-                                    location))
-           return false;
-       }
-
-      return true;
-    }
-}
-
 // Get a tree for the length of a fixed array.  The length may be
 // computed using a function call, so we must only evaluate it once.
 
@@ -4491,129 +4384,6 @@ Array_type::get_backend_length(Gogo* gogo)
   return tree_to_expr(this->get_length_tree(gogo));
 }
 
-// Handle the builtin make function for a slice.
-
-tree
-Array_type::do_make_expression_tree(Translate_context* context,
-                                   Expression_list* args,
-                                   source_location location)
-{
-  go_assert(this->length_ == NULL);
-
-  Gogo* gogo = context->gogo();
-  tree type_tree = type_to_tree(this->get_backend(gogo));
-  if (type_tree == error_mark_node)
-    return error_mark_node;
-
-  tree values_field = TYPE_FIELDS(type_tree);
-  go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(values_field)),
-                   "__values") == 0);
-
-  tree count_field = DECL_CHAIN(values_field);
-  go_assert(strcmp(IDENTIFIER_POINTER(DECL_NAME(count_field)),
-                   "__count") == 0);
-
-  tree element_type_tree = type_to_tree(this->element_type_->get_backend(gogo));
-  if (element_type_tree == error_mark_node)
-    return error_mark_node;
-  tree element_size_tree = TYPE_SIZE_UNIT(element_type_tree);
-
-  // The first argument is the number of elements, the optional second
-  // argument is the capacity.
-  go_assert(args != NULL && args->size() >= 1 && args->size() <= 2);
-
-  tree length_tree = args->front()->get_tree(context);
-  if (length_tree == error_mark_node)
-    return error_mark_node;
-  if (!DECL_P(length_tree))
-    length_tree = save_expr(length_tree);
-  if (!INTEGRAL_TYPE_P(TREE_TYPE(length_tree)))
-    length_tree = convert_to_integer(TREE_TYPE(count_field), length_tree);
-
-  tree bad_index = Expression::check_bounds(length_tree,
-                                           TREE_TYPE(count_field),
-                                           NULL_TREE, location);
-
-  length_tree = fold_convert_loc(location, TREE_TYPE(count_field), length_tree);
-  tree capacity_tree;
-  if (args->size() == 1)
-    capacity_tree = length_tree;
-  else
-    {
-      capacity_tree = args->back()->get_tree(context);
-      if (capacity_tree == error_mark_node)
-       return error_mark_node;
-      if (!DECL_P(capacity_tree))
-       capacity_tree = save_expr(capacity_tree);
-      if (!INTEGRAL_TYPE_P(TREE_TYPE(capacity_tree)))
-       capacity_tree = convert_to_integer(TREE_TYPE(count_field),
-                                          capacity_tree);
-
-      bad_index = Expression::check_bounds(capacity_tree,
-                                          TREE_TYPE(count_field),
-                                          bad_index, location);
-
-      tree chktype = (((TYPE_SIZE(TREE_TYPE(capacity_tree))
-                       > TYPE_SIZE(TREE_TYPE(length_tree)))
-                      || ((TYPE_SIZE(TREE_TYPE(capacity_tree))
-                           == TYPE_SIZE(TREE_TYPE(length_tree)))
-                          && TYPE_UNSIGNED(TREE_TYPE(capacity_tree))))
-                     ? TREE_TYPE(capacity_tree)
-                     : TREE_TYPE(length_tree));
-      tree chk = fold_build2_loc(location, LT_EXPR, boolean_type_node,
-                                fold_convert_loc(location, chktype,
-                                                 capacity_tree),
-                                fold_convert_loc(location, chktype,
-                                                 length_tree));
-      if (bad_index == NULL_TREE)
-       bad_index = chk;
-      else
-       bad_index = fold_build2_loc(location, TRUTH_OR_EXPR, boolean_type_node,
-                                   bad_index, chk);
-
-      capacity_tree = fold_convert_loc(location, TREE_TYPE(count_field),
-                                      capacity_tree);
-    }
-
-  tree size_tree = fold_build2_loc(location, MULT_EXPR, sizetype,
-                                  element_size_tree,
-                                  fold_convert_loc(location, sizetype,
-                                                   capacity_tree));
-
-  tree chk = fold_build2_loc(location, TRUTH_AND_EXPR, boolean_type_node,
-                            fold_build2_loc(location, GT_EXPR,
-                                            boolean_type_node,
-                                            fold_convert_loc(location,
-                                                             sizetype,
-                                                             capacity_tree),
-                                            size_zero_node),
-                            fold_build2_loc(location, LT_EXPR,
-                                            boolean_type_node,
-                                            size_tree, element_size_tree));
-  if (bad_index == NULL_TREE)
-    bad_index = chk;
-  else
-    bad_index = fold_build2_loc(location, TRUTH_OR_EXPR, boolean_type_node,
-                               bad_index, chk);
-
-  tree space = context->gogo()->allocate_memory(this->element_type_,
-                                               size_tree, location);
-
-  space = fold_convert(TREE_TYPE(values_field), space);
-
-  if (bad_index != NULL_TREE && bad_index != boolean_false_node)
-    {
-      tree crash = Gogo::runtime_error(RUNTIME_ERROR_MAKE_SLICE_OUT_OF_BOUNDS,
-                                      location);
-      space = build2(COMPOUND_EXPR, TREE_TYPE(space),
-                    build3(COND_EXPR, void_type_node,
-                           bad_index, crash, NULL_TREE),
-                    space);
-    }
-
-  return gogo->slice_constructor(type_tree, space, length_tree, capacity_tree);
-}
-
 // Return a tree for a pointer to the values in ARRAY.
 
 tree
@@ -4962,28 +4732,6 @@ Map_type::do_hash_for_method(Gogo* gogo) const
          + 2);
 }
 
-// Check that a call to the builtin make function is valid.  For a map
-// the optional argument is the number of spaces to preallocate for
-// values.
-
-bool
-Map_type::do_check_make_expression(Expression_list* args,
-                                  source_location location)
-{
-  if (args != NULL && !args->empty())
-    {
-      if (!Type::check_int_value(args->front(), _("bad size when making map"),
-                                location))
-       return false;
-      else if (args->size() > 1)
-       {
-         error_at(location, "too many arguments when making map");
-         return false;
-       }
-    }
-  return true;
-}
-
 // Get the backend representation for a map type.  A map type is
 // represented as a pointer to a struct.  The struct is __go_map in
 // libgo/map.h.
@@ -5024,62 +4772,6 @@ Map_type::do_get_backend(Gogo* gogo)
   return backend_map_type;
 }
 
-// Return an expression for a newly allocated map.
-
-tree
-Map_type::do_make_expression_tree(Translate_context* context,
-                                 Expression_list* args,
-                                 source_location location)
-{
-  tree bad_index = NULL_TREE;
-
-  tree expr_tree;
-  if (args == NULL || args->empty())
-    expr_tree = size_zero_node;
-  else
-    {
-      expr_tree = args->front()->get_tree(context);
-      if (expr_tree == error_mark_node)
-       return error_mark_node;
-      if (!DECL_P(expr_tree))
-       expr_tree = save_expr(expr_tree);
-      if (!INTEGRAL_TYPE_P(TREE_TYPE(expr_tree)))
-       expr_tree = convert_to_integer(sizetype, expr_tree);
-      bad_index = Expression::check_bounds(expr_tree, sizetype, bad_index,
-                                          location);
-    }
-
-  Gogo* gogo = context->gogo();
-  tree map_type = type_to_tree(this->get_backend(gogo));
-
-  static tree new_map_fndecl;
-  tree ret = Gogo::call_builtin(&new_map_fndecl,
-                               location,
-                               "__go_new_map",
-                               2,
-                               map_type,
-                               TREE_TYPE(TYPE_FIELDS(TREE_TYPE(map_type))),
-                               this->map_descriptor_pointer(gogo, location),
-                               sizetype,
-                               expr_tree);
-  if (ret == error_mark_node)
-    return error_mark_node;
-  // This can panic if the capacity is out of range.
-  TREE_NOTHROW(new_map_fndecl) = 0;
-
-  if (bad_index == NULL_TREE)
-    return ret;
-  else
-    {
-      tree crash = Gogo::runtime_error(RUNTIME_ERROR_MAKE_MAP_OUT_OF_BOUNDS,
-                                      location);
-      return build2(COMPOUND_EXPR, TREE_TYPE(ret),
-                   build3(COND_EXPR, void_type_node,
-                          bad_index, crash, NULL_TREE),
-                   ret);
-    }
-}
-
 // The type of a map type descriptor.
 
 Type*
@@ -5343,29 +5035,6 @@ Channel_type::is_identical(const Channel_type* t,
          && this->may_receive_ == t->may_receive_);
 }
 
-// Check whether the parameters for a call to the builtin function
-// make are OK for a channel.  A channel can take an optional single
-// parameter which is the buffer size.
-
-bool
-Channel_type::do_check_make_expression(Expression_list* args,
-                                     source_location location)
-{
-  if (args != NULL && !args->empty())
-    {
-      if (!Type::check_int_value(args->front(),
-                                _("bad buffer size when making channel"),
-                                location))
-       return false;
-      else if (args->size() > 1)
-       {
-         error_at(location, "too many arguments when making channel");
-         return false;
-       }
-    }
-  return true;
-}
-
 // Return the tree for a channel type.  A channel is a pointer to a
 // __go_channel struct.  The __go_channel struct is defined in
 // libgo/runtime/channel.h.
@@ -5384,66 +5053,6 @@ Channel_type::do_get_backend(Gogo* gogo)
   return backend_channel_type;
 }
 
-// Handle the builtin function make for a channel.
-
-tree
-Channel_type::do_make_expression_tree(Translate_context* context,
-                                     Expression_list* args,
-                                     source_location location)
-{
-  Gogo* gogo = context->gogo();
-  tree channel_type = type_to_tree(this->get_backend(gogo));
-
-  Type* ptdt = Type::make_type_descriptor_ptr_type();
-  tree element_type_descriptor =
-    this->element_type_->type_descriptor_pointer(gogo, location);
-
-  tree bad_index = NULL_TREE;
-
-  tree expr_tree;
-  if (args == NULL || args->empty())
-    expr_tree = size_zero_node;
-  else
-    {
-      expr_tree = args->front()->get_tree(context);
-      if (expr_tree == error_mark_node)
-       return error_mark_node;
-      if (!DECL_P(expr_tree))
-       expr_tree = save_expr(expr_tree);
-      if (!INTEGRAL_TYPE_P(TREE_TYPE(expr_tree)))
-       expr_tree = convert_to_integer(sizetype, expr_tree);
-      bad_index = Expression::check_bounds(expr_tree, sizetype, bad_index,
-                                          location);
-    }
-
-  static tree new_channel_fndecl;
-  tree ret = Gogo::call_builtin(&new_channel_fndecl,
-                               location,
-                               "__go_new_channel",
-                               2,
-                               channel_type,
-                               type_to_tree(ptdt->get_backend(gogo)),
-                               element_type_descriptor,
-                               sizetype,
-                               expr_tree);
-  if (ret == error_mark_node)
-    return error_mark_node;
-  // This can panic if the capacity is out of range.
-  TREE_NOTHROW(new_channel_fndecl) = 0;
-
-  if (bad_index == NULL_TREE)
-    return ret;
-  else
-    {
-      tree crash = Gogo::runtime_error(RUNTIME_ERROR_MAKE_CHAN_OUT_OF_BOUNDS,
-                                      location);
-      return build2(COMPOUND_EXPR, TREE_TYPE(ret),
-                   build3(COND_EXPR, void_type_node,
-                          bad_index, crash, NULL_TREE),
-                   ret);
-    }
-}
-
 // Build a type descriptor for a channel type.
 
 Type*
index 2ee80a4868b24d937f196bb10e2e0bce8f23fad2..9947a2ca749f4d98bc8ffac26881ce8bfc91de34 100644 (file)
@@ -78,6 +78,8 @@ static const int RUNTIME_TYPE_KIND_STRING = 24;
 static const int RUNTIME_TYPE_KIND_STRUCT = 25;
 static const int RUNTIME_TYPE_KIND_UNSAFE_POINTER = 26;
 
+static const int RUNTIME_TYPE_KIND_NO_POINTERS = (1 << 7);
+
 // To build the complete list of methods for a named type we need to
 // gather all methods from anonymous fields.  Those methods may
 // require an arbitrary set of indirections and field offsets.  There
@@ -811,13 +813,6 @@ class Type
   is_unexported_field_or_method(Gogo*, const Type*, const std::string&,
                                std::vector<const Named_type*>*);
 
-  // This type was passed to the builtin function make.  ARGS are the
-  // arguments passed to make after the type; this may be NULL if
-  // there were none.  Issue any required errors.
-  bool
-  check_make_expression(Expression_list* args, source_location location)
-  { return this->do_check_make_expression(args, location); }
-
   // Convert the builtin named types.
   static void
   convert_builtin_named_types(Gogo*);
@@ -826,12 +821,6 @@ class Type
   Btype*
   get_backend(Gogo*);
 
-  // Return a tree for a make expression applied to this type.
-  tree
-  make_expression_tree(Translate_context* context, Expression_list* args,
-                      source_location location)
-  { return this->do_make_expression_tree(context, args, location); }
-
   // Build a type descriptor entry for this type.  Return a pointer to
   // it.  The location is the location which causes us to need the
   // entry.
@@ -878,16 +867,9 @@ class Type
   virtual unsigned int
   do_hash_for_method(Gogo*) const;
 
-  virtual bool
-  do_check_make_expression(Expression_list* args, source_location);
-
   virtual Btype*
   do_get_backend(Gogo*) = 0;
 
-  virtual tree
-  do_make_expression_tree(Translate_context*, Expression_list*,
-                         source_location);
-
   virtual Expression*
   do_type_descriptor(Gogo*, Named_type* name) = 0;
 
@@ -901,10 +883,6 @@ class Type
   virtual void
   do_export(Export*) const;
 
-  // Return whether an expression is an integer.
-  static bool
-  check_int_value(Expression*, const char*, source_location);
-
   // Return whether a method expects a pointer as the receiver.
   static bool
   method_expects_pointer(const Named_object*);
@@ -2083,16 +2061,9 @@ class Array_type : public Type
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  bool
-  do_check_make_expression(Expression_list*, source_location);
-
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_make_expression_tree(Translate_context*, Expression_list*,
-                         source_location);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -2180,16 +2151,9 @@ class Map_type : public Type
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  bool
-  do_check_make_expression(Expression_list*, source_location);
-
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_make_expression_tree(Translate_context*, Expression_list*,
-                         source_location);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -2269,16 +2233,9 @@ class Channel_type : public Type
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  bool
-  do_check_make_expression(Expression_list*, source_location);
-
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_make_expression_tree(Translate_context*, Expression_list*,
-                         source_location);
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -2611,18 +2568,9 @@ class Named_type : public Type
   unsigned int
   do_hash_for_method(Gogo*) const;
 
-  bool
-  do_check_make_expression(Expression_list* args, source_location location)
-  { return this->type_->check_make_expression(args, location); }
-
   Btype*
   do_get_backend(Gogo*);
 
-  tree
-  do_make_expression_tree(Translate_context* context, Expression_list* args,
-                         source_location location)
-  { return this->type_->make_expression_tree(context, args, location); }
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
@@ -2751,18 +2699,9 @@ class Forward_declaration_type : public Type
   do_hash_for_method(Gogo* gogo) const
   { return this->real_type()->hash_for_method(gogo); }
 
-  bool
-  do_check_make_expression(Expression_list* args, source_location location)
-  { return this->base()->check_make_expression(args, location); }
-
   Btype*
   do_get_backend(Gogo* gogo);
 
-  tree
-  do_make_expression_tree(Translate_context* context, Expression_list* args,
-                         source_location location)
-  { return this->base()->make_expression_tree(context, args, location); }
-
   Expression*
   do_type_descriptor(Gogo*, Named_type*);
 
index c98a17637d30abd2b75c414524016d02f42dd9e3..761a11ad265f5d4c370d9544d962901a3c81c743 100644 (file)
@@ -381,6 +381,7 @@ runtime_files = \
        runtime/go-interface-eface-compare.c \
        runtime/go-interface-val-compare.c \
        runtime/go-lock-os-thread.c \
+       runtime/go-make-slice.c \
        runtime/go-map-delete.c \
        runtime/go-map-index.c \
        runtime/go-map-len.c \
index ac5de78dca426af82f48ad824a29a845ccb9108a..8637ec41b7d72cc8240e380fa393178ac6c399c7 100644 (file)
@@ -184,18 +184,18 @@ am__libgo_la_SOURCES_DIST = runtime/go-append.c runtime/go-assert.c \
        runtime/go-interface-compare.c \
        runtime/go-interface-eface-compare.c \
        runtime/go-interface-val-compare.c runtime/go-lock-os-thread.c \
-       runtime/go-map-delete.c runtime/go-map-index.c \
-       runtime/go-map-len.c runtime/go-map-range.c \
-       runtime/go-nanotime.c runtime/go-new-channel.c \
-       runtime/go-new-map.c runtime/go-new.c runtime/go-note.c \
-       runtime/go-panic.c runtime/go-panic-defer.c runtime/go-print.c \
-       runtime/go-rec-big.c runtime/go-rec-nb-big.c \
-       runtime/go-rec-nb-small.c runtime/go-rec-small.c \
-       runtime/go-recover.c runtime/go-reflect.c \
-       runtime/go-reflect-call.c runtime/go-reflect-chan.c \
-       runtime/go-reflect-map.c runtime/go-rune.c \
-       runtime/go-runtime-error.c runtime/go-sched.c \
-       runtime/go-select.c runtime/go-semacquire.c \
+       runtime/go-make-slice.c runtime/go-map-delete.c \
+       runtime/go-map-index.c runtime/go-map-len.c \
+       runtime/go-map-range.c runtime/go-nanotime.c \
+       runtime/go-new-channel.c runtime/go-new-map.c runtime/go-new.c \
+       runtime/go-note.c runtime/go-panic.c runtime/go-panic-defer.c \
+       runtime/go-print.c runtime/go-rec-big.c \
+       runtime/go-rec-nb-big.c runtime/go-rec-nb-small.c \
+       runtime/go-rec-small.c runtime/go-recover.c \
+       runtime/go-reflect.c runtime/go-reflect-call.c \
+       runtime/go-reflect-chan.c runtime/go-reflect-map.c \
+       runtime/go-rune.c runtime/go-runtime-error.c \
+       runtime/go-sched.c runtime/go-select.c runtime/go-semacquire.c \
        runtime/go-send-big.c runtime/go-send-nb-big.c \
        runtime/go-send-nb-small.c runtime/go-send-small.c \
        runtime/go-setenv.c runtime/go-signal.c runtime/go-strcmp.c \
@@ -227,25 +227,25 @@ am__objects_3 = go-append.lo go-assert.lo go-assert-interface.lo \
        go-gomaxprocs.lo go-int-array-to-string.lo go-int-to-string.lo \
        go-interface-compare.lo go-interface-eface-compare.lo \
        go-interface-val-compare.lo go-lock-os-thread.lo \
-       go-map-delete.lo go-map-index.lo go-map-len.lo go-map-range.lo \
-       go-nanotime.lo go-new-channel.lo go-new-map.lo go-new.lo \
-       go-note.lo go-panic.lo go-panic-defer.lo go-print.lo \
-       go-rec-big.lo go-rec-nb-big.lo go-rec-nb-small.lo \
-       go-rec-small.lo go-recover.lo go-reflect.lo go-reflect-call.lo \
-       go-reflect-chan.lo go-reflect-map.lo go-rune.lo \
-       go-runtime-error.lo go-sched.lo go-select.lo go-semacquire.lo \
-       go-send-big.lo go-send-nb-big.lo go-send-nb-small.lo \
-       go-send-small.lo go-setenv.lo go-signal.lo go-strcmp.lo \
-       go-string-to-byte-array.lo go-string-to-int-array.lo \
-       go-strplus.lo go-strslice.lo go-trampoline.lo go-type-eface.lo \
-       go-type-error.lo go-type-identity.lo go-type-interface.lo \
-       go-type-string.lo go-typedesc-equal.lo go-typestring.lo \
-       go-unreflect.lo go-unsafe-new.lo go-unsafe-newarray.lo \
-       go-unsafe-pointer.lo go-unwind.lo cpuprof.lo mcache.lo \
-       mcentral.lo $(am__objects_1) mfinal.lo mfixalloc.lo mgc0.lo \
-       mheap.lo msize.lo proc.lo thread.lo $(am__objects_2) chan.lo \
-       iface.lo malloc.lo map.lo mprof.lo reflect.lo sigqueue.lo \
-       string.lo
+       go-make-slice.lo go-map-delete.lo go-map-index.lo \
+       go-map-len.lo go-map-range.lo go-nanotime.lo go-new-channel.lo \
+       go-new-map.lo go-new.lo go-note.lo go-panic.lo \
+       go-panic-defer.lo go-print.lo go-rec-big.lo go-rec-nb-big.lo \
+       go-rec-nb-small.lo go-rec-small.lo go-recover.lo go-reflect.lo \
+       go-reflect-call.lo go-reflect-chan.lo go-reflect-map.lo \
+       go-rune.lo go-runtime-error.lo go-sched.lo go-select.lo \
+       go-semacquire.lo go-send-big.lo go-send-nb-big.lo \
+       go-send-nb-small.lo go-send-small.lo go-setenv.lo go-signal.lo \
+       go-strcmp.lo go-string-to-byte-array.lo \
+       go-string-to-int-array.lo go-strplus.lo go-strslice.lo \
+       go-trampoline.lo go-type-eface.lo go-type-error.lo \
+       go-type-identity.lo go-type-interface.lo go-type-string.lo \
+       go-typedesc-equal.lo go-typestring.lo go-unreflect.lo \
+       go-unsafe-new.lo go-unsafe-newarray.lo go-unsafe-pointer.lo \
+       go-unwind.lo cpuprof.lo mcache.lo mcentral.lo $(am__objects_1) \
+       mfinal.lo mfixalloc.lo mgc0.lo mheap.lo msize.lo proc.lo \
+       thread.lo $(am__objects_2) chan.lo iface.lo malloc.lo map.lo \
+       mprof.lo reflect.lo sigqueue.lo string.lo
 am_libgo_la_OBJECTS = $(am__objects_3)
 libgo_la_OBJECTS = $(am_libgo_la_OBJECTS)
 libgo_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
@@ -800,6 +800,7 @@ runtime_files = \
        runtime/go-interface-eface-compare.c \
        runtime/go-interface-val-compare.c \
        runtime/go-lock-os-thread.c \
+       runtime/go-make-slice.c \
        runtime/go-map-delete.c \
        runtime/go-map-index.c \
        runtime/go-map-len.c \
@@ -2309,6 +2310,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-interface-val-compare.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-lock-os-thread.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-make-slice.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-delete.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-index.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/go-map-len.Plo@am__quote@
@@ -2610,6 +2612,13 @@ go-lock-os-thread.lo: runtime/go-lock-os-thread.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-lock-os-thread.lo `test -f 'runtime/go-lock-os-thread.c' || echo '$(srcdir)/'`runtime/go-lock-os-thread.c
 
+go-make-slice.lo: runtime/go-make-slice.c
+@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-make-slice.lo -MD -MP -MF $(DEPDIR)/go-make-slice.Tpo -c -o go-make-slice.lo `test -f 'runtime/go-make-slice.c' || echo '$(srcdir)/'`runtime/go-make-slice.c
+@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-make-slice.Tpo $(DEPDIR)/go-make-slice.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='runtime/go-make-slice.c' object='go-make-slice.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o go-make-slice.lo `test -f 'runtime/go-make-slice.c' || echo '$(srcdir)/'`runtime/go-make-slice.c
+
 go-map-delete.lo: runtime/go-map-delete.c
 @am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT go-map-delete.lo -MD -MP -MF $(DEPDIR)/go-map-delete.Tpo -c -o go-map-delete.lo `test -f 'runtime/go-map-delete.c' || echo '$(srcdir)/'`runtime/go-map-delete.c
 @am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/go-map-delete.Tpo $(DEPDIR)/go-map-delete.Plo
index e440e87365267c960473370721538a6ba9408efa..0c6f39185de6a2a8edf1954e67170e415092b069 100644 (file)
 #include "channel.h"
 
 struct __go_channel*
-__go_new_channel (const struct __go_type_descriptor *element_type,
+__go_new_channel (const struct __go_type_descriptor *channel_type,
                  uintptr_t entries)
 {
+  const struct __go_channel_type *ctd;
+  const struct __go_type_descriptor *element_type;
   uintptr_t element_size;
+  int ientries;
   struct __go_channel* ret;
   size_t alloc_size;
   int i;
 
+  __go_assert (channel_type->__code == GO_CHAN);
+  ctd = (const struct __go_channel_type *) channel_type;
+  element_type = ctd->__element_type;
+
   element_size = element_type->__size;
 
-  if ((uintptr_t) (int) entries != entries
+  ientries = (int) entries;
+  if (ientries < 0
+      || (uintptr_t) ientries != entries
       || entries > (uintptr_t) -1 / element_size)
     __go_panic_msg ("chan size out of range");
 
index 3a471299b225ba36b93b93c9a372dcc3555640dd..05ac8a1a40c95517cfb515b686a4042fa6775671 100644 (file)
@@ -106,9 +106,11 @@ __go_map_next_prime (uintptr_t n)
 struct __go_map *
 __go_new_map (const struct __go_map_descriptor *descriptor, uintptr_t entries)
 {
+  int ientries;
   struct __go_map *ret;
 
-  if ((uintptr_t) (int) entries != entries)
+  ientries = (int) entries;
+  if (ientries < 0 || (uintptr_t) ientries != entries)
     __go_panic_msg ("map size out of range");
 
   if (entries == 0)
index a769142c3dfbd041719116ad6363596e807f71f8..27177e2fc7387ca312fe6a1517120ea8beafffb6 100644 (file)
@@ -161,7 +161,7 @@ go_complex_to_ffi (ffi_type *float_type)
 static ffi_type *
 go_type_to_ffi (const struct __go_type_descriptor *descriptor)
 {
-  switch (descriptor->__code)
+  switch (descriptor->__code & GO_CODE_MASK)
     {
     case GO_BOOL:
       if (sizeof (_Bool) == 1)
index d568024b3dfa826258c8b36fbc6c24fab18f646c..61e360212f0dfb216e2091846a62cdeeaa351676 100644 (file)
@@ -26,9 +26,6 @@ makechan (const struct __go_type_descriptor *typ, uint32_t size)
   struct __go_channel *channel;
   void *ret;
 
-  __go_assert (typ->__code == GO_CHAN);
-  typ = ((const struct __go_channel_type *) typ)->__element_type;
-
   channel = __go_new_channel (typ, size);
 
   ret = __go_alloc (sizeof (void *));
index bf13a11fae2cf3ef8cb1bbe815e99c0d48659764..af7d5e8968f01eaed5e9db8818c94a2a5bd57788 100644 (file)
@@ -57,7 +57,7 @@ extern const struct __go_type_descriptor ptr_struct_descriptor
 const struct __go_type_descriptor *
 get_descriptor (int code)
 {
-  switch (code)
+  switch (code & GO_CODE_MASK)
     {
     case GO_BOOL:
       return &ptr_bool_descriptor;
index e048141e93e7a9b45eec09369a00548eb106605c..6e2193982d65a90bb096a646f332b7349e2fc051 100644 (file)
 #define GO_STRUCT 25
 #define GO_UNSAFE_POINTER 26
 
+#define GO_NO_POINTERS (1 << 7)
+
+#define GO_CODE_MASK 0x7f
+
 /* For each Go type the compiler constructs one of these structures.
    This is used for type reflectin, interfaces, maps, and reference
    counting.  */
 
 struct __go_type_descriptor
 {
-  /* The type code for this type, a value in enum __go_type_codes.
+  /* The type code for this type, one of the type kind values above.
      This is used by unsafe.Reflect and unsafe.Typeof to determine the
      type descriptor to return for this type itself.  It is also used
      by reflect.toType when mapping to a reflect Type structure.  */