The Go language was changed slightly so that comparisons return an untyped boolean value rather than the named type "bool". This patch implements that change in gccgo. One of the tests in the testsuite changed as well. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.7 branch.
Ian
Index: gcc/go/gofrontend/expressions.h =================================================================== --- gcc/go/gofrontend/expressions.h (revision 190404) +++ gcc/go/gofrontend/expressions.h (working copy) @@ -623,9 +623,9 @@ class Expression // Return a tree implementing the comparison LHS_TREE OP RHS_TREE. // TYPE is the type of both sides. static tree - comparison_tree(Translate_context*, Operator op, Type* left_type, - tree left_tree, Type* right_type, tree right_tree, - Location); + comparison_tree(Translate_context*, Type* result_type, Operator op, + Type* left_type, tree left_tree, Type* right_type, + tree right_tree, Location); // Return a tree for the multi-precision integer VAL in TYPE. static tree @@ -1149,7 +1149,7 @@ class Binary_expression : public Express Binary_expression(Operator op, Expression* left, Expression* right, Location location) : Expression(EXPRESSION_BINARY, location), - op_(op), left_(left), right_(right) + op_(op), left_(left), right_(right), type_(NULL) { } // Return the operator. @@ -1280,6 +1280,8 @@ class Binary_expression : public Express Expression* left_; // The right hand side operand. Expression* right_; + // The type of a comparison operation. + Type* type_; }; // A call expression. The go statement needs to dig inside this. Index: gcc/go/gofrontend/expressions.cc =================================================================== --- gcc/go/gofrontend/expressions.cc (revision 190608) +++ gcc/go/gofrontend/expressions.cc (working copy) @@ -5075,7 +5075,7 @@ Binary_expression::do_lower(Gogo* gogo, &right_nc, location, &result)) return this; - return Expression::make_cast(Type::lookup_bool_type(), + return Expression::make_cast(Type::make_boolean_type(), Expression::make_boolean(result, location), location); @@ -5106,10 +5106,7 @@ Binary_expression::do_lower(Gogo* gogo, { int cmp = left_string.compare(right_string); bool r = Binary_expression::cmp_to_bool(op, cmp); - return Expression::make_cast(Type::lookup_bool_type(), - Expression::make_boolean(r, - location), - location); + return Expression::make_boolean(r, location); } } } @@ -5327,15 +5324,15 @@ Binary_expression::do_type() switch (this->op_) { - case OPERATOR_OROR: - case OPERATOR_ANDAND: case OPERATOR_EQEQ: case OPERATOR_NOTEQ: case OPERATOR_LT: case OPERATOR_LE: case OPERATOR_GT: case OPERATOR_GE: - return Type::lookup_bool_type(); + if (this->type_ == NULL) + this->type_ = Type::make_boolean_type(); + return this->type_; case OPERATOR_PLUS: case OPERATOR_MINUS: @@ -5346,6 +5343,8 @@ Binary_expression::do_type() case OPERATOR_MOD: case OPERATOR_AND: case OPERATOR_BITCLEAR: + case OPERATOR_OROR: + case OPERATOR_ANDAND: { Type* type; if (!Binary_expression::operation_type(this->op_, @@ -5453,6 +5452,16 @@ Binary_expression::do_determine_type(con } this->right_->determine_type(&subcontext); + + if (is_comparison) + { + if (this->type_ != NULL && !this->type_->is_abstract()) + ; + else if (context->type != NULL && context->type->is_boolean_type()) + this->type_ = context->type; + else if (!context->may_be_abstract) + this->type_ = Type::lookup_bool_type(); + } } // Report an error if the binary operator OP does not support TYPE. @@ -5664,7 +5673,7 @@ Binary_expression::do_get_tree(Translate case OPERATOR_LE: case OPERATOR_GT: case OPERATOR_GE: - return Expression::comparison_tree(context, this->op_, + return Expression::comparison_tree(context, this->type_, this->op_, this->left_->type(), left, this->right_->type(), right, this->location()); @@ -6125,8 +6134,8 @@ Expression::make_binary(Operator op, Exp // Implement a comparison. tree -Expression::comparison_tree(Translate_context* context, Operator op, - Type* left_type, tree left_tree, +Expression::comparison_tree(Translate_context* context, Type* result_type, + Operator op, Type* left_type, tree left_tree, Type* right_type, tree right_tree, Location location) { @@ -6367,7 +6376,13 @@ Expression::comparison_tree(Translate_co if (left_tree == error_mark_node || right_tree == error_mark_node) return error_mark_node; - tree ret = fold_build2(code, boolean_type_node, left_tree, right_tree); + tree result_type_tree; + if (result_type == NULL) + result_type_tree = boolean_type_node; + else + result_type_tree = type_to_tree(result_type->get_backend(context->gogo())); + + tree ret = fold_build2(code, result_type_tree, left_tree, right_tree); if (CAN_HAVE_LOCATION_P(ret)) SET_EXPR_LOCATION(ret, location.gcc_location()); return ret; Index: gcc/testsuite/go.test/test/named1.go =================================================================== --- gcc/testsuite/go.test/test/named1.go (revision 190404) +++ gcc/testsuite/go.test/test/named1.go (working copy) @@ -37,8 +37,8 @@ func main() { asBool(true) asBool(*&b) asBool(Bool(true)) - asBool(1 != 2) // ERROR "cannot use.*type bool.*as type Bool" - asBool(i < j) // ERROR "cannot use.*type bool.*as type Bool" + asBool(1 != 2) // ok now + asBool(i < j) // ok now _, b = m[2] // ERROR "cannot .* bool.*type Bool"