libgo patch committed: Allocate correct types in refect for interface conversions
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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