compiler: Comparisons return untyped boolean value.
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Aug 2012 04:58:30 +0000 (04:58 +0000)
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 23 Aug 2012 04:58:30 +0000 (04:58 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190612 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/testsuite/go.test/test/named1.go

index 60856c4..b66a193 100644 (file)
@@ -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;
index 156cf3c..eea141f 100644 (file)
@@ -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.
index 499b77b..561d84a 100644 (file)
@@ -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"