diff options
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 39 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 10 | ||||
-rw-r--r-- | gcc/testsuite/go.test/test/named1.go | 4 |
3 files changed, 35 insertions, 18 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 60856c4..b66a193 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -5075,7 +5075,7 @@ Binary_expression::do_lower(Gogo* gogo, Named_object*, &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, Named_object*, { 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(const Type_context* context) } 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_context* context) 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, Expression* left, Expression* right, // 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_context* context, Operator op, 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; diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 156cf3c..eea141f 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -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 Expression 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 Expression 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. diff --git a/gcc/testsuite/go.test/test/named1.go b/gcc/testsuite/go.test/test/named1.go index 499b77b..561d84a 100644 --- a/gcc/testsuite/go.test/test/named1.go +++ b/gcc/testsuite/go.test/test/named1.go @@ -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" |