libgo patch committed: Allocate correct types in refect for interface conversions

2014-10-20 Thread Ian Taylor
This patch to libgo is a copy of a patch I recently made to the master
Go library.  This changes the reflect package to allocate memory using
the correct types for interface conversions.  The code was incorrectly
allocating an empty interface type to hold a non-empty interface
value.  This was working in the master library because it
coincidentally always handled the values correctly.  This was working
in gccgo because we almost never have the types anyhow, although we
plan to change that shortly.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r 87f8de53800a libgo/go/reflect/value.go
--- a/libgo/go/reflect/value.go Fri Oct 17 17:41:04 2014 -0700
+++ b/libgo/go/reflect/value.go Mon Oct 20 10:59:43 2014 -0700
@@ -1405,9 +1405,9 @@
 func (v Value) Set(x Value) {
v.mustBeAssignable()
x.mustBeExported() // do not let unexported x leak
-   var target *interface{}
+   var target unsafe.Pointer
if v.kind() == Interface {
-   target = (*interface{})(v.ptr)
+   target = v.ptr
}
x = x.assignTo("reflect.Set", v.typ, target)
if x.flag&flagIndir != 0 {
@@ -2230,7 +2230,7 @@
 // assignTo returns a value v that can be assigned directly to typ.
 // It panics if v is not assignable to typ.
 // For a conversion to an interface type, target is a suggested scratch space 
to use.
-func (v Value) assignTo(context string, dst *rtype, target *interface{}) Value 
{
+func (v Value) assignTo(context string, dst *rtype, target unsafe.Pointer) 
Value {
if v.flag&flagMethod != 0 {
v = makeMethodValue(context, v)
}
@@ -2246,15 +2246,15 @@
 
case implements(dst, v.typ):
if target == nil {
-   target = new(interface{})
+   target = unsafe_New(dst)
}
x := valueInterface(v, false)
if dst.NumMethod() == 0 {
-   *target = x
+   *(*interface{})(target) = x
} else {
-   ifaceE2I(dst, x, unsafe.Pointer(target))
+   ifaceE2I(dst, x, target)
}
-   return Value{dst, unsafe.Pointer(target) /* 0, */, flagIndir | 
flag(Interface)< interface
 func cvtT2I(v Value, typ Type) Value {
-   target := new(interface{})
+   target := unsafe_New(typ.common())
x := valueInterface(v, false)
if typ.NumMethod() == 0 {
-   *target = x
+   *(*interface{})(target) = x
} else {
-   ifaceE2I(typ.(*rtype), x, unsafe.Pointer(target))
+   ifaceE2I(typ.(*rtype), x, target)
}
-   return Value{typ.common(), unsafe.Pointer(target) /* 0, */, 
v.flag&flagRO | flagIndir | flag(Interface)< interface


Go patch committed: Pass type information to heap allocations

2014-10-20 Thread Ian Taylor
This patch by Chris Manghane passes type information to
compiler-generated heap allocations in gccgo.  This gives us precise
type information for much of the gccgo heap, and means that garbage
collection is much more precise and less prone to errors due to
mistaking integer or float values as pointers.  Bootstrapped and ran
Go testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r f6e937cbbe5a go/expressions.cc
--- a/go/expressions.cc Mon Oct 20 11:04:12 2014 -0700
+++ b/go/expressions.cc Mon Oct 20 12:04:16 2014 -0700
@@ -12170,7 +12170,7 @@
   { return this->vals_ == NULL ? 0 : this->vals_->size(); }
 
 protected:
-  int
+  virtual int
   do_traverse(Traverse* traverse);
 
   bool
@@ -12495,11 +12495,33 @@
 : Array_construction_expression(EXPRESSION_SLICE_CONSTRUCTION,
type, indexes, vals, location),
   valtype_(NULL)
-  { go_assert(type->is_slice_type()); }
+  {
+go_assert(type->is_slice_type());
+
+mpz_t lenval;
+Expression* length;
+if (vals == NULL || vals->empty())
+  mpz_init_set_ui(lenval, 0);
+else
+  {
+   if (this->indexes() == NULL)
+ mpz_init_set_ui(lenval, vals->size());
+   else
+ mpz_init_set_ui(lenval, indexes->back() + 1);
+  }
+Type* int_type = Type::lookup_integer_type("int");
+length = Expression::make_integer(&lenval, int_type, location);
+mpz_clear(lenval);
+Type* element_type = type->array_type()->element_type();
+this->valtype_ = Type::make_array_type(element_type, length);
+  }
 
  protected:
   // Note that taking the address of a slice literal is invalid.
 
+  int
+  do_traverse(Traverse* traverse);
+
   Expression*
   do_copy()
   {
@@ -12518,6 +12540,19 @@
   Type* valtype_;
 };
 
+// Traversal.
+
+int
+Slice_construction_expression::do_traverse(Traverse* traverse)
+{
+  if (this->Array_construction_expression::do_traverse(traverse)
+  == TRAVERSE_EXIT)
+return TRAVERSE_EXIT;
+  if (Type::traverse(this->valtype_, traverse) == TRAVERSE_EXIT)
+return TRAVERSE_EXIT;
+  return TRAVERSE_CONTINUE;
+}
+
 // Return the backend representation for constructing a slice.
 
 Bexpression*
@@ -12532,24 +12567,7 @@
 
   Location loc = this->location();
   Type* element_type = array_type->element_type();
-  if (this->valtype_ == NULL)
-{
-  mpz_t lenval;
-  Expression* length;
-  if (this->vals() == NULL || this->vals()->empty())
-mpz_init_set_ui(lenval, 0);
-  else
-{
-  if (this->indexes() == NULL)
-mpz_init_set_ui(lenval, this->vals()->size());
-  else
-mpz_init_set_ui(lenval, this->indexes()->back() + 1);
-}
-  Type* int_type = Type::lookup_integer_type("int");
-  length = Expression::make_integer(&lenval, int_type, loc);
-  mpz_clear(lenval);
-  this->valtype_ = Type::make_array_type(element_type, length);
-}
+  go_assert(this->valtype_ != NULL);
 
   Expression_list* vals = this->vals();
   if (this->vals() == NULL || this->vals()->empty())
@@ -14028,7 +14046,7 @@
  protected:
   Type*
   do_type()
-  { return Type::make_pointer_type(Type::make_void_type()); }
+  { return Type::lookup_integer_type("uintptr"); }
 
   bool
   do_is_immutable() const
diff -r f6e937cbbe5a go/go.cc
--- a/go/go.cc  Mon Oct 20 11:04:12 2014 -0700
+++ b/go/go.cc  Mon Oct 20 12:04:16 2014 -0700
@@ -96,9 +96,6 @@
   // Create function descriptors as needed.
   ::gogo->create_function_descriptors();
 
-  // Write out queued up functions for hash and comparison of types.
-  ::gogo->write_specific_type_functions();
-
   // Now that we have seen all the names, verify that types are
   // correct.
   ::gogo->verify_types();
@@ -130,6 +127,9 @@
   // Convert complicated go and defer statements into simpler ones.
   ::gogo->simplify_thunk_statements();
 
+  // Write out queued up functions for hash and comparison of types.
+  ::gogo->write_specific_type_functions();
+
   // Flatten the parse tree.
   ::gogo->flatten();
 
diff -r f6e937cbbe5a go/gogo.cc
--- a/go/gogo.ccMon Oct 20 11:04:12 2014 -0700
+++ b/go/gogo.ccMon Oct 20 12:04:16 2014 -0700
@@ -4196,21 +4196,18 @@
 Expression*
 Gogo::allocate_memory(Type* type, Location location)
 {
-  Btype* btype = type->get_backend(this);
-  size_t size = this->backend()->type_size(btype);
-  mpz_t size_val;
-  mpz_init_set_ui(size_val, size);
-  Type* uintptr = Type::lookup_integer_type("uintptr");
-  Expression* size_expr =
-Expression::make_integer(&size_val, uintptr, location);
-
-  // If the package imports unsafe, then it may play games with
-  // pointers that look like integers.
+  Expression* td = Expression::make_type_descriptor(type, location);
+  Expression* size =
+Expression::make_type_info(type, Expression::TYPE_INFO_SIZE);
+
+  // If this package imports unsafe, then it may play games with
+  // pointers that look like integers.  We should be able to determine
+  // whether or not to use 

Go patch committed: Remove old hidden_fields_are_ok code

2014-10-21 Thread Ian Taylor
Back in December 2011 I changed the Go frontend to permit assigning
structs with hidden fields
(https://gcc.gnu.org/ml/gcc-patches/2011-12/msg00632.html).  At the
time the language change was somewhat experimental, so I left the old
code.  The language change has clearly stuck, and that old code is
never used.  This patch removes it.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r dd6bc37fcf2d go/expressions.cc
--- a/go/expressions.cc Mon Oct 20 12:10:55 2014 -0700
+++ b/go/expressions.cc Tue Oct 21 08:34:29 2014 -0700
@@ -9305,13 +9305,7 @@
 bool issued_error)
 {
   std::string reason;
-  bool ok;
-  if (this->are_hidden_fields_ok_)
-ok = Type::are_assignable_hidden_ok(parameter_type, argument_type,
-   &reason);
-  else
-ok = Type::are_assignable(parameter_type, argument_type, &reason);
-  if (!ok)
+  if (!Type::are_assignable(parameter_type, argument_type, &reason))
 {
   if (!issued_error)
{
@@ -9359,13 +9353,11 @@
   go_assert(this->args_ != NULL && !this->args_->empty());
   Type* rtype = fntype->receiver()->type();
   Expression* first_arg = this->args_->front();
-  // The language permits copying hidden fields for a method
-  // receiver.  We dereference the values since receivers are
-  // always passed as pointers.
+  // We dereference the values since receivers are always passed
+  // as pointers.
   std::string reason;
-  if (!Type::are_assignable_hidden_ok(rtype->deref(),
- first_arg->type()->deref(),
- &reason))
+  if (!Type::are_assignable(rtype->deref(), first_arg->type()->deref(),
+   &reason))
{
  if (reason.empty())
this->report_error(_("incompatible type for receiver"));
diff -r dd6bc37fcf2d go/expressions.h
--- a/go/expressions.h  Mon Oct 20 12:10:55 2014 -0700
+++ b/go/expressions.h  Tue Oct 21 08:34:29 2014 -0700
@@ -1617,8 +1617,8 @@
 : Expression(EXPRESSION_CALL, location),
   fn_(fn), args_(args), type_(NULL), results_(NULL), call_(NULL),
   call_temp_(NULL), expected_result_count_(0), is_varargs_(is_varargs),
-  are_hidden_fields_ok_(false), varargs_are_lowered_(false),
-  types_are_determined_(false), is_deferred_(false), issued_error_(false)
+  varargs_are_lowered_(false), types_are_determined_(false),
+  is_deferred_(false), issued_error_(false)
   { }
 
   // The function to call.
@@ -1674,12 +1674,6 @@
   set_varargs_are_lowered()
   { this->varargs_are_lowered_ = true; }
 
-  // Note that it is OK for this call to set hidden fields when
-  // passing arguments.
-  void
-  set_hidden_fields_are_ok()
-  { this->are_hidden_fields_ok_ = true; }
-
   // Whether this call is being deferred.
   bool
   is_deferred() const
@@ -1788,9 +1782,6 @@
   size_t expected_result_count_;
   // True if the last argument is a varargs argument (f(a...)).
   bool is_varargs_;
-  // True if this statement may pass hidden fields in the arguments.
-  // This is used for generated method stubs.
-  bool are_hidden_fields_ok_;
   // True if varargs have already been lowered.
   bool varargs_are_lowered_;
   // True if types have been determined.
diff -r dd6bc37fcf2d go/statements.cc
--- a/go/statements.cc  Mon Oct 20 12:10:55 2014 -0700
+++ b/go/statements.cc  Tue Oct 21 08:34:29 2014 -0700
@@ -409,13 +409,7 @@
   if (this->type_ != NULL && this->init_ != NULL)
 {
   std::string reason;
-  bool ok;
-  if (this->are_hidden_fields_ok_)
-   ok = Type::are_assignable_hidden_ok(this->type_, this->init_->type(),
-   &reason);
-  else
-   ok = Type::are_assignable(this->type_, this->init_->type(), &reason);
-  if (!ok)
+  if (!Type::are_assignable(this->type_, this->init_->type(), &reason))
{
  if (reason.empty())
error_at(this->location(), "incompatible types in assignment");
@@ -511,15 +505,9 @@
   Assignment_statement(Expression* lhs, Expression* rhs,
   Location location)
 : Statement(STATEMENT_ASSIGNMENT, location),
-  lhs_(lhs), rhs_(rhs), are_hidden_fields_ok_(false)
+  lhs_(lhs), rhs_(rhs)
   { }
 
-  // Note that it is OK for this assignment statement to set hidden
-  // fields.
-  void
-  set_hidden_fields_are_ok()
-  { this->are_hidden_fields_ok_ = true; }
-
  protected:
   int
   do_traverse(Traverse* traverse);
@@ -544,9 +532,6 @@
   Expression* lhs_;
   // Right hand side--the rvalue.
   Expression* rhs_;
-  // True if this statement may set hidden fields in the assignment
-  // statement.  This is used for generated method stubs.
-  bool are_hidden_fields_ok_;
 };
 
 // Traversal.
@@ -607,12 +592,7 @@
 }
 
   std::string reason;
-  bool ok;
-  if (this->are_hidden_fields_ok_)
-ok = Type::are_assignable

Patch committed: Add missing ChangeLog entry

2014-10-22 Thread Ian Taylor
I committed this patch to the top-level ChangeLog to add a missing
entry.  I forgot to commit the ChangeLog patch with the real change
over a year ago, and just came across it.

Ian
Index: ChangeLog
===
--- ChangeLog   (revision 216522)
+++ ChangeLog   (working copy)
@@ -635,6 +635,12 @@
* configure.ac: Set libgloss_dir for the aarch64*-*-* targets.
* configure: Regenerated.
 
+2013-02-05  Ian Lance Taylor  
+
+   PR go/55969
+   * configure.ac: Disable libgo on some systems where it does not
+   work.
+
 2013-02-04  David Edelsohn  
 
* MAINTAINERS: Explicitly add myself as AIX maintainer.


Patch RFA: Top-level configure patch: disable go on systems where it doesn't work

2014-10-22 Thread Ian Taylor
This patch to the top level GCC configure script disables the go
languages on some systems where it is known to not work.  Bootstrapped
on x86_64-unknown-gnu-linux.

OK for mainline?

Ian

2014-10-22  Ian Lance Taylor  

* configure.ac: Disable the Go frontend on systems where it is known
to not work.
* configure: Regenerate.
Index: configure.ac
===
--- configure.ac(revision 216522)
+++ configure.ac(working copy)
@@ -772,6 +772,13 @@ case "${target}" in
 ;; 
 esac
 
+# Disable the go frontend on systems where it is known to not work.
+case "${target}" in
+*-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix*)
+unsupported_languages="$unsupported_languages go"
+;;
+esac
+
 # Disable libgo for some systems where it is known to not work.
 # For testing, you can easily override this with --enable-libgo.
 if test x$enable_libgo = x; then


Re: Patch RFA: Top-level configure patch: disable go on systems where it doesn't work

2014-10-23 Thread Ian Taylor
On Thu, Oct 23, 2014 at 8:27 AM, Pedro Alves  wrote:
>
> I think it'd be better if knowledge specific to subdirs was pushed down to
> the subdirs, rather than being kept in the top level, in the direction
> of how we disable libatomic, libsanitizer, etc.  That is, by sourcing
> something in the subdir to get back the info top level needs.  With that
> in place, changes to the set of supported hosts/targets/configurations
> no longer needs to be synchronized between the projects that use
> the top-level scripts.
>
> In the specific case of languages, it seems to be we already have such
> a script.  E.g.:
>
>   # First scan to see if an enabled language requires some other language.
>   # We assume that a given config-lang.in will list all the language
>   # front ends it requires, even if some are required indirectly.
>   for lang_frag in ${srcdir}/gcc/*/config-lang.in .. ; do
> case ${lang_frag} in
>
> Each config-lang.in sets some output variables.  For the case of a
> language being unsupported for some reason, we'd declare that
> the lang fragments can specify one more output variable, simply called
> "unsupported", and then in in go's gcc/go/config-lang.in, we'd add:
>
> # Disable the go frontend on systems where it is known to not work.
> case "${target}" in
> *-*-darwin* | *-*-cygwin* | *-*-mingw* | *-*-aix*)
> unsupported=true
> ;;
> esac
>
> Then back in the top level, near where we do:
>
> # Disable languages that need other directories if these aren't 
> available.
> for i in $subdir_requires; do
>   test -f "$srcdir/gcc/$i/config-lang.in" && continue
> ...
>
> We'd handle the "unsupported" variable.

My patch was, of course, just building on the existing
unsupported_languages support.  You are suggesting that we move that
support from the top level configure script to the language-specific
config-lang.in scripts.

That change sounds fine to me.

Ian


Re: Patch RFA: Top-level configure patch: disable go on systems where it doesn't work

2014-10-23 Thread Ian Taylor
On Thu, Oct 23, 2014 at 8:39 AM, Pedro Alves  wrote:
> On 10/23/2014 04:31 PM, Ian Taylor wrote:
>>
>> My patch was, of course, just building on the existing
>> unsupported_languages support.  You are suggesting that we move that
>> support from the top level configure script to the language-specific
>> config-lang.in scripts.
>
> AFAICS no target in the top level disables go yet, so we
> could IMO do the config-lang.in mechanism without moving any of
> the existing target checks for other languages.  It'd be a small
> change that way.

That sounds like setting up yet another incomplete transition.  I
would strongly prefer to have all languages act the same way.

Ian


libbacktrace patch committed: Fix load_pointer if no atomic or sync functions

2014-10-23 Thread Ian Taylor
This patch to libbacktrace fixes the type returned by the backup
definition of backtrace_atomic_load_pointer for the case where
libbacktrace is compiled with neither the atomic nor the sync
functions available.  This case does not arise in general but could
arise from other uses of the library, or when building stage 1 with a
very old host compiler.  Bootstrapped and ran libbacktrace tests on
x86_64-unknown-linux-gnu, which proves nothing, really.

Ian


2014-10-23  Ian Lance Taylor  

* internal.h (backtrace_atomic_load_pointer) [no atomic or sync]:
Fix to return void *.
Index: internal.h
===
--- internal.h  (revision 216522)
+++ internal.h  (working copy)
@@ -99,7 +99,7 @@ extern void backtrace_atomic_store_int (
 /* We have neither the sync nor the atomic functions.  These will
never be called.  */
 
-#define backtrace_atomic_load_pointer(p) (abort(), 0)
+#define backtrace_atomic_load_pointer(p) (abort(), (void *) NULL)
 #define backtrace_atomic_load_int(p) (abort(), 0)
 #define backtrace_atomic_store_pointer(p, v) abort()
 #define backtrace_atomic_store_size_t(p, v) abort()


Patch committed: Don't define TARGET_HAS_F_SETLKW

2014-10-23 Thread Ian Taylor
The target macro TARGET_HAS_F_SETLKW was removed from GCC back in 2005
(https://gcc.gnu.org/ml/gcc-patches/2005-07/msg00917.html).  I
happened to notice a dreg in mep.h.  After so long without a meaning,
it can't be necessary now.  This patch removes it.  Committed as
obvious.

Ian


2014-10-23  Ian Lance Taylor  

* config/mep/mep.h (TARGET_HAS_F_SETLKW): Don't define.
Index: gcc/config/mep/mep.h
===
--- gcc/config/mep/mep.h(revision 216522)
+++ gcc/config/mep/mep.h(working copy)
@@ -512,7 +512,6 @@ typedef struct
 /* Profiling is supported.  */
  
 #define FUNCTION_PROFILER(FILE, LABELNO) mep_function_profiler (FILE);
-#undef TARGET_HAS_F_SETLKW
 #define NO_PROFILE_COUNTERS 1
 
 /* Trampolines are built at run-time.  The cache is invalidated at


Patch committed: Fix typo in comment in tree-vrp.c

2014-10-23 Thread Ian Taylor
This patch fixes a typo in a comment in tree-vrp.c.  Committed as obvious.

Ian


2014-10-23  Ian Lance Taylor  

* tree-vrp.c (extract_range_from_assert): Fix typo in comment.
Index: gcc/tree-vrp.c
===
--- gcc/tree-vrp.c  (revision 216604)
+++ gcc/tree-vrp.c  (working copy)
@@ -1718,7 +1718,7 @@ extract_range_from_assert (value_range_t
 
   /* Make sure to not set TREE_OVERFLOW on the final type
 conversion.  We are willingly interpreting large positive
-unsigned values as negative singed values here.  */
+unsigned values as negative signed values here.  */
   min = force_fit_type (TREE_TYPE (var), wi::to_widest (min), 0, false);
   max = force_fit_type (TREE_TYPE (var), wi::to_widest (max), 0, false);
 


Go patch committed: Simplify making a constant integer expression

2014-10-23 Thread Ian Taylor
The Go frontend currently only makes integer expressions using the
mpz_t type, which is awkward when building an expression for a
constant or other ordinary C integer.  This patch adds a couple of
helper functions and changes the frontend to use them.  Bootstrapped
and ran Go testsuite on x86_64-unknown-linux-gnu.  Committed to
mainline.

Ian
diff -r 6887e559501c go/expressions.cc
--- a/go/expressions.cc Tue Oct 21 08:59:11 2014 -0700
+++ b/go/expressions.cc Thu Oct 23 18:43:32 2014 -0700
@@ -157,11 +157,8 @@
   else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
 {
   // Assigning nil to a slice.
-  mpz_t zval;
-  mpz_init_set_ui(zval, 0UL);
-  Expression* zero = Expression::make_integer(&zval, NULL, location);
-  mpz_clear(zval);
   Expression* nil = Expression::make_nil(location);
+  Expression* zero = Expression::make_integer_ul(0, NULL, location);
   return Expression::make_slice_value(lhs_type, nil, zero, zero, location);
 }
   else if (rhs_type->is_nil_type())
@@ -491,11 +488,7 @@
   Expression* index_overflows = Expression::make_boolean(false, loc);
   if (!val_is_unsigned)
 {
-  mpz_t zval;
-  mpz_init_set_ui(zval, 0UL);
-  Expression* zero = Expression::make_integer(&zval, val_type, loc);
-  mpz_clear(zval);
-
+  Expression* zero = Expression::make_integer_ul(0, val_type, loc);
   negative_index = Expression::make_binary(OPERATOR_LT, val, zero, loc);
 }
 
@@ -512,7 +505,7 @@
   mpz_init(maxval);
   mpz_mul_2exp(maxval, one, bound_type_size - 1);
   mpz_sub_ui(maxval, maxval, 1);
-  Expression* max = Expression::make_integer(&maxval, val_type, loc);
+  Expression* max = Expression::make_integer_z(&maxval, val_type, loc);
   mpz_clear(one);
   mpz_clear(maxval);
 
@@ -1824,8 +1817,8 @@
   return Expression::make_character(&this->val_, this->type_,
this->location());
 else
-  return Expression::make_integer(&this->val_, this->type_,
- this->location());
+  return Expression::make_integer_z(&this->val_, this->type_,
+   this->location());
   }
 
   void
@@ -2047,7 +2040,7 @@
   if (is_character_constant)
ret = Expression::make_character(&val, NULL, imp->location());
   else
-   ret = Expression::make_integer(&val, NULL, imp->location());
+   ret = Expression::make_integer_z(&val, NULL, imp->location());
   mpz_clear(val);
   return ret;
 }
@@ -2077,14 +2070,38 @@
 ast_dump_context->ostream() << '\'';
 }
 
-// Build a new integer value.
-
-Expression*
-Expression::make_integer(const mpz_t* val, Type* type, Location location)
+// Build a new integer value from a multi-precision integer.
+
+Expression*
+Expression::make_integer_z(const mpz_t* val, Type* type, Location location)
 {
   return new Integer_expression(val, type, false, location);
 }
 
+// Build a new integer value from an unsigned long.
+
+Expression*
+Expression::make_integer_ul(unsigned long val, Type *type, Location location)
+{
+  mpz_t zval;
+  mpz_init_set_ui(zval, val);
+  Expression* ret = Expression::make_integer_z(&zval, type, location);
+  mpz_clear(zval);
+  return ret;
+}
+
+// Build a new integer value from a signed long.
+
+Expression*
+Expression::make_integer_sl(long val, Type *type, Location location)
+{
+  mpz_t zval;
+  mpz_init_set_si(zval, val);
+  Expression* ret = Expression::make_integer_z(&zval, type, location);
+  mpz_clear(zval);
+  return ret;
+}
+
 // Build a new character constant value.
 
 Expression*
@@ -2593,12 +2610,7 @@
   "iota is only defined in const declarations");
  iota_value = 0;
}
-  mpz_t val;
-  mpz_init_set_ui(val, static_cast(iota_value));
-  Expression* ret = Expression::make_integer(&val, NULL,
-this->location());
-  mpz_clear(val);
-  return ret;
+  return Expression::make_integer_ul(iota_value, NULL, this->location());
 }
 
   // Make sure that the constant itself has been lowered.
@@ -3105,13 +3117,10 @@
   p != s.end();
   p++)
{
- mpz_t val;
- mpz_init_set_ui(val, static_cast(*p));
- Expression* v = Expression::make_integer(&val,
-  element_type,
-  location);
- vals->push_back(v);
- mpz_clear(val);
+ unsigned char c = static_cast(*p);
+ vals->push_back(Expression::make_integer_ul(c,
+ element_type,
+ location));
}
}
  el

Go patch committed: Use MPC library for complex numbers

2014-10-23 Thread Ian Taylor
This patch to the Go frontend changes it to use the MPC library for
complex numbers, rather than using pairs of MPFR values.  This is a
boilerplate change that lets us get rid of a bunch of code handling
complex constant multiplication and division.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian


2014-10-23  Ian Lance Taylor  

* go-gcc.cc (Gcc_backend::complex_constant_expression): Take one
mpc_t parameter instead of two mpfr_t parameters.
Index: gcc/go/go-gcc.cc
===
--- gcc/go/go-gcc.cc(revision 216522)
+++ gcc/go/go-gcc.cc(working copy)
@@ -247,7 +247,7 @@ class Gcc_backend : public Backend
   float_constant_expression(Btype* btype, mpfr_t val);
 
   Bexpression*
-  complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag);
+  complex_constant_expression(Btype* btype, mpc_t val);
 
   Bexpression*
   string_constant_expression(const std::string& val);
@@ -1241,7 +1241,7 @@ Gcc_backend::float_constant_expression(B
 // Return a typed real and imaginary value as a constant complex number.
 
 Bexpression*
-Gcc_backend::complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t 
imag)
+Gcc_backend::complex_constant_expression(Btype* btype, mpc_t val)
 {
   tree t = btype->get_tree();
   tree ret;
@@ -1249,12 +1249,12 @@ Gcc_backend::complex_constant_expression
 return this->error_expression();
 
   REAL_VALUE_TYPE r1;
-  real_from_mpfr(&r1, real, TREE_TYPE(t), GMP_RNDN);
+  real_from_mpfr(&r1, mpc_realref(val), TREE_TYPE(t), GMP_RNDN);
   REAL_VALUE_TYPE r2;
   real_convert(&r2, TYPE_MODE(TREE_TYPE(t)), &r1);
 
   REAL_VALUE_TYPE r3;
-  real_from_mpfr(&r3, imag, TREE_TYPE(t), GMP_RNDN);
+  real_from_mpfr(&r3, mpc_imagref(val), TREE_TYPE(t), GMP_RNDN);
   REAL_VALUE_TYPE r4;
   real_convert(&r4, TYPE_MODE(TREE_TYPE(t)), &r3);
 
Index: gcc/go/gofrontend/backend.h
===
--- gcc/go/gofrontend/backend.h (revision 216522)
+++ gcc/go/gofrontend/backend.h (working copy)
@@ -9,6 +9,7 @@
 
 #include 
 #include 
+#include 
 
 #include "operator.h"
 
@@ -277,9 +278,9 @@ class Backend
   virtual Bexpression*
   float_constant_expression(Btype* btype, mpfr_t val) = 0;
 
-  // Return an expression for the complex value REAL/IMAG in BTYPE.
+  // Return an expression for the complex value VAL in BTYPE.
   virtual Bexpression*
-  complex_constant_expression(Btype* btype, mpfr_t real, mpfr_t imag) = 0;
+  complex_constant_expression(Btype* btype, mpc_t val) = 0;
 
   // Return an expression for the string value VAL.
   virtual Bexpression*
Index: gcc/go/gofrontend/expressions.cc
===
--- gcc/go/gofrontend/expressions.cc(revision 216610)
+++ gcc/go/gofrontend/expressions.cc(working copy)
@@ -436,16 +436,14 @@ Expression::backend_numeric_constant_exp
 }
   else if (type->complex_type() != NULL)
 {
-  mpfr_t real;
-  mpfr_t imag;
-  if (!val->to_complex(&real, &imag))
+  mpc_t cval;
+  if (!val->to_complex(&cval))
 {
   go_assert(saw_errors());
   return gogo->backend()->error_expression();
 }
-  ret = gogo->backend()->complex_constant_expression(btype, real, imag);
-  mpfr_clear(real);
-  mpfr_clear(imag);
+  ret = gogo->backend()->complex_constant_expression(btype, cval);
+  mpc_clear(cval);
 }
   else
 go_unreachable();
@@ -2016,10 +2014,13 @@ Integer_expression::do_import(Import* im
   imag_str.c_str());
  return Expression::make_error(imp->location());
}
-  Expression* ret = Expression::make_complex(&real, &imag, NULL,
-imp->location());
+  mpc_t cval;
+  mpc_init2(cval, mpc_precision);
+  mpc_set_fr_fr(cval, real, imag, MPC_RNDNN);
   mpfr_clear(real);
   mpfr_clear(imag);
+  Expression* ret = Expression::make_complex(&cval, NULL, imp->location());
+  mpc_clear(cval);
   return ret;
 }
   else if (num.find('.') == std::string::npos
@@ -2297,23 +2298,21 @@ Expression::make_float(const mpfr_t* val
 class Complex_expression : public Expression
 {
  public:
-  Complex_expression(const mpfr_t* real, const mpfr_t* imag, Type* type,
-Location location)
+  Complex_expression(const mpc_t* val, Type* type, Location location)
 : Expression(EXPRESSION_COMPLEX, location),
   type_(type)
   {
-mpfr_init_set(this->real_, *real, GMP_RNDN);
-mpfr_init_set(this->imag_, *imag, GMP_RNDN);
+mpc_init2(this->val_, mpc_precision);
+mpc_set(this->val_, *val, MPC_RNDNN);
   }
 
-  // Write REAL/IMAG to string dump.
+  // Write VAL to string dump.
   static void
-  export_complex(String_dump* exp, const mpfr_t real, const mpfr_t val);
+  export_complex(String_dump* exp, const mpc_t val);
 
   // Write REAL/IMAG to dump context.
   static v

Re: Patch committed: Don't define TARGET_HAS_F_SETLKW

2014-10-24 Thread Ian Taylor
On Fri, Oct 24, 2014 at 6:26 AM, Andreas Schwab  wrote:
> Ian Taylor  writes:
>
>> 2014-10-23  Ian Lance Taylor  
>>
>> * config/mep/mep.h (TARGET_HAS_F_SETLKW): Don't define.
>
> s/define/undefine/

Thanks.  Fixed.  (Changes to ChangeLog files do not themselves require
ChangeLog entries.)

Ian
Index: gcc/ChangeLog
===
--- gcc/ChangeLog   (revision 216675)
+++ gcc/ChangeLog   (working copy)
@@ -200,7 +200,7 @@
 
 2014-10-23  Ian Lance Taylor  
 
-   * config/mep/mep.h (TARGET_HAS_F_SETLKW): Don't define.
+   * config/mep/mep.h (TARGET_HAS_F_SETLKW): Don't undefine.
 
 2014-10-23  Jakub Jelinek  
 


Re: Patch RFA: Top-level configure patch: disable go on systems where it doesn't work

2014-10-27 Thread Ian Taylor
On Mon, Oct 27, 2014 at 8:06 AM, Jan-Benedict Glaw  wrote:
>
> On Wed, 2014-10-22 20:36:53 -0700, Ian Taylor  wrote:
>> This patch to the top level GCC configure script disables the go
>> languages on some systems where it is known to not work.  Bootstrapped
>> on x86_64-unknown-gnu-linux.
>
> I don't have a clue here, but in what way is Go broken for these
> targets? Bacause this patch "breaks" a number of targets mentioned in
> contrib/config-list.mk.  Maybe Go didn't work on these, but it at
> least built.  Is it FUBAR there? Or just little fixes needed?

I'm not sure exactly what you mean by "breaks," here, as Go is never
in the set of default languages.  It should only break builds that are
using --enable-languages=go.  And for those targets, the Go support
has never worked, so they were already broken.

For Darwin I expect that only small fixes are needed.  This is
http://gcc.gnu.org/PR46986.

For Windows the compiler probably only needs small fixes, but the
libgo build will need a bunch of support, particularly in the syscall
package.  The support for Windows is mostly there in the code, because
it is in the master Go library, but it's not being built for libgo.

For AIX I'm not sure.  It's probably not too much work.

Ian


Re: Patch RFA: Top-level configure patch: disable go on systems where it doesn't work

2014-10-27 Thread Ian Taylor
On Mon, Oct 27, 2014 at 9:02 AM, Jan-Benedict Glaw  wrote:
> On Mon, 2014-10-27 08:19:34 -0700, Ian Taylor  wrote:
>> On Mon, Oct 27, 2014 at 8:06 AM, Jan-Benedict Glaw  wrote:
>> > On Wed, 2014-10-22 20:36:53 -0700, Ian Taylor  wrote:
>> > > This patch to the top level GCC configure script disables the go
>> > > languages on some systems where it is known to not work.  Bootstrapped
>> > > on x86_64-unknown-gnu-linux.
>> >
>> > I don't have a clue here, but in what way is Go broken for these
>> > targets? Bacause this patch "breaks" a number of targets mentioned in
>> > contrib/config-list.mk.  Maybe Go didn't work on these, but it at
>> > least built.  Is it FUBAR there? Or just little fixes needed?
>>
>> I'm not sure exactly what you mean by "breaks," here, as Go is never
>> in the set of default languages.  It should only break builds that are
>> using --enable-languages=go.  And for those targets, the Go support
>> has never worked, so they were already broken.
>
> With its initial commit in 2010, Joern had Go in the
> --enable-languages list in contrib/config-list.mk .  This used to work
> (read: build succeeded), even if Go wouldn't work (or wasn't built
> silently, I didn't check.)
>
>   With this slight change in behavior, we'd probably fix
> config-list.mk to reflect these targets where Go would lead to a
> configury failure early.

I think changing config-list.mk is appropriate.

I added this patch to the top-level configure script because someone
observed that it was annoying to configure GCC for Darwin with
--enable-languages=go, have the whole build succeed, and only then
discover that attempts to build Go programs failed with obscure error
messages.  That does not serve our users.

Ian


libgo patch committed: Update to 1.3.3

2014-10-27 Thread Ian Taylor
This patch to libgo updates it to the Go 1.3.3 release.  This is just
a few bug fixes.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r 03219f2d0191 libgo/MERGE
--- a/libgo/MERGE   Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/MERGE   Mon Oct 27 09:34:59 2014 -0700
@@ -1,4 +1,4 @@
-9895f9e36435
+f44017549ff9
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
diff -r 03219f2d0191 libgo/go/compress/gzip/gzip.go
--- a/libgo/go/compress/gzip/gzip.goThu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/compress/gzip/gzip.goMon Oct 27 09:34:59 2014 -0700
@@ -245,7 +245,8 @@
return z.err
 }
 
-// Close closes the Writer. It does not close the underlying io.Writer.
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
 func (z *Writer) Close() error {
if z.err != nil {
return z.err
diff -r 03219f2d0191 libgo/go/compress/zlib/writer.go
--- a/libgo/go/compress/zlib/writer.go  Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/compress/zlib/writer.go  Mon Oct 27 09:34:59 2014 -0700
@@ -174,7 +174,8 @@
return z.err
 }
 
-// Calling Close does not close the wrapped io.Writer originally passed to 
NewWriter.
+// Close closes the Writer, flushing any unwritten data to the underlying
+// io.Writer, but does not close the underlying io.Writer.
 func (z *Writer) Close() error {
if !z.wroteHeader {
z.err = z.writeHeader()
diff -r 03219f2d0191 libgo/go/crypto/rsa/pkcs1v15.go
--- a/libgo/go/crypto/rsa/pkcs1v15.go   Thu Oct 23 21:57:37 2014 -0700
+++ b/libgo/go/crypto/rsa/pkcs1v15.go   Mon Oct 27 09:34:59 2014 -0700
@@ -53,11 +53,14 @@
if err := checkPub(&priv.PublicKey); err != nil {
return nil, err
}
-   valid, out, err := decryptPKCS1v15(rand, priv, ciphertext)
-   if err == nil && valid == 0 {
-   err = ErrDecryption
+   valid, out, index, err := decryptPKCS1v15(rand, priv, ciphertext)
+   if err != nil {
+   return
}
-
+   if valid == 0 {
+   return nil, ErrDecryption
+   }
+   out = out[index:]
return
 }
 
@@ -80,21 +83,32 @@
}
k := (priv.N.BitLen() + 7) / 8
if k-(len(key)+3+8) < 0 {
-   err = ErrDecryption
-   return
+   return ErrDecryption
}
 
-   valid, msg, err := decryptPKCS1v15(rand, priv, ciphertext)
+   valid, em, index, err := decryptPKCS1v15(rand, priv, ciphertext)
if err != nil {
return
}
 
-   valid &= subtle.ConstantTimeEq(int32(len(msg)), int32(len(key)))
-   subtle.ConstantTimeCopy(valid, key, msg)
+   if len(em) != k {
+   // This should be impossible because decryptPKCS1v15 always
+   // returns the full slice.
+   return ErrDecryption
+   }
+
+   valid &= subtle.ConstantTimeEq(int32(len(em)-index), int32(len(key)))
+   subtle.ConstantTimeCopy(valid, key, em[len(em)-len(key):])
return
 }
 
-func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) 
(valid int, msg []byte, err error) {
+// decryptPKCS1v15 decrypts ciphertext using priv and blinds the operation if
+// rand is not nil. It returns one or zero in valid that indicates whether the
+// plaintext was correctly structured. In either case, the plaintext is
+// returned in em so that it may be read independently of whether it was valid
+// in order to maintain constant memory access patterns. If the plaintext was
+// valid then index contains the index of the original message in em.
+func decryptPKCS1v15(rand io.Reader, priv *PrivateKey, ciphertext []byte) 
(valid int, em []byte, index int, err error) {
k := (priv.N.BitLen() + 7) / 8
if k < 11 {
err = ErrDecryption
@@ -107,7 +121,7 @@
return
}
 
-   em := leftPad(m.Bytes(), k)
+   em = leftPad(m.Bytes(), k)
firstByteIsZero := subtle.ConstantTimeByteEq(em[0], 0)
secondByteIsTwo := subtle.ConstantTimeByteEq(em[1], 2)
 
@@ -115,8 +129,7 @@
// octets, followed by a 0, followed by the message.
//   lookingForIndex: 1 iff we are still looking for the zero.
//   index: the offset of the first zero byte.
-   var lookingForIndex, index int
-   lookingForIndex = 1
+   lookingForIndex := 1
 
for i := 2; i < len(em); i++ {
equals0 := subtle.ConstantTimeByteEq(em[i], 0)
@@ -129,8 +142,8 @@
validPS := subtle.ConstantTimeLessOrEq(2+8, index)
 
valid = firstByteIsZero & secondByteIsTwo & (^lookingForIndex & 1) & 
validPS
-   msg = em[index+1:]
-   return
+   index = subtle.ConstantTimeSelect(valid, index+1, 0)
+   return valid, em, index, nil
 }
 
 // nonZeroRandomBytes fills the giv

Install llgo version of libgo under a different name

2014-11-14 Thread Ian Taylor
This patch from Peter Collingbourne installs libgo under a different
name when it is built using llgo.  Bootstrapped and ran Go testsuite
on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r ed47faa83681 libgo/Makefile.am
--- a/libgo/Makefile.am Wed Nov 12 16:07:28 2014 -0800
+++ b/libgo/Makefile.am Fri Nov 14 09:40:03 2014 -0800
@@ -99,8 +99,13 @@
 # Subdir rules rely on $(FLAGS_TO_PASS)
 FLAGS_TO_PASS = $(AM_MAKEFLAGS)
 
+if GOC_IS_LLGO
+toolexeclib_LTLIBRARIES = libgo-llgo.la
+toolexeclib_LIBRARIES = libgobegin-llgo.a
+else
 toolexeclib_LTLIBRARIES = libgo.la
 toolexeclib_LIBRARIES = libgobegin.a
+endif
 
 toolexeclibgo_DATA = \
bufio.gox \
@@ -1993,18 +1998,27 @@
unicode/utf16.lo \
unicode/utf8.lo
 
-libgo_la_SOURCES = $(runtime_files)
-
-libgo_la_LDFLAGS = \
+libgo_ldflags = \
-version-info $(libtool_VERSION) $(PTHREAD_CFLAGS) $(AM_LDFLAGS)
 
-libgo_la_LIBADD = \
+libgo_libadd = \
$(libgo_go_objs) ../libbacktrace/libbacktrace.la \
$(LIBATOMIC) $(LIBFFI) $(PTHREAD_LIBS) $(MATH_LIBS) $(NET_LIBS)
 
+libgo_la_SOURCES = $(runtime_files)
+libgo_la_LDFLAGS = $(libgo_ldflags)
+libgo_la_LIBADD = $(libgo_libadd)
+
+libgo_llgo_la_SOURCES = $(runtime_files)
+libgo_llgo_la_LDFLAGS = $(libgo_ldflags)
+libgo_llgo_la_LIBADD = $(libgo_libadd)
+
 libgobegin_a_SOURCES = \
runtime/go-main.c
 
+libgobegin_llgo_a_SOURCES = \
+   runtime/go-main.c
+
 LTLDFLAGS = $(shell $(SHELL) $(top_srcdir)/../libtool-ldflags $(LDFLAGS))
 
 GOCFLAGS = $(CFLAGS)
@@ -2066,7 +2080,7 @@
fi
 
 # Build all packages before checking any.
-CHECK_DEPS = libgo.la libgobegin.a \
+CHECK_DEPS = \
$(toolexeclibgo_DATA) \
$(toolexeclibgoarchive_DATA) \
$(toolexeclibgocompress_DATA) \
@@ -2095,6 +2109,12 @@
$(toolexeclibgotexttemplate_DATA) \
$(toolexeclibgounicode_DATA)
 
+if GOC_IS_LLGO
+CHECK_DEPS += libgo-llgo.la libgobegin-llgo.a
+else
+CHECK_DEPS += libgo.la libgobegin.a
+endif
+
 @go_include@ bufio.lo.dep
 bufio.lo.dep: $(go_bufio_files)
$(BUILDDEPS)
diff -r ed47faa83681 libgo/configure.ac
--- a/libgo/configure.acWed Nov 12 16:07:28 2014 -0800
+++ b/libgo/configure.acFri Nov 14 09:40:03 2014 -0800
@@ -392,6 +392,14 @@
[Define if the linker support split stack adjustments])
 fi
 
+AC_CACHE_CHECK([whether compiler is llgo],
+[libgo_cv_c_goc_is_llgo],
+[libgo_cv_c_goc_is_llgo=no
+if $GOC -dumpversion 2>/dev/null | grep llgo >/dev/null 2>&1; then
+  libgo_cv_c_goc_is_llgo=yes
+fi])
+AM_CONDITIONAL(GOC_IS_LLGO, test "$libgo_cv_c_goc_is_llgo" = yes)
+
 dnl Test for the -lm library.
 MATH_LIBS=
 AC_CHECK_LIB([m], [sqrt], MATH_LIBS=-lm)


Re: [gofrontend-dev] [PATCH 4/4] Gccgo port to s390[x] -- part II

2014-11-15 Thread Ian Taylor
On Thu, Nov 13, 2014 at 2:58 AM, Dominik Vogt  wrote:
>
> What do you think about the attached patches?  They work for me, but I'm
> not sure whether the patch to go-test.exp is good because I know
> nothing about tcl.

Looks plausible to me.

Ian


Go patch committed: Fix initialization order

2014-11-18 Thread Ian Taylor
The Go frontend was slightly incorrect in the way that it handled the
order of initialization (http://golang.org/issue/8052).  Fortunately
it rarely made a difference in real code.  This patch by Chris
Manghane fixes it.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r 82f97044669e go/gogo.cc
--- a/go/gogo.ccFri Nov 14 10:02:13 2014 -0800
+++ b/go/gogo.ccTue Nov 18 09:02:23 2014 -0800
@@ -1018,11 +1018,11 @@
 {
  public:
   Var_init()
-: var_(NULL), init_(NULL)
+: var_(NULL), init_(NULL), dep_count_(0)
   { }
 
   Var_init(Named_object* var, Bstatement* init)
-: var_(var), init_(init)
+: var_(var), init_(init), dep_count_(0)
   { }
 
   // Return the variable.
@@ -1035,13 +1035,38 @@
   init() const
   { return this->init_; }
 
+  // Return the number of remaining dependencies.
+  size_t
+  dep_count() const
+  { return this->dep_count_; }
+
+  // Increment the number of dependencies.
+  void
+  add_dependency()
+  { ++this->dep_count_; }
+
+  // Decrement the number of dependencies.
+  void
+  remove_dependency()
+  { --this->dep_count_; }
+
  private:
   // The variable being initialized.
   Named_object* var_;
   // The initialization statement.
   Bstatement* init_;
+  // The number of initializations this is dependent on.  A variable
+  // initialization should not be emitted if any of its dependencies
+  // have not yet been resolved.
+  size_t dep_count_;
 };
 
+// For comparing Var_init keys in a map.
+
+inline bool
+operator<(const Var_init& v1, const Var_init& v2)
+{ return v1.var()->name() < v2.var()->name(); }
+
 typedef std::list Var_inits;
 
 // Sort the variable initializations.  The rule we follow is that we
@@ -1052,14 +1077,21 @@
 static void
 sort_var_inits(Gogo* gogo, Var_inits* var_inits)
 {
+  if (var_inits->empty())
+return;
+
   typedef std::pair No_no;
   typedef std::map Cache;
   Cache cache;
 
-  Var_inits ready;
-  while (!var_inits->empty())
-{
-  Var_inits::iterator p1 = var_inits->begin();
+  // A mapping from a variable initialization to a set of
+  // variable initializations that depend on it.
+  typedef std::map > Init_deps;
+  Init_deps init_deps;
+  for (Var_inits::iterator p1 = var_inits->begin();
+   p1 != var_inits->end();
+   ++p1)
+{
   Named_object* var = p1->var();
   Expression* init = var->var_value()->init();
   Block* preinit = var->var_value()->preinit();
@@ -1067,11 +1099,13 @@
 
   // Start walking through the list to see which variables VAR
   // needs to wait for.
-  Var_inits::iterator p2 = p1;
-  ++p2;
-
-  for (; p2 != var_inits->end(); ++p2)
+  for (Var_inits::iterator p2 = var_inits->begin();
+  p2 != var_inits->end();
+  ++p2)
{
+ if (var == p2->var())
+   continue;
+
  Named_object* p2var = p2->var();
  No_no key(var, p2var);
  std::pair ins =
@@ -1080,6 +1114,10 @@
ins.first->second = expression_requires(init, preinit, dep, p2var);
  if (ins.first->second)
{
+ // VAR depends on P2VAR.
+ init_deps[*p2].insert(&(*p1));
+ p1->add_dependency();
+
  // Check for cycles.
  key = std::make_pair(p2var, var);
  ins = cache.insert(std::make_pair(key, false));
@@ -1100,36 +1138,66 @@
 p2var->message_name().c_str());
  p2 = var_inits->end();
}
- else
-   {
- // We can't emit P1 until P2 is emitted.  Move P1.
- Var_inits::iterator p3 = p2;
- ++p3;
- var_inits->splice(p3, *var_inits, p1);
-   }
- break;
}
}
-
-  if (p2 == var_inits->end())
+}
+
+  // If there are no dependencies then the declaration order is sorted.
+  if (!init_deps.empty())
+{
+  // Otherwise, sort variable initializations by emitting all variables 
with
+  // no dependencies in declaration order. VAR_INITS is already in
+  // declaration order.
+  Var_inits ready;
+  while (!var_inits->empty())
{
- // VAR does not depends upon any other initialization expressions.
-
- // Check for a loop of VAR on itself.  We only do this if
- // INIT is not NULL and there is no dependency; when INIT is
- // NULL, it means that PREINIT sets VAR, which we will
- // interpret as a loop.
- if (init != NULL && dep == NULL
- && expression_requires(init, preinit, NULL, var))
-   error_at(var->location(),
-"initialization expression for %qs depends upon itself",
-var->message_name().c_str());
- ready.splice(ready.end(), *var_inits, p1);
+ Var_inits::iterator v1;;
+ for (v1 = var_inits->begin(); v1 != var_inits->end(); ++v1)
+   {
+ if

Re: [gofrontend-dev] [PATCH 7/9] Gccgo port to s390[x] -- part I

2014-10-28 Thread Ian Taylor
On Tue, Oct 28, 2014 at 7:31 AM, Dominik Vogt  wrote:
>
> The attached patch contains all the discussed changes.

I made a few formatting changes.  I patched the test to work on x86,
by making the char types accept either int8 or uint8, and making the
long double tests accept any floating point size.

Approved and applied as attached.

Thanks.

Ian


gcc/:
2014-10-28  Dominik Vogt  

* godump.c (precision_to_units): New helper function.
(go_append_artificial_name): Ditto.
(go_append_decl_name): Ditto.
(go_append_bitfield): Ditto.
(go_get_uinttype_for_precision): Ditto.
(go_append_padding): Ditto.
(go_force_record_alignment): Ditto.
(go_format_type): Represent unions with an array of uints of the size
of the alignment in go.  This fixes the 'random' size of the union's
representation using just the first field.
(go_format_type): Add argument that indicates whether a record is
nested (used for generation of artificial go names).
(go_output_fndecl): Adapt to new go_format_type signature.
(go_output_typedef): Ditto.
(go_output_var): Ditto.
(go_output_var): Prefer to output type as alias (typedef).
(go_format_type): Bitfields in records are simulated as arrays of bytes
in go.

* godump.c (go_format_type): Fix handling of arrays with zero elements.


gcc/testsuite/:
2014-10-28  Dominik Vogt  

* gcc.misc-tests/godump.exp: New.
* gcc.misc-tests/godump-1.c: New.
Index: godump.c
===
--- godump.c(revision 216766)
+++ godump.c(working copy)
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.
 #include "obstack.h"
 #include "debug.h"
 #include "wide-int-print.h"
+#include "stor-layout.h"
+#include "defaults.h"
 
 /* We dump this information from the debug hooks.  This gives us a
stable and maintainable API to hook into.  In order to work
@@ -73,6 +75,15 @@ struct macro_hash_value
   char *value;
 };
 
+/* Returns the number of units necessary to represent an integer with the given
+   PRECISION (in bits).  */
+
+static inline unsigned int
+precision_to_units (unsigned int precision)
+{
+  return (precision + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+}
+
 /* Calculate the hash value for an entry in the macro hash table.  */
 
 static hashval_t
@@ -552,19 +563,132 @@ go_append_string (struct obstack *ob, tr
   obstack_grow (ob, IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
 }
 
+/* Given an integer PRECISION in bits, returns a constant string that is the
+   matching go int or uint type (depending on the IS_UNSIGNED flag).  Returns a
+   NULL pointer if there is no matching go type.  */
+
+static const char *
+go_get_uinttype_for_precision (unsigned int precision, bool is_unsigned)
+{
+  switch (precision)
+{
+case 8:
+  return is_unsigned ? "uint8" : "int8";
+case 16:
+  return is_unsigned ? "uint16" : "int16";
+case 32:
+  return is_unsigned ? "uint32" : "int32";
+case 64:
+  return is_unsigned ? "uint64" : "int64";
+default:
+  return NULL;
+}
+}
+
+/* Append an artificial variable name with the suffix _INDEX to OB.  Returns
+   INDEX + 1.  */
+
+static unsigned int
+go_append_artificial_name (struct obstack *ob, unsigned int index)
+{
+  char buf[100];
+
+  /* FIXME: identifier may not be unique.  */
+  obstack_grow (ob, "Godump_", 7);
+  snprintf (buf, sizeof buf, "%u", index);
+  obstack_grow (ob, buf, strlen (buf));
+
+  return index + 1;
+}
+
+/* Append the variable name from DECL to OB.  If the name is in the
+   KEYWORD_HASH, prepend an '_'.  */
+
+static void
+go_append_decl_name (struct obstack *ob, tree decl, htab_t keyword_hash)
+{
+  const char *var_name;
+  void **slot;
+
+  /* Start variable name with an underscore if a keyword.  */
+  var_name = IDENTIFIER_POINTER (DECL_NAME (decl));
+  slot = htab_find_slot (keyword_hash, var_name, NO_INSERT);
+  if (slot != NULL)
+obstack_1grow (ob, '_');
+  go_append_string (ob, DECL_NAME (decl));
+}
+
+/* Appends a byte array with the necessary number of elements and the name
+   "Godump_INDEX_pad" to pad from FROM_OFFSET to TO_OFFSET to OB assuming that
+   the next field is automatically aligned to ALIGN_UNITS.  Returns INDEX + 1,
+   or INDEX if no padding had to be appended.  The resulting offset where the
+   next field is allocated is returned through RET_OFFSET.  */
+
+static unsigned int
+go_append_padding (struct obstack *ob, unsigned int from_offset,
+  unsigned int to_offset, unsigned int align_units,
+  unsigned int index, unsigned int *ret_offset)
+{
+  if (from_offset % align_units > 0)
+from_offset += align_units - (from_offset % align_units);
+  gcc_assert (to_offset >= from_offset);
+  if (to_offset > from_offset)
+{
+  char buf[100];
+
+  index = go_append_artificial_name (ob, index);
+  snprintf (buf,

libgo patch committed: Add consts for ioctl

2014-10-28 Thread Ian Taylor
This patch from Lynn Boger ensures that some ioctl constants are
available on more systems.  Bootstrapped and ran Go testsuite on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r ec3c929aae72 libgo/mksysinfo.sh
--- a/libgo/mksysinfo.shTue Oct 28 10:34:18 2014 -0700
+++ b/libgo/mksysinfo.shTue Oct 28 11:16:30 2014 -0700
@@ -174,6 +174,9 @@
 #ifdef TIOCGWINSZ
   TIOCGWINSZ_val = TIOCGWINSZ,
 #endif
+#ifdef TIOCSWINSZ
+  TIOCSWINSZ_val = TIOCSWINSZ,
+#endif
 #ifdef TIOCNOTTY
   TIOCNOTTY_val = TIOCNOTTY,
 #endif
@@ -192,6 +195,12 @@
 #ifdef TIOCSIG
   TIOCSIG_val = TIOCSIG,
 #endif
+#ifdef TCGETS
+  TCGETS_val = TCGETS,
+#endif
+#ifdef TCSETS
+  TCSETS_val = TCSETS,
+#endif
 };
 EOF
 
@@ -790,6 +799,11 @@
 echo 'const TIOCGWINSZ = _TIOCGWINSZ_val' >> ${OUT}
   fi
 fi
+if ! grep '^const TIOCSWINSZ' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TIOCSWINSZ_val' ${OUT} >/dev/null 2>&1; then
+echo 'const TIOCSWINSZ = _TIOCSWINSZ_val' >> ${OUT}
+  fi
+fi
 if ! grep '^const TIOCNOTTY' ${OUT} >/dev/null 2>&1; then
   if grep '^const _TIOCNOTTY_val' ${OUT} >/dev/null 2>&1; then
 echo 'const TIOCNOTTY = _TIOCNOTTY_val' >> ${OUT}
@@ -822,8 +836,18 @@
 fi
 
 # The ioctl flags for terminal control
-grep '^const _TC[GS]ET' gen-sysinfo.go | \
+grep '^const _TC[GS]ET' gen-sysinfo.go | grep -v _val | \
 sed -e 's/^\(const \)_\(TC[GS]ET[^= ]*\)\(.*\)$/\1\2 = _\2/' >> ${OUT}
+if ! grep '^const TCGETS' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TCGETS_val' ${OUT} >/dev/null 2>&1; then
+echo 'const TCGETS = _TCGETS_val' >> ${OUT}
+  fi
+fi
+if ! grep '^const TCSETS' ${OUT} >/dev/null 2>&1; then
+  if grep '^const _TCSETS_val' ${OUT} >/dev/null 2>&1; then
+echo 'const TCSETS = _TCSETS_val' >> ${OUT}
+  fi
+fi
 
 # ioctl constants.  Might fall back to 0 if TIOCNXCL is missing, too, but
 # needs handling in syscalls.exec.go.


libgo patch committed: Recognize PPC relocs

2014-10-28 Thread Ian Taylor
This patch to libgo recognizes PPC relocations in the debug/elf
package.  This is a backport of
https://codereview.appspot.com/125910043 which was applied to the PPC
development branch of the master Go repository.  For this patch
bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian
diff -r 30cebdd47f70 libgo/go/debug/elf/elf.go
--- a/libgo/go/debug/elf/elf.go Tue Oct 28 11:18:19 2014 -0700
+++ b/libgo/go/debug/elf/elf.go Tue Oct 28 15:53:31 2014 -0700
@@ -1162,6 +1162,184 @@
 func (i R_PPC) String() string   { return stringName(uint32(i), rppcStrings, 
false) }
 func (i R_PPC) GoString() string { return stringName(uint32(i), rppcStrings, 
true) }
 
+// Relocation types for PowerPC 64.
+type R_PPC64 int
+
+const (
+   R_PPC64_NONE   R_PPC64 = 0
+   R_PPC64_ADDR32 R_PPC64 = 1
+   R_PPC64_ADDR24 R_PPC64 = 2
+   R_PPC64_ADDR16 R_PPC64 = 3
+   R_PPC64_ADDR16_LO  R_PPC64 = 4
+   R_PPC64_ADDR16_HI  R_PPC64 = 5
+   R_PPC64_ADDR16_HA  R_PPC64 = 6
+   R_PPC64_ADDR14 R_PPC64 = 7
+   R_PPC64_ADDR14_BRTAKEN R_PPC64 = 8
+   R_PPC64_ADDR14_BRNTAKENR_PPC64 = 9
+   R_PPC64_REL24  R_PPC64 = 10
+   R_PPC64_REL14  R_PPC64 = 11
+   R_PPC64_REL14_BRTAKEN  R_PPC64 = 12
+   R_PPC64_REL14_BRNTAKEN R_PPC64 = 13
+   R_PPC64_GOT16  R_PPC64 = 14
+   R_PPC64_GOT16_LO   R_PPC64 = 15
+   R_PPC64_GOT16_HI   R_PPC64 = 16
+   R_PPC64_GOT16_HA   R_PPC64 = 17
+   R_PPC64_JMP_SLOT   R_PPC64 = 21
+   R_PPC64_REL32  R_PPC64 = 26
+   R_PPC64_ADDR64 R_PPC64 = 38
+   R_PPC64_ADDR16_HIGHER  R_PPC64 = 39
+   R_PPC64_ADDR16_HIGHERA R_PPC64 = 40
+   R_PPC64_ADDR16_HIGHEST R_PPC64 = 41
+   R_PPC64_ADDR16_HIGHESTAR_PPC64 = 42
+   R_PPC64_REL64  R_PPC64 = 44
+   R_PPC64_TOC16  R_PPC64 = 47
+   R_PPC64_TOC16_LO   R_PPC64 = 48
+   R_PPC64_TOC16_HI   R_PPC64 = 49
+   R_PPC64_TOC16_HA   R_PPC64 = 50
+   R_PPC64_TOCR_PPC64 = 51
+   R_PPC64_ADDR16_DS  R_PPC64 = 56
+   R_PPC64_ADDR16_LO_DS   R_PPC64 = 57
+   R_PPC64_GOT16_DS   R_PPC64 = 58
+   R_PPC64_GOT16_LO_DSR_PPC64 = 59
+   R_PPC64_TOC16_DS   R_PPC64 = 63
+   R_PPC64_TOC16_LO_DSR_PPC64 = 64
+   R_PPC64_TLSR_PPC64 = 67
+   R_PPC64_DTPMOD64   R_PPC64 = 68
+   R_PPC64_TPREL16R_PPC64 = 69
+   R_PPC64_TPREL16_LO R_PPC64 = 70
+   R_PPC64_TPREL16_HI R_PPC64 = 71
+   R_PPC64_TPREL16_HA R_PPC64 = 72
+   R_PPC64_TPREL64R_PPC64 = 73
+   R_PPC64_DTPREL16   R_PPC64 = 74
+   R_PPC64_DTPREL16_LOR_PPC64 = 75
+   R_PPC64_DTPREL16_HIR_PPC64 = 76
+   R_PPC64_DTPREL16_HAR_PPC64 = 77
+   R_PPC64_DTPREL64   R_PPC64 = 78
+   R_PPC64_GOT_TLSGD16R_PPC64 = 79
+   R_PPC64_GOT_TLSGD16_LO R_PPC64 = 80
+   R_PPC64_GOT_TLSGD16_HI R_PPC64 = 81
+   R_PPC64_GOT_TLSGD16_HA R_PPC64 = 82
+   R_PPC64_GOT_TLSLD16R_PPC64 = 83
+   R_PPC64_GOT_TLSLD16_LO R_PPC64 = 84
+   R_PPC64_GOT_TLSLD16_HI R_PPC64 = 85
+   R_PPC64_GOT_TLSLD16_HA R_PPC64 = 86
+   R_PPC64_GOT_TPREL16_DS R_PPC64 = 87
+   R_PPC64_GOT_TPREL16_LO_DS  R_PPC64 = 88
+   R_PPC64_GOT_TPREL16_HI R_PPC64 = 89
+   R_PPC64_GOT_TPREL16_HA R_PPC64 = 90
+   R_PPC64_GOT_DTPREL16_DSR_PPC64 = 91
+   R_PPC64_GOT_DTPREL16_LO_DS R_PPC64 = 92
+   R_PPC64_GOT_DTPREL16_HIR_PPC64 = 93
+   R_PPC64_GOT_DTPREL16_HAR_PPC64 = 94
+   R_PPC64_TPREL16_DS R_PPC64 = 95
+   R_PPC64_TPREL16_LO_DS  R_PPC64 = 96
+   R_PPC64_TPREL16_HIGHER R_PPC64 = 97
+   R_PPC64_TPREL16_HIGHERAR_PPC64 = 98
+   R_PPC64_TPREL16_HIGHESTR_PPC64 = 99
+   R_PPC64_TPREL16_HIGHESTA   R_PPC64 = 100
+   R_PPC64_DTPREL16_DSR_PPC64 = 101
+   R_PPC64_DTPREL16_LO_DS R_PPC64 = 102
+   R_PPC64_DTPREL16_HIGHERR_PPC64 = 103
+   R_PPC64_DTPREL16_HIGHERA   R_PPC64 = 104
+   R_PPC64_DTPREL16_HIGHEST   R_PPC64 = 105
+   R_PPC64_DTPREL16_HIGHESTA  R_PPC64 = 106
+   R_PPC64_TLSGD  R_PPC64 = 107
+   R_PPC64_TLSLD  R_PPC64 = 108
+   R_PPC64_REL16  R_PPC64 = 249
+   R_PPC64_REL16_LO   R_PPC64 = 250
+   R_PPC64_REL16_HI   R_PPC64 = 251
+   R_PPC64_REL16_HA   R_PPC64 = 252
+)
+
+var rppc64Strings = []intName{
+   {0, "R_PPC64_NONE"},
+   {1, "R_PPC64_ADDR32"},
+   {2, "R_PPC64_ADDR24"},
+   {3, "R_PPC64_ADDR16"},
+   {4, "R_PPC64_ADDR16_LO"},
+   {5, "R_PPC64_ADDR16_HI"},
+   {6, "R_PPC64_ADD

Re: [gofrontend-dev] [PATCH 8/9] Gccgo port to s390[x] -- part I

2014-10-29 Thread Ian Taylor
On Wed, Oct 29, 2014 at 12:01 AM, Dominik Vogt  wrote:
> Patch updated to remove conflicts with changed tests in patch 7.

Thanks.  Approved and committed.

Ian


Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I

2014-10-29 Thread Ian Taylor
On Wed, Oct 29, 2014 at 9:38 AM, Andreas Schwab  wrote:
> I'm getting these test failures on m68k-linux:

Can you send the file BUILDDIR/gcc/testsuite/gcc/godump-1.out?

Ian


Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I

2014-10-29 Thread Ian Taylor
Thanks.  Part of the problem is that the m68k max alignment is 16
bits, but the godump test expects it to be at least 64 bits.  This is
BIGGEST_ALIGNMENT in config/m68k/m68k.h.  Another part of the problem
seems to be that structs are sometimes aligned to 16 bits although
there is no obvious reason for that.  I'm not sure where that is
coming from.

I'll let Dominik decide how he wants to handle this.  We could disable
the test on m68k or make it more accepting.  There may be problems on
other architectures as well.

Ian


Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I

2014-10-30 Thread Ian Taylor
On Thu, Oct 30, 2014 at 12:25 AM, Dominik Vogt  wrote:
> On Wed, Oct 29, 2014 at 10:16:40AM -0700, Ian Taylor wrote:
>> Thanks.  Part of the problem is that the m68k max alignment is 16
>> bits, but the godump test expects it to be at least 64 bits.  This is
>> BIGGEST_ALIGNMENT in config/m68k/m68k.h.  Another part of the problem
>> seems to be that structs are sometimes aligned to 16 bits although
>> there is no obvious reason for that.  I'm not sure where that is
>> coming from.
>
> Hm, the test cases make assumptions about the Abi (structure
> padding and alignment) that are true on x86, x64_64 and s390[x].
> That may not be the case on other platforms and hence the tests
> fail.  Another candidate for test failures is the effect of
> bitfields (named or anonymous) on structure layout.
>
>> We could disable the test on m68k or make it more accepting.
>
> Since the point of some of the tests is to make sure that the Go
> structure layout matches the C layout, making the tests accept
> deviations seems to be rather pointless.  It's possible to add
> target selectors to all the "scan-file" lines, but that is a lot
> of work and will likely become unmaintainable very soon when more
> platforms need to be added.  Personally I cannot provide fixed
> tests for all the Abis either, so my suggestion is to "xfail" the
> test on all targets except s390[x] and x86_64 and leave it to the
> people who know the other platforms to decide whether the test
> should work there or how the test could be modified to work.
>
> See attached patch.

I don't mind skipping the test on other platforms, but xfail is not
correct.  When an xfail test passes, we get an XPASS error from the
testsuite.  We need dg-skip-if.  I committed this patch.

Ian


2014-10-30  Dominik Vogt  

* gcc.misc-tests/godump-1.c: Skip -fdump-go-spec tests for all
platforms except s390[x] and x86_64.
Index: gcc.misc-tests/godump-1.c
===
--- gcc.misc-tests/godump-1.c   (revision 216840)
+++ gcc.misc-tests/godump-1.c   (working copy)
@@ -2,6 +2,7 @@
 
 /* { dg-options "-c -fdump-go-spec=godump-1.out" } */
 /* { dg-do compile } */
+/* { dg-skip-if "not supported for target" { ! "s390*-*-* x86_64-*-*" } } */
 
 #include 
 


Re: [PATCH] config-list.mk: Build Go only for supported targets (was: Patch RFA: Top-level configure patch: disable go on systems where it doesn't work)

2014-10-30 Thread Ian Taylor
On Thu, Oct 30, 2014 at 6:19 AM, Jan-Benedict Glaw  wrote:
>
> This updates contrib/config-list.mk to build Go for all but
> known-non-working targets. A comment to configure{.ac,} is also added.



> diff --git a/contrib/config-list.mk b/contrib/config-list.mk
> index 94884d9..16900e1 100644
> --- a/contrib/config-list.mk
> +++ b/contrib/config-list.mk
> @@ -95,11 +95,24 @@ make-log-dir: ../gcc/MAINTAINERS
>
>  $(LIST): make-log-dir
> -mkdir $@
> -   (cd $@ && \
> -   ../../gcc/configure \
> -   --target=$(subst SCRIPTS,`pwd`/../scripts/,$(subst OPT,$(empty) 
> -,$@)) \
> -   --enable-werror-always ${host_options} --enable-languages=all,ada,go) 
> \
> -   > log/$@-config.out 2>&1
> +   ( 
>   \
> +   cd $@ &&  
>   \
> +   echo $@ &&
>   \
> +   TGT=`echo $@ | sed -e 's/^\(.*\)OPT.*$$/\1/'` &&  
>   \
> +   TGT=`../../gcc/config.sub $$TGT` &&   
>   \

This isn't necessary.  The OPT bits will be matched by the * at the
end of the cases anyhow.  You can just write
 case $@ in

This is OK with that change.

Thanks for doing it.

Ian


Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I

2014-10-30 Thread Ian Taylor
On Thu, Oct 30, 2014 at 8:05 AM, Uros Bizjak  wrote:
>
>  /* { dg-options "-c -fdump-go-spec=godump-1.out" } */
>  /* { dg-do compile } */
> +/* { dg-skip-if "not supported for target" { ! "s390*-*-* x86_64-*-*" } } */
>
> x86_64 also needs && lp64, otherwise -m32 will defeat this condition.

Thanks.  I committed this patch.

Ian


2014-10-30  Ian Lance Taylor  

* gcc.misc-tests/godump-1.c: Skip if ! lp64.
Index: gcc.misc-tests/godump-1.c
===
--- gcc.misc-tests/godump-1.c   (revision 216936)
+++ gcc.misc-tests/godump-1.c   (working copy)
@@ -3,6 +3,7 @@
 /* { dg-options "-c -fdump-go-spec=godump-1.out" } */
 /* { dg-do compile } */
 /* { dg-skip-if "not supported for target" { ! "s390*-*-* x86_64-*-*" } } */
+/* { dg-skip-if "not supported for target" { ! lp64 } } */
 
 #include 
 


Re: [PATCH] config-list.mk: Build Go only for supported targets (was: Patch RFA: Top-level configure patch: disable go on systems where it doesn't work)

2014-10-30 Thread Ian Taylor
On Thu, Oct 30, 2014 at 12:14 PM, Jan-Benedict Glaw  wrote:
> On Thu, 2014-10-30 08:08:51 -0700, Ian Taylor  wrote:
>> On Thu, Oct 30, 2014 at 6:19 AM, Jan-Benedict Glaw  wrote:
>> >
>> > This updates contrib/config-list.mk to build Go for all but
>> > known-non-working targets. A comment to configure{.ac,} is also added.
>>
>> > diff --git a/contrib/config-list.mk b/contrib/config-list.mk
>> > index 94884d9..16900e1 100644
>> > --- a/contrib/config-list.mk
>> > +++ b/contrib/config-list.mk
>> > @@ -95,11 +95,24 @@ make-log-dir: ../gcc/MAINTAINERS
>> >
>> >  $(LIST): make-log-dir
>> > -mkdir $@
>> > -   (cd $@ && \
>> > -   ../../gcc/configure \
>> > -   --target=$(subst SCRIPTS,`pwd`/../scripts/,$(subst OPT,$(empty) 
>> > -,$@)) \
>> > -   --enable-werror-always ${host_options} 
>> > --enable-languages=all,ada,go) \
>> > -   > log/$@-config.out 2>&1
>> > +   (  
>> >  \
>> > +   cd $@ &&   
>> >  \
>> > +   echo $@ && 
>> >  \
>> > +   TGT=`echo $@ | sed -e 's/^\(.*\)OPT.*$$/\1/'` &&   
>> >  \
>> > +   TGT=`../../gcc/config.sub $$TGT` &&
>> >  \
>>
>> This isn't necessary.  The OPT bits will be matched by the * at the
>> end of the cases anyhow.  You can just write
>>  case $@ in
>>
>> This is OK with that change.
>
> Not exactly: My intention was to keep the triplet matches as they show
> up in configure.ac .  However, the target list in config-list.mk uses
> (almost exclusively) shorthands for all the targets, so these need to
> be expand (--> config.sub); that however won't really fly with the
> OPTs in there.

Oh, right, sorry.

The original patch is OK.

Thanks.

Ian


Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I

2014-10-31 Thread Ian Taylor
On Fri, Oct 31, 2014 at 2:11 AM, Dominik Vogt  wrote:
> On Thu, Oct 30, 2014 at 07:51:45AM -0700, Ian Taylor wrote:
>> On Thu, Oct 30, 2014 at 12:25 AM, Dominik Vogt  
>> wrote:
>> > See attached patch.
>>
>> I don't mind skipping the test on other platforms, but xfail is not
>> correct.  When an xfail test passes, we get an XPASS error from the
>> testsuite.  We need dg-skip-if.  I committed this patch.
>
> That is exactly the reason why I chose dg-xfail-if:  To identify
> the targets where the test works out of the box, because I think
> there won't be many of them.

That would be fine if coupled with an immediate plan to test on all
systems.  What we don't want is an XPASS on some random system six
months from now that forces some poor GCC developer who knows nothing
at all about this code to figure out what is going on.


> But anyway, we can leave it as it is for the moment and eventually
> I'll get around cleaning that up.

OK.

Ian


libgo patch committed: Use -dumpversion rather than looking at BASE-VER

2014-11-03 Thread Ian Taylor
This patch from Peter Collingbourne changes the libgo install to get
the version number from gccgo -dumpversion rather than looking at the
BASE-VER file in the gcc source directory.  Bootstrapped on
x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff -r 21b8b46b67f2 libgo/Makefile.am
--- a/libgo/Makefile.am Tue Oct 28 15:56:23 2014 -0700
+++ b/libgo/Makefile.am Mon Nov 03 08:29:13 2014 -0800
@@ -15,7 +15,7 @@
 
 SUBDIRS = ${subdirs}
 
-gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
+gcc_version := $(shell $(GOC) -dumpversion)
 
 MAINT_CHARSET = latin1
 


Re: Recent go changes broke alpha bootstrap

2014-11-03 Thread Ian Taylor
On Mon, Nov 3, 2014 at 9:02 AM, Dominik Vogt  wrote:
> On Thu, Oct 30, 2014 at 08:05:14AM -0700, Ian Taylor wrote:
>> On Thu, Oct 30, 2014 at 5:46 AM, Dominik Vogt  
>> wrote:
>> > I'm not quite sure about the best approach.  The attempt to
>> > represent C unions in the "right" way is ultimately futile as Go
>> > does not have the types necessary for it.  For example, the
>> > handling of anonymous bit fields will never be right as it's
>> > undefinied.  On the other hand I could fix the issue at hand by
>> > changing the way anonymous unions are represented in Go.
>> >
>> > Example:
>> >
>> >   struct { int8_t x; union { int16_t y; int 32_t z; }; };
>> >
>> > Was represented (before the patch) as
>> >
>> >   struct { X byte; int16 Y; }
>> >
>> > which had size 4, alignment 2 and y at offset 2 but should had
>> > have size 8, alignment 4 and y at offset 4.  With the current
>> > patch the Go layout is
>> >
>> >   struct { X byte; artificial_name struct { y [2]byte; align [0]int32; } }
>> >
>> > with the proper size, alignment and offset, but y is addressed as
>> > ".artificial_name.y" insted of just ".y", and y is a byte array
>> > and not an int16.
>> >
>> > I could remove the "artificial_name struct" and add padding before
>> > and after y instead:
>> >
>> >   struct { X byte; pad_0 [3]byte; Y int16; pad_1 [2]byte; align [0]int32; }
>> >
>> > What do you think?
>>
>> Sounds good to me.  Basically the fields of the anonymous union should
>> be promoted to become fields of the struct.  We can't do it in
>> general, but we can do it for the first field.  That addresses the
>> actual uses of anonymous unions.
>
> The attached patch fixes this, at least if the first element of the
> union is not a bitfield.
>
> Bitfields can really not be represented properly in Go (think about
> constructs like "struct { int : 1; int bf : 1; }"), I'd rather not
> try to represent them in a predictable way.  The patched code may
> or may not give them a name, and reserves the proper amount of
> padding where required in structs.  If a union begins with an
> anonymous bitfield (which makes no sense), that is ignored.  If a
> union begins with a named bitfield (possibly after unnamed ones),
> this may or may not be used as the (sole) element of the Go
> struct.


Thanks.  I committed your patch.

Ian


Go patch committed: untyped bool for logical operators

2014-11-04 Thread Ian Taylor
The Go language was tweaked to permit logical operators to return an
untyped boolean value, which means that code like
type myBool bool
var b myBool = a < b || c < d
is now permitted (previously the || operator would return the named
type "bool" and an explicit conversion was required for this code).

This patch from Chris Manghane implements this in gccgo, simply by
removing the old code that prevented it from working.  This requires
adjusting one existing testcase.  This is http://golang.org/issue/6671
.

Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian
Index: gcc/go/gofrontend/expressions.cc
===
--- gcc/go/gofrontend/expressions.cc(revision 217049)
+++ gcc/go/gofrontend/expressions.cc(working copy)
@@ -5314,15 +5314,6 @@ Binary_expression::do_determine_type(con
   subcontext.type = NULL;
 }
 
-  if (this->op_ == OPERATOR_ANDAND || this->op_ == OPERATOR_OROR)
-{
-  // For a logical operation, the context does not determine the
-  // types of the operands.  The operands must be some boolean
-  // type but if the context has a boolean type they do not
-  // inherit it.  See http://golang.org/issue/3924.
-  subcontext.type = NULL;
-}
-
   // Set the context for the left hand operand.
   if (is_shift_op)
 {
Index: gcc/testsuite/go.test/test/fixedbugs/issue3924.go
===
--- gcc/testsuite/go.test/test/fixedbugs/issue3924.go   (revision 217049)
+++ gcc/testsuite/go.test/test/fixedbugs/issue3924.go   (working copy)
@@ -1,4 +1,4 @@
-// errorcheck
+// compile
 
 // Copyright 2012 The Go Authors.  All rights reserved.
 // Use of this source code is governed by a BSD-style
@@ -9,5 +9,5 @@ package foo
 type mybool bool
 
 var x, y = 1, 2
-var _ mybool = x < y && x < y // ERROR "cannot use"
-var _ mybool = x < y || x < y // ERROR "cannot use"
+var _ mybool = x < y && x < y
+var _ mybool = x < y || x < y


Re: [gofrontend-dev] [PATCH 1/4] Gccgo port to s390[x] -- part II

2014-11-04 Thread Ian Taylor
On Tue, Nov 4, 2014 at 4:15 AM, Dominik Vogt  wrote:
> See commit comment and ChangeLog for details.

>   case "amd64", "386":
> + case "s390", "s390x":

Note that this doesn't do what you want.  In Go, unlike C, cases do
not fall through by default.  So doing this means that the amd64 and
386 cases do nothing at all.

I will change it to

case "amd64", "386", "s390", "s390x":

Ian


Re: [gofrontend-dev] [PATCH 1/4] Gccgo port to s390[x] -- part II

2014-11-04 Thread Ian Taylor
On Tue, Nov 4, 2014 at 4:15 AM, Dominik Vogt  wrote:
> See commit comment and ChangeLog for details.

Committed patch 0001 with various formatting fixes, as attached.

Note that libgo/runtime/runtime.c now refers to S390_HAVE_STCKF.  It's
not obvious to me that that is defined anywhere.  Perhaps it is in a
later patch in this series--I haven't looked.

Ian
diff -r 836325fe0181 libgo/Makefile.am
--- a/libgo/Makefile.am Tue Nov 04 09:45:01 2014 -0800
+++ b/libgo/Makefile.am Tue Nov 04 14:19:01 2014 -0800
@@ -943,11 +943,26 @@
 go_reflect_makefunc_s_file = \
go/reflect/makefunc_386.S
 else
+if LIBGO_IS_S390
+go_reflect_makefunc_file = \
+   go/reflect/makefuncgo_s390.go
+go_reflect_makefunc_s_file = \
+   go/reflect/makefunc_s390.c
+else
+if LIBGO_IS_S390X
+go_reflect_makefunc_file = \
+   go/reflect/makefuncgo_s390x.go \
+   go/reflect/makefuncgo_s390.go
+go_reflect_makefunc_s_file = \
+   go/reflect/makefunc_s390.c
+else
 go_reflect_makefunc_file =
 go_reflect_makefunc_s_file = \
go/reflect/makefunc_dummy.c
 endif
 endif
+endif
+endif
 
 go_reflect_files = \
go/reflect/deepequal.go \
diff -r 836325fe0181 libgo/configure.ac
--- a/libgo/configure.acTue Nov 04 09:45:01 2014 -0800
+++ b/libgo/configure.acTue Nov 04 14:19:01 2014 -0800
@@ -194,6 +194,8 @@
 mips_abi=unknown
 is_ppc=no
 is_ppc64=no
+is_s390=no
+is_s390x=no
 is_sparc=no
 is_sparc64=no
 is_x86_64=no
@@ -271,6 +273,18 @@
   GOARCH=ppc64
 fi
 ;;
+  s390*-*-*)
+AC_COMPILE_IFELSE([
+#if defined(__s390x__)
+#error 64-bit
+#endif],
+[is_s390=yes], [is_s390x=yes])
+if test "$is_s390" = "yes"; then
+  GOARCH=s390
+else
+  GOARCH=s390x
+fi
+;;
   sparc*-*-*)
 AC_COMPILE_IFELSE([
 #if defined(__sparcv9) || defined(__arch64__)
@@ -296,6 +310,8 @@
 AM_CONDITIONAL(LIBGO_IS_MIPSO64, test $mips_abi = o64)
 AM_CONDITIONAL(LIBGO_IS_PPC, test $is_ppc = yes)
 AM_CONDITIONAL(LIBGO_IS_PPC64, test $is_ppc64 = yes)
+AM_CONDITIONAL(LIBGO_IS_S390, test $is_s390 = yes)
+AM_CONDITIONAL(LIBGO_IS_S390X, test $is_s390x = yes)
 AM_CONDITIONAL(LIBGO_IS_SPARC, test $is_sparc = yes)
 AM_CONDITIONAL(LIBGO_IS_SPARC64, test $is_sparc64 = yes)
 AM_CONDITIONAL(LIBGO_IS_X86_64, test $is_x86_64 = yes)
diff -r 836325fe0181 libgo/go/debug/elf/elf.go
--- a/libgo/go/debug/elf/elf.go Tue Nov 04 09:45:01 2014 -0800
+++ b/libgo/go/debug/elf/elf.go Tue Nov 04 14:19:01 2014 -0800
@@ -1340,6 +1340,72 @@
 func (i R_PPC64) String() string   { return stringName(uint32(i), 
rppc64Strings, false) }
 func (i R_PPC64) GoString() string { return stringName(uint32(i), 
rppc64Strings, true) }
 
+// Relocation types for s390
+type R_390 int
+
+const (
+   R_390_NONE R_390 = 0
+   R_390_8R_390 = 1
+   R_390_12   R_390 = 2
+   R_390_16   R_390 = 3
+   R_390_32   R_390 = 4
+   R_390_PC32 R_390 = 5
+   R_390_GOT12R_390 = 6
+   R_390_GOT32R_390 = 7
+   R_390_PLT32R_390 = 8
+   R_390_COPY R_390 = 9
+   R_390_GLOB_DAT R_390 = 10
+   R_390_JMP_SLOT R_390 = 11
+   R_390_RELATIVE R_390 = 12
+   R_390_GOTOFF   R_390 = 13
+   R_390_GOTPCR_390 = 14
+   R_390_GOT16R_390 = 15
+   R_390_PC16 R_390 = 16
+   R_390_PC16DBL  R_390 = 17
+   R_390_PLT16DBL R_390 = 18
+   R_390_PC32DBL  R_390 = 19
+   R_390_PLT32DBL R_390 = 20
+   R_390_GOTPCDBL R_390 = 21
+   R_390_64   R_390 = 22
+   R_390_PC64 R_390 = 23
+   R_390_GOT64R_390 = 24
+   R_390_PLT64R_390 = 25
+   R_390_GOTENT   R_390 = 26
+)
+
+var r390Strings = []intName{
+   {0, "R_390_NONE"},
+   {1, "R_390_8"},
+   {2, "R_390_12"},
+   {3, "R_390_16"},
+   {4, "R_390_32"},
+   {5, "R_390_PC32"},
+   {6, "R_390_GOT12"},
+   {7, "R_390_GOT32"},
+   {8, "R_390_PLT32"},
+   {9, "R_390_COPY"},
+   {10, "R_390_GLOB_DAT"},
+   {11, "R_390_JMP_SLOT"},
+   {12, "R_390_RELATIVE"},
+   {13, "R_390_GOTOFF"},
+   {14, "R_390_GOTPC"},
+   {15, "R_390_GOT16"},
+   {16, "R_390_PC16"},
+   {17, "R_390_PC16DBL"},
+   {18, "R_390_PLT16DBL"},
+   {19, "R_390_PC32DBL"},
+   {20, "R_390_PLT32DBL"},
+   {21, "R_390_GOTPCDBL"},
+   {22, "R_390_64"},
+   {23, "R_390_PC64"},
+   {24, "R_390_GOT64"},
+   {25, "R_390_PLT64"},
+   {26, "R_390_GOTENT"},
+}
+
+func (i R_390) String() string   { return stringName(uint32(i), r390Strings, 
false) }
+func (i R_390) GoString() string { return stringName(uint32(i), r390Strings, 
true) }
+
 // Relocation types for SPARC.
 type R_SPARC int
 
diff -r 836325fe0181 libgo/go/debug/elf/file.go
--- a/libgo/go/debug/elf/file.goTue Nov 04 09:45:01 2014 -0800
+++ b/libgo/go/debug/elf/file.goTue Nov 04 14:19:01 2014 -0800
@@ -528,6 +528,9 @@
if f.Class == ELFCLASS64 && f.Machine == EM_PPC64 {
return f.applyRelocationsPPC64(dst, rels)
}
+   if

Re: [gofrontend-dev] [PATCH 2/4] Gccgo port to s390[x] -- part II

2014-11-04 Thread Ian Taylor
Part of this patch duplicates a patch that is already applied to the
master Go library, so I explicitly backported that patch
(https://codereview.appspot.com/111320044) instead.

Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian
diff -r 3b8f536b76d8 libgo/go/sync/atomic/atomic_test.go
--- a/libgo/go/sync/atomic/atomic_test.go   Tue Nov 04 14:36:54 2014 -0800
+++ b/libgo/go/sync/atomic/atomic_test.go   Tue Nov 04 19:37:03 2014 -0800
@@ -858,7 +858,7 @@
addr := (*int32)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
for {
-   v := *addr
+   v := LoadInt32(addr)
if CompareAndSwapInt32(addr, v, v+1) {
break
}
@@ -869,7 +869,7 @@
 func hammerCompareAndSwapUint32(addr *uint32, count int) {
for i := 0; i < count; i++ {
for {
-   v := *addr
+   v := LoadUint32(addr)
if CompareAndSwapUint32(addr, v, v+1) {
break
}
@@ -883,7 +883,7 @@
addr := (*uintptr)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
for {
-   v := *addr
+   v := LoadUintptr(addr)
if CompareAndSwapUintptr(addr, v, v+1) {
break
}
@@ -897,7 +897,7 @@
addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
for {
-   v := *addr
+   v := LoadPointer(addr)
if CompareAndSwapPointer(addr, v, 
unsafe.Pointer(uintptr(v)+1)) {
break
}
@@ -1039,7 +1039,7 @@
addr := (*int64)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
for {
-   v := *addr
+   v := LoadInt64(addr)
if CompareAndSwapInt64(addr, v, v+1) {
break
}
@@ -1050,7 +1050,7 @@
 func hammerCompareAndSwapUint64(addr *uint64, count int) {
for i := 0; i < count; i++ {
for {
-   v := *addr
+   v := LoadUint64(addr)
if CompareAndSwapUint64(addr, v, v+1) {
break
}
@@ -1064,7 +1064,7 @@
addr := (*uintptr)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
for {
-   v := *addr
+   v := LoadUintptr(addr)
if CompareAndSwapUintptr(addr, v, v+1) {
break
}
@@ -1078,7 +1078,7 @@
addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
for {
-   v := *addr
+   v := LoadPointer(addr)
if CompareAndSwapPointer(addr, v, 
unsafe.Pointer(uintptr(v)+1)) {
break
}


Re: [gofrontend-dev] [PATCH 2/4] Gccgo port to s390[x] -- part II

2014-11-04 Thread Ian Taylor
For the rest of this patch, I replied on the bug
(http://gcc.gnu.org/PR63269).  I'm not persuaded that the approach
this patch takes is correct.

Ian


Re: [gofrontend-dev] [PATCH 3/4] Gccgo port to s390[x] -- part II

2014-11-04 Thread Ian Taylor
I committed this patch.

Thanks.

I changed the ChangeLog entry to this, since your ChangeLog entry
didn't seem accurate to me.

2014-11-04  Dominik Vogt  

* go.test/go-test.exp: In +build lines, require whitespace around
expected strings, fix check for negation.

Ian


Re: [gofrontend-dev] [PATCH 0/4] Gccgo port to s390[x] -- part II

2014-11-04 Thread Ian Taylor
On Tue, Nov 4, 2014 at 4:15 AM, Dominik Vogt  wrote:
>
> This is the second set of patches to support s390[x] with Gccgo,
> containing mostly architecture dependent parts that affect the
> following directories:

> Summary of this series:
> ---
>
> 0001: Ports libgo to s390[x].
> 0002: Adapts some tests in libgo but also fixes some bugs in the
>   tests.
> 0003: Allow "//+ build" for the go tests in Gcc.
> 0004: s390[x] specific fixes for some tests in golang.

Thanks.  I've replied to all the patches in this series.

Ian


Re: [gofrontend-dev] [PATCH 4/4] Gccgo port to s390[x] -- part II

2014-11-04 Thread Ian Taylor
I committed the change to go-test.exp.  Thanks.

The other changes are not OK.  As described in
gcc/testsuite/go.test/test/README.gcc, the files in
gcc/testsuite/go.test/test are an exact copy of the master Go
testsuite.  Any changes must be made to the master Go testsuite first.

I don't know what's up with the complex number change.  In general the
Go compiler and libraries go to some effort to produce the same
answers on all platforms.  We need to understand why we get different
answers on s390 (you may understand the differences, but I don't).  I
won't change the tests without a clear understanding of why we are
changing them.

The nilptr test doesn't run on some other platforms when using
gccgo--search for "nilptr" in go-test.exp.  If you want to work out a
way to change the master Go testsuite such that the nilptr test passes
on more platforms, that would be great.  The way to do it is not by
copying the test.  If the test needs to be customized, add additional
files that use // +build lines to pick which files is built.  Move
them into a directory, like method4.go or other tests that use
"rundir".

Ian


Re: [gofrontend-dev] [PATCH 4/4] Gccgo port to s390[x] -- part II

2014-11-05 Thread Ian Taylor
On Wed, Nov 5, 2014 at 2:05 AM, Dominik Vogt  wrote:
> On Tue, Nov 04, 2014 at 08:16:51PM -0800, Ian Taylor wrote:
>> I committed the change to go-test.exp.  Thanks.
>>
>> The other changes are not OK.  As described in
>> gcc/testsuite/go.test/test/README.gcc, the files in
>> gcc/testsuite/go.test/test are an exact copy of the master Go
>> testsuite.  Any changes must be made to the master Go testsuite first.
>
> I understand that, but I'm unsure how to handle a set of patches
> that all depend on each other but refer to three different
> reposiories.  So I posted this patch intentionally in the wrong
> place, not knowing how to do it in a better way.

Changes to the master Go repository must follow the procedure
described at http://golang.org/doc/contribute.html.


>> I don't know what's up with the complex number change. In general the
>> Go compiler and libraries go to some effort to produce the same
>> answers on all platforms.  We need to understand why we get different
>> answers on s390 (you may understand the differences, but I don't).  I
>> won't change the tests without a clear understanding of why we are
>> changing them.
>
> It's actually not a Go specific problem, the same deviation occurs
> in C code too.  The cause is that constant folding is done with a
> higher precision and may yield a different result than the run
> time calculations.  There is a Gcc bug report for that "issue":
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60181

So far it doesn't sound appropriate to change the Go testsuite for
this.  If the immediate goal is simply to get the s390 tests to pass,
let's change go-test.exp to xfail the test unless and until somebody
figures out the whole issue.

Ian


Re: [gofrontend-dev] [PATCH 1/4] Gccgo port to s390[x] -- part II

2014-11-06 Thread Ian Taylor
On Thu, Nov 6, 2014 at 7:34 AM, Dominik Vogt  wrote:
> On Thu, Nov 06, 2014 at 03:02:13PM +0100, Rainer Orth wrote:
>> Ian Taylor  writes:
>> > Committed patch 0001 with various formatting fixes, as attached.
>>
>> Unfortunately, the mksysinfo.sh part broke Solaris bootstrap: there's no
>> type _ucred in gen-sysinfo.go, so the grep in upcase_fields fails.  Due
>> to the use of set -e, the whole script aborts.
>
> The attached patch fixes the problem.

Thanks.  Committed.

Ian


Re: [gofrontend-dev] [PATCH 1/4] Gccgo port to s390[x] -- part II

2014-11-06 Thread Ian Taylor
On Wed, Nov 5, 2014 at 4:55 AM, Dominik Vogt  wrote:
> On Wed, Nov 05, 2014 at 11:31:28AM +0100, Dominik Vogt wrote:
>> On Tue, Nov 04, 2014 at 02:39:34PM -0800, Ian Taylor wrote:
>> > Note that libgo/runtime/runtime.c now refers to S390_HAVE_STCKF.  It's
>> > not obvious to me that that is defined anywhere.  Perhaps it is in a
>> > later patch in this series--I haven't looked.
>
> The attached patch fixes this (by using stckf unconditionally).

Thanks.  Committed.

Ian


Re: [gofrontend-dev] [PATCH 4/4] Gccgo port to s390[x] -- part II

2014-11-06 Thread Ian Taylor
On Thu, Nov 6, 2014 at 4:04 AM, Dominik Vogt  wrote:
> On Tue, Nov 04, 2014 at 08:16:51PM -0800, Ian Taylor wrote:
>> The way to do it is not by
>> copying the test.  If the test needs to be customized, add additional
>> files that use // +build lines to pick which files is built.  Move
>> them into a directory, like method4.go or other tests that use
>> "rundir".
>
> Currently go-test.exp does not look at the "build" lines of the
> files in subdirectories.  Before I add that to the gcc testsuite
> start adding that, is it certain that the golang testsuite will be
> able to understand that and compile only the requested files?

Hmmm, that is a good point.  The testsuite doesn't use the go command
to build the files in subdirectories, so it won't honor the +build
lines.  I didn't think of that.  Sorry for pointing you in the wrong
direction.

I'd still like to avoid the rampant duplication if possible.  One
approach would be to put most of the test in something like
nilptr_tests.go marked with "// skip".  Then we can have top-level
nilptrXX.go tests with +build lines that use "// run nilptr_tests.go".

(By the way, it's not "golang;" it's "Go."  Please try to avoid the
term "golang."  Thanks.)

Ian


Re: [gofrontend-dev] Re: [PATCH 00/13] Go closures, libffi, and the static chain

2014-11-06 Thread Ian Taylor
On Thu, Nov 6, 2014 at 5:04 AM, Richard Henderson  wrote:
>
> That said, this *may* not actually be a problem.  It's not the direct 
> (possibly
> lazy bound) call into libffi that needs a static chain, it's the indirect call
> that libffi produces.  And the indirect calls that Go produces.
>
> I'm pretty sure that there are no dynamically linked Go calls that require the
> static chain.  They're used for closures, which are either fully indirect from
> a different translation unit, or locally bound closures through which the
> optimizer has seen the construction, and optimized to a direct call.
>
> Ian, have I missed a case where a closure could wind up with a direct call to 
> a
> lazy bound function?

I think you've covered all the cases.  The closure value is only
required when calling a nested function.  There is no way to refer
directly to a nested function defined in a different shared library.
The only way you can get such a reference is if some function in that
shared library returns it.

So we are OK assuming that when returning a nested function, which is
always known to be locally defined, we never return a reference to the
PLT, but always return a fully resolved function address.  That seems
like a plausible assumption, particularly since we should never need
to set up a PLT for a nested function, since it can never be called
directly from a different shared library.

Ian


Re: [gofrontend-dev] Re: [PATCH 00/13] Go closures, libffi, and the static chain

2014-11-07 Thread Ian Taylor
On Thu, Nov 6, 2014 at 11:38 PM, Richard Henderson  wrote:
> On 11/06/2014 06:45 PM, Ian Taylor wrote:
>> On Thu, Nov 6, 2014 at 5:04 AM, Richard Henderson  wrote:
>>>
>>> That said, this *may* not actually be a problem.  It's not the direct 
>>> (possibly
>>> lazy bound) call into libffi that needs a static chain, it's the indirect 
>>> call
>>> that libffi produces.  And the indirect calls that Go produces.
>>>
>>> I'm pretty sure that there are no dynamically linked Go calls that require 
>>> the
>>> static chain.  They're used for closures, which are either fully indirect 
>>> from
>>> a different translation unit, or locally bound closures through which the
>>> optimizer has seen the construction, and optimized to a direct call.
>>>
>>> Ian, have I missed a case where a closure could wind up with a direct call 
>>> to a
>>> lazy bound function?
>>
>> I think you've covered all the cases.  The closure value is only
>> required when calling a nested function.  There is no way to refer
>> directly to a nested function defined in a different shared library.
>> The only way you can get such a reference is if some function in that
>> shared library returns it.
>
> Sorry, I wasn't clear.  I know nested functions must be local.
>
> I'm asking about Go closures, supposing we go ahead with the change to
> make them use the static chain register.

I think we're saying the same thing.

Closures exist only for nested functions and for functions created by
reflect.MakeFunc and friends.

Storing a top-level function into a variable will give you something
that looks like it has a closure, but the closure will always be empty
and it will never be used.  The indirect call will set the closure
value in the static chain register, but the register will not be used
by the function being called.

> I'm merely pretty sure that calling a closure is either fully indirect
> or local direct.

Yes.

> Certainly there are cases in the testsuite where -O3 is able to look
> through the creation of a closure and have a direct call to the function.
>
> Given that closures are custom created for the data at the creation
> site, it seems unlikely that the optimizer could look through that and
> come up with a dynamically bound function.

Yes.

Ian


Re: [gofrontend-dev] [PATCH 4/4] Gccgo port to s390[x] -- part II

2014-11-07 Thread Ian Taylor
On Fri, Nov 7, 2014 at 12:51 AM, Dominik Vogt  wrote:
> On Thu, Nov 06, 2014 at 09:06:18AM -0800, Ian Taylor wrote:
>> On Thu, Nov 6, 2014 at 4:04 AM, Dominik Vogt  wrote:
>> > On Tue, Nov 04, 2014 at 08:16:51PM -0800, Ian Taylor wrote:
>> >> The way to do it is not by
>> >> copying the test.  If the test needs to be customized, add additional
>> >> files that use // +build lines to pick which files is built.  Move
>> >> them into a directory, like method4.go or other tests that use
>> >> "rundir".
>> >
>> > Currently go-test.exp does not look at the "build" lines of the
>> > files in subdirectories.  Before I add that to the gcc testsuite
>> > start adding that, is it certain that the golang testsuite will be
>> > able to understand that and compile only the requested files?
>>
>> Hmmm, that is a good point.  The testsuite doesn't use the go command
>> to build the files in subdirectories, so it won't honor the +build
>> lines.  I didn't think of that.  Sorry for pointing you in the wrong
>> direction.
>
> That's no problem, I can enhance go-test.exp in Gcc.  The question
> is if test cases extended in such a way would run in the master Go
> repository too.  Are the tests there run with the Go tool?

I'm sorry, I wasn't clear.  The test cases will not work in the master
Go repository.  When I said "the testsuite doesn't use go command" I
was referring to the master testsuite.  Sorry for the confusion.

Ian


Re: [gofrontend-dev] [PATCH 4/4] Gccgo port to s390[x] -- part II

2014-11-10 Thread Ian Taylor
On Mon, Nov 10, 2014 at 6:00 AM, Dominik Vogt  wrote:
>> I'd still like to avoid the rampant duplication if possible.  One
>> approach would be to put most of the test in something like
>> nilptr_tests.go marked with "// skip".  Then we can have top-level
>> nilptrXX.go tests with +build lines that use "// run nilptr_tests.go".
>
> I fail to see how that could be done with "// run".  There is one
> example use, namely cmplxdivide.go".  That is not run in gcc
> because the "run" line does not match anything in go-test.exp.  If
> I add a rule for that, how does that help me to compile a test
> that consists of multiple files?

That test is run (all tests are run or explicitly skipped or marked
unsupported).  In go-test.exp look for
$test_line == "// run cmplxdivide1.go"

Ian


libgo patch committed: Update libtool support

2014-11-11 Thread Ian Taylor
This patch to libgo updates the libtool support to that currently
found in the gcc trunk.  This includes a patch for support of OS X
10.10.  Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

This is Go issue 9089.

Ian
diff -r 1c308e945873 libgo/config/libtool.m4
--- a/libgo/config/libtool.m4   Thu Nov 06 08:59:53 2014 -0800
+++ b/libgo/config/libtool.m4   Tue Nov 11 19:43:19 2014 -0800
@@ -1011,7 +1011,7 @@
   case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
10.0,*86*-darwin8*|10.0,*-darwin[[91]]*)
  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
-   10.[[012]]*)
+   10.[[012]][[,.]]*)
  _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined 
${wl}suppress' ;;
10.*)
  _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
@@ -1237,7 +1237,14 @@
LD="${LD-ld} -m elf_i386_fbsd"
;;
  x86_64-*linux*)
-   LD="${LD-ld} -m elf_i386"
+   case `/usr/bin/file conftest.o` in
+ *x86-64*)
+   LD="${LD-ld} -m elf32_x86_64"
+   ;;
+ *)
+   LD="${LD-ld} -m elf_i386"
+   ;;
+   esac
;;
  powerpc64le-*linux*)
LD="${LD-ld} -m elf32lppclinux"
@@ -1293,27 +1300,14 @@
 CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
-*-*solaris*)
+sparc*-*solaris*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
 case `/usr/bin/file conftest.o` in
 *64-bit*)
   case $lt_cv_prog_gnu_ld in
-  yes*)
-case $host in
-i?86-*-solaris* | x86_64-*-solaris2.1[[0-9]]*)
-  LD="${LD-ld} -m elf_x86_64"
-  ;;
-sparc*-*-solaris*)
-  LD="${LD-ld} -m elf64_sparc"
-  ;;
-esac
-# GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
-if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
-  LD="${LD-ld}_sol2"
-fi
-;;
+  yes*) LD="${LD-ld} -m elf64_sparc" ;;
   *)
if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
  LD="${LD-ld} -64"
@@ -2297,7 +2291,7 @@
 objformat=`/usr/bin/objformat`
   else
 case $host_os in
-freebsd[[123]]*) objformat=aout ;;
+freebsd[[23]].*) objformat=aout ;;
 *) objformat=elf ;;
 esac
   fi
@@ -2315,7 +2309,7 @@
   esac
   shlibpath_var=LD_LIBRARY_PATH
   case $host_os in
-  freebsd2*)
+  freebsd2.*)
 shlibpath_overrides_runpath=yes
 ;;
   freebsd3.[[01]]* | freebsdelf3.[[01]]*)
@@ -3597,6 +3591,7 @@
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
   fi
+  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
   ;;
 
 amigaos*)
@@ -3908,6 +3903,7 @@
# AIX 5 now supports IA64 processor
_LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
   fi
+  _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
   ;;
 
 amigaos*)
@@ -4828,7 +4824,7 @@
   ;;
 
 # Unfortunately, older versions of FreeBSD 2 do not have this feature.
-freebsd2*)
+freebsd2.*)
   _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs 
$linker_flags'
   _LT_TAGVAR(hardcode_direct, $1)=yes
   _LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -5775,7 +5771,7 @@
 esac
 ;;
 
-  freebsd[[12]]*)
+  freebsd2.*)
 # C++ shared libraries reported to be fairly broken before
# switch to ELF
 _LT_TAGVAR(ld_shlibs, $1)=no
diff -r 1c308e945873 libgo/config/ltmain.sh
--- a/libgo/config/ltmain.shThu Nov 06 08:59:53 2014 -0800
+++ b/libgo/config/ltmain.shTue Nov 11 19:43:19 2014 -0800
@@ -5928,7 +5928,7 @@
 test "$hardcode_direct_absolute" = no; then
add="$dir/$linklib"
  elif test "$hardcode_minus_L" = yes; then
-   add_dir="-L$dir"
+   add_dir="-L$absdir"
# Try looking first in the location we're being installed to.
if test -n "$inst_prefix_dir"; then
  case $libdir in


Go patch committed: Report unused packages correctly for ambiguous lookups

2014-11-12 Thread Ian Taylor
This patch from Chris Manghane fixes the Go frontend to correctly
report unused packages when there are ambiguous lookups.  Previously
some cases involving composite literals could cause a package to be
considered as used, when it was really not used.  That is, in some
cases, the compiler did not report an error that it should have
reported.  This is http://golang.org/issue/6427 .

Bootstrapped and ran testsuite on x86_64-unknown-linux-gnu.  Committed
to mainline.

Ian
Index: gcc/go/gofrontend/expressions.cc
===
--- gcc/go/gofrontend/expressions.cc(revision 217402)
+++ gcc/go/gofrontend/expressions.cc(working copy)
@@ -12791,6 +12791,16 @@ Composite_literal_expression::lower_stru
{
case EXPRESSION_UNKNOWN_REFERENCE:
  name = name_expr->unknown_expression()->name();
+ if (type->named_type() != NULL)
+   {
+ // If the named object found for this field name comes from a
+ // different package than the struct it is a part of, do not count
+ // this incorrect lookup as a usage of the object's package.
+ no = name_expr->unknown_expression()->named_object();
+ if (no->package() != NULL
+ && no->package() != 
type->named_type()->named_object()->package())
+   no->package()->forget_usage(name_expr);
+   }
  break;
 
case EXPRESSION_CONST_REFERENCE:
Index: gcc/go/gofrontend/gogo.cc
===
--- gcc/go/gofrontend/gogo.cc   (revision 217402)
+++ gcc/go/gofrontend/gogo.cc   (working copy)
@@ -1412,7 +1412,7 @@ Gogo::lookup(const std::string& name, Na
   if (ret != NULL)
{
  if (ret->package() != NULL)
-   ret->package()->set_used();
+   ret->package()->note_usage();
  return ret;
}
 }
@@ -7426,6 +7426,36 @@ Package::set_priority(int priority)
 this->priority_ = priority;
 }
 
+// Forget a given usage.  If forgetting this usage means this package becomes
+// unused, report that error.
+
+void
+Package::forget_usage(Expression* usage) const
+{
+  if (this->fake_uses_.empty())
+return;
+
+  std::set::iterator p = this->fake_uses_.find(usage);
+  go_assert(p != this->fake_uses_.end());
+  this->fake_uses_.erase(p);
+
+  if (this->fake_uses_.empty())
+error_at(this->location(), "imported and not used: %s",
+Gogo::message_name(this->package_name()).c_str());
+}
+
+// Clear the used field for the next file.  If the only usages of this package
+// are possibly fake, keep the fake usages for lowering.
+
+void
+Package::clear_used()
+{
+  if (this->used_ > this->fake_uses_.size())
+this->fake_uses_.clear();
+
+  this->used_ = 0;
+}
+
 // Determine types of constants.  Everything else in a package
 // (variables, function declarations) should already have a fixed
 // type.  Constants may have abstract types.
Index: gcc/go/gofrontend/gogo.h
===
--- gcc/go/gofrontend/gogo.h(revision 217402)
+++ gcc/go/gofrontend/gogo.h(working copy)
@@ -2645,17 +2645,25 @@ class Package
   // Whether some symbol from the package was used.
   bool
   used() const
-  { return this->used_; }
+  { return this->used_ > 0; }
 
   // Note that some symbol from this package was used.
   void
-  set_used() const
-  { this->used_ = true; }
+  note_usage() const
+  { this->used_++; }
+
+  // Note that USAGE might be a fake usage of this package.
+  void
+  note_fake_usage(Expression* usage) const
+  { this->fake_uses_.insert(usage); }
+
+  // Forget a given USAGE of this package.
+  void
+  forget_usage(Expression* usage) const;
 
   // Clear the used field for the next file.
   void
-  clear_used()
-  { this->used_ = false; }
+  clear_used();
 
   // Whether this package was imported in the current file.
   bool
@@ -2749,10 +2757,12 @@ class Package
   int priority_;
   // The location of the import statement.
   Location location_;
-  // True if some name from this package was used.  This is mutable
-  // because we can use a package even if we have a const pointer to
-  // it.
-  mutable bool used_;
+  // The amount of times some name from this package was used.  This is mutable
+  // because we can use a package even if we have a const pointer to it.
+  mutable size_t used_;
+  // A set of possibly fake uses of this package.  This is mutable because we
+  // can track fake uses of a package even if we have a const pointer to it.
+  mutable std::set fake_uses_;
   // True if this package was imported in the current file.
   bool is_imported_;
   // True if this package was imported with a name of "_".
Index: gcc/go/gofrontend/parse.cc
===
--- gcc/go/gofrontend/parse.cc  (revision 217402)
+++ gcc/go/gofrontend/parse.cc  (working copy)
@@ -199,7 +199,7 @@ Parse::qu