]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: Be more careful to follow GENERIC type rules.
authorIan Lance Taylor <iant@google.com>
Fri, 9 Mar 2012 08:25:05 +0000 (08:25 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 9 Mar 2012 08:25:05 +0000 (08:25 +0000)
* go-gcc.cc (Gcc_backend::assignment_statement): Convert the rhs
to the lhs type if necessary.

From-SVN: r185128

gcc/go/ChangeLog
gcc/go/go-gcc.cc
gcc/go/gofrontend/expressions.cc

index 2c0b3c233369a0982a37deb095ba7c1417569169..f779e9b89cf3934f1bd9622f9f67603837824aa3 100644 (file)
@@ -1,3 +1,8 @@
+2012-03-09  Ian Lance Taylor  <iant@google.com>
+
+       * go-gcc.cc (Gcc_backend::assignment_statement): Convert the rhs
+       to the lhs type if necessary.
+
 2012-03-08  Ian Lance Taylor  <iant@google.com>
 
        * go-gcc.cc (Gcc_backend::init_statement): Don't initialize a
index 0cc167d4ba7bbfdb5dd6bca04aa85273aa68de60..96c171835c420e4efc55412fec087f9ab9dfddc7 100644 (file)
@@ -918,6 +918,30 @@ Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
     return this->compound_statement(this->expression_statement(lhs),
                                    this->expression_statement(rhs));
 
+  // Sometimes the same unnamed Go type can be created multiple times
+  // and thus have multiple tree representations.  Make sure this does
+  // not confuse the middle-end.
+  if (TREE_TYPE(lhs_tree) != TREE_TYPE(rhs_tree))
+    {
+      tree lhs_type_tree = TREE_TYPE(lhs_tree);
+      gcc_assert(TREE_CODE(lhs_type_tree) == TREE_CODE(TREE_TYPE(rhs_tree)));
+      if (POINTER_TYPE_P(lhs_type_tree)
+         || INTEGRAL_TYPE_P(lhs_type_tree)
+         || SCALAR_FLOAT_TYPE_P(lhs_type_tree)
+         || COMPLEX_FLOAT_TYPE_P(lhs_type_tree))
+       rhs_tree = fold_convert_loc(location.gcc_location(), lhs_type_tree,
+                                   rhs_tree);
+      else if (TREE_CODE(lhs_type_tree) == RECORD_TYPE
+              || TREE_CODE(lhs_type_tree) == ARRAY_TYPE)
+       {
+         gcc_assert(int_size_in_bytes(lhs_type_tree)
+                    == int_size_in_bytes(TREE_TYPE(rhs_tree)));
+         rhs_tree = fold_build1_loc(location.gcc_location(),
+                                    VIEW_CONVERT_EXPR,
+                                    lhs_type_tree, rhs_tree);
+       }
+    }
+
   return this->make_statement(fold_build2_loc(location.gcc_location(),
                                               MODIFY_EXPR,
                                              void_type_node,
index 134b5ae2aae7134a494cc42a85bc9d06d5ab5065..90cf6f32dab1eca9466526f90b5a4f0ed9f8ae0b 100644 (file)
@@ -205,9 +205,6 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
                                   Type* rhs_type, tree rhs_tree,
                                   Location location)
 {
-  if (lhs_type == rhs_type)
-    return rhs_tree;
-
   if (lhs_type->is_error() || rhs_type->is_error())
     return error_mark_node;
 
@@ -220,7 +217,7 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
   if (lhs_type_tree == error_mark_node)
     return error_mark_node;
 
-  if (lhs_type->interface_type() != NULL)
+  if (lhs_type != rhs_type && lhs_type->interface_type() != NULL)
     {
       if (rhs_type->interface_type() == NULL)
        return Expression::convert_type_to_interface(context, lhs_type,
@@ -231,7 +228,7 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
                                                          rhs_type, rhs_tree,
                                                          false, location);
     }
-  else if (rhs_type->interface_type() != NULL)
+  else if (lhs_type != rhs_type && rhs_type->interface_type() != NULL)
     return Expression::convert_interface_to_type(context, lhs_type, rhs_type,
                                                 rhs_tree, location);
   else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
@@ -289,10 +286,16 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
           || (TREE_CODE(lhs_type_tree) == ARRAY_TYPE
               && TREE_CODE(TREE_TYPE(rhs_tree)) == ARRAY_TYPE))
     {
+      // Avoid confusion from zero sized variables which may be
+      // represented as non-zero-sized.
+      if (int_size_in_bytes(lhs_type_tree) == 0
+         || int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
+       return rhs_tree;
+
       // This conversion must be permitted by Go, or we wouldn't have
       // gotten here.
       go_assert(int_size_in_bytes(lhs_type_tree)
-                == int_size_in_bytes(TREE_TYPE(rhs_tree)));
+               == int_size_in_bytes(TREE_TYPE(rhs_tree)));
       return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
                              lhs_type_tree, rhs_tree);
     }