]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: Handle recursive pointer types for unary indirection.
authorChris Manghane <cmang@google.com>
Mon, 5 May 2014 23:54:16 +0000 (23:54 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 5 May 2014 23:54:16 +0000 (23:54 +0000)
* go-gcc.cc (Gcc_backend::indirect_expression): Add btype
parameter.
(Gcc_backend::temporary_variable): Check for erroneous function.

From-SVN: r210087

gcc/go/ChangeLog
gcc/go/go-gcc.cc
gcc/go/gofrontend/backend.h
gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/gogo.cc

index a468beed742ba8aa8f7a0f9f3027b86eca5b37c0..4e4afdb64baf3aa7ab0736f8094df7786918aaab 100644 (file)
@@ -1,3 +1,9 @@
+2014-05-05  Chris Manghane  <cmang@google.com>
+
+       * go-gcc.cc (Gcc_backend::indirect_expression): Add btype
+       parameter.
+       (Gcc_backend::temporary_variable): Check for erroneous function.
+
 2014-04-30  Chris Manghane  <cmang@google.com>
 
        * go-backend.c: #include "diagnostics.h".
index 0f3f44b32b8d1bda783df4c40e4e673ba7266b13..343661ec9d28874d304d7dd0abbd580e6df2357f 100644 (file)
@@ -229,7 +229,7 @@ class Gcc_backend : public Backend
   var_expression(Bvariable* var, Location);
 
   Bexpression*
-  indirect_expression(Bexpression* expr, bool known_valid, Location);
+  indirect_expression(Btype*, Bexpression* expr, bool known_valid, Location);
 
   Bexpression*
   named_constant_expression(Btype* btype, const std::string& name,
@@ -1147,14 +1147,26 @@ Gcc_backend::var_expression(Bvariable* var, Location)
 // An expression that indirectly references an expression.
 
 Bexpression*
-Gcc_backend::indirect_expression(Bexpression* expr, bool known_valid,
-                                 Location location)
+Gcc_backend::indirect_expression(Btype* btype, Bexpression* expr,
+                                bool known_valid, Location location)
 {
+  tree expr_tree = expr->get_tree();
+  tree type_tree = btype->get_tree();
+  if (expr_tree == error_mark_node || type_tree == error_mark_node)
+    return this->error_expression();
+
+  // If the type of EXPR is a recursive pointer type, then we
+  // need to insert a cast before indirecting.
+  tree target_type_tree = TREE_TYPE(TREE_TYPE(expr_tree));
+  if (VOID_TYPE_P(target_type_tree))
+    expr_tree = fold_convert_loc(location.gcc_location(),
+                                build_pointer_type(type_tree), expr_tree);
+
   tree ret = build_fold_indirect_ref_loc(location.gcc_location(),
-                                         expr->get_tree());
+                                         expr_tree);
   if (known_valid)
     TREE_THIS_NOTRAP(ret) = 1;
-  return tree_to_expr(ret);
+  return this->make_expression(ret);
 }
 
 // Return an expression that declares a constant named NAME with the
@@ -2406,17 +2418,18 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
                                Location location,
                                Bstatement** pstatement)
 {
+  gcc_assert(function != NULL);
+  tree decl = function->get_tree();
   tree type_tree = btype->get_tree();
   tree init_tree = binit == NULL ? NULL_TREE : binit->get_tree();
-  if (type_tree == error_mark_node || init_tree == error_mark_node)
+  if (type_tree == error_mark_node
+      || init_tree == error_mark_node
+      || decl == error_mark_node)
     {
       *pstatement = this->error_statement();
       return this->error_variable();
     }
 
-  gcc_assert(function != NULL);
-  tree decl = function->get_tree();
-
   tree var;
   // We can only use create_tmp_var if the type is not addressable.
   if (!TREE_ADDRESSABLE(type_tree))
index 786223fe736cb2b26033c721d0235711c13690f2..e49cedf54cc16b0bfbff1812ed777fcf5e7f5886 100644 (file)
@@ -253,9 +253,11 @@ class Backend
 
   // Create an expression that indirects through the pointer expression EXPR
   // (i.e., return the expression for *EXPR). KNOWN_VALID is true if the pointer
-  // is known to point to a valid memory location.
+  // is known to point to a valid memory location.  BTYPE is the expected type
+  // of the indirected EXPR.
   virtual Bexpression*
-  indirect_expression(Bexpression* expr, bool known_valid, Location) = 0;
+  indirect_expression(Btype* btype, Bexpression* expr, bool known_valid,
+                     Location) = 0;
 
   // Return an expression that declares a constant named NAME with the
   // constant value VAL in BTYPE.
index ec59354f7fe0fc27a0589e7a3cd09d7ce6e51273..b1d9bcc9839c97a1647cda1fc3db9897eb335b15 100644 (file)
@@ -760,16 +760,24 @@ Var_expression::do_get_tree(Translate_context* context)
                                                          context->function());
   bool is_in_heap;
   Location loc = this->location();
+  Btype* btype;
+  Gogo* gogo = context->gogo();
   if (this->variable_->is_variable())
-    is_in_heap = this->variable_->var_value()->is_in_heap();
+    {
+      is_in_heap = this->variable_->var_value()->is_in_heap();
+      btype = this->variable_->var_value()->type()->get_backend(gogo);
+    }
   else if (this->variable_->is_result_variable())
-    is_in_heap = this->variable_->result_var_value()->is_in_heap();
+    {
+      is_in_heap = this->variable_->result_var_value()->is_in_heap();
+      btype = this->variable_->result_var_value()->type()->get_backend(gogo);
+    }
   else
     go_unreachable();
 
   Bexpression* ret = context->backend()->var_expression(bvar, loc);
   if (is_in_heap)
-    ret = context->backend()->indirect_expression(ret, true, loc);
+    ret = context->backend()->indirect_expression(btype, ret, true, loc);
   return expr_to_tree(ret);
 }
 
@@ -4168,20 +4176,7 @@ Unary_expression::do_get_tree(Translate_context* context)
 
              }
          }
-
-       // If the type of EXPR is a recursive pointer type, then we
-       // need to insert a cast before indirecting.
-        tree expr = expr_to_tree(bexpr);
-        tree target_type_tree = TREE_TYPE(TREE_TYPE(expr));
-        if (VOID_TYPE_P(target_type_tree))
-          {
-            tree ind = type_to_tree(pbtype);
-            expr = fold_convert_loc(loc.gcc_location(),
-                                    build_pointer_type(ind), expr);
-            bexpr = tree_to_expr(expr);
-          }
-
-        ret = gogo->backend()->indirect_expression(bexpr, false, loc);
+        ret = gogo->backend()->indirect_expression(pbtype, bexpr, false, loc);
       }
       break;
 
@@ -10329,7 +10324,10 @@ Array_index_expression::do_get_tree(Translate_context* context)
               array_type->get_value_pointer(gogo, this->array_);
          Bexpression* ptr = tree_to_expr(valptr->get_tree(context));
           ptr = gogo->backend()->pointer_offset_expression(ptr, start, loc);
-         ret = gogo->backend()->indirect_expression(ptr, true, loc);
+
+         Type* ele_type = this->array_->type()->array_type()->element_type();
+         Btype* ele_btype = ele_type->get_backend(gogo);
+         ret = gogo->backend()->indirect_expression(ele_btype, ptr, true, loc);
        }
       return expr_to_tree(ret);
     }
@@ -10667,7 +10665,9 @@ String_index_expression::do_get_tree(Translate_context* context)
       Bexpression* bstart = tree_to_expr(start->get_tree(context));
       Bexpression* ptr = tree_to_expr(bytes->get_tree(context));
       ptr = gogo->backend()->pointer_offset_expression(ptr, bstart, loc);
-      Bexpression* index = gogo->backend()->indirect_expression(ptr, true, loc);
+      Btype* ubtype = Type::lookup_integer_type("uint8")->get_backend(gogo);
+      Bexpression* index = 
+       gogo->backend()->indirect_expression(ubtype, ptr, true, loc);
 
       Btype* byte_btype = bytes->type()->points_to()->get_backend(gogo);
       Bexpression* index_error = tree_to_expr(bad_index->get_tree(context));
@@ -13816,7 +13816,9 @@ Heap_expression::do_get_tree(Translate_context* context)
     gogo->backend()->temporary_variable(fndecl, context->bblock(), btype,
                                        space, true, loc, &decl);
   space = gogo->backend()->var_expression(space_temp, loc);
-  Bexpression* ref = gogo->backend()->indirect_expression(space, true, loc);
+  Btype* expr_btype = this->expr_->type()->get_backend(gogo);
+  Bexpression* ref =
+    gogo->backend()->indirect_expression(expr_btype, space, true, loc);
 
   Bexpression* bexpr = tree_to_expr(this->expr_->get_tree(context));
   Bstatement* assn = gogo->backend()->assignment_statement(ref, bexpr, loc);
index ab54f8491e3c56a17b422b97eef25eaae55cfe0a..e0ddc2f35ffabe30e5b08c778a5c02a4dcbd47e6 100644 (file)
@@ -5210,7 +5210,10 @@ Function::return_value(Gogo* gogo, Named_object* named_function,
       Bvariable* bvar = no->get_backend_variable(gogo, named_function);
       Bexpression* val = gogo->backend()->var_expression(bvar, location);
       if (no->result_var_value()->is_in_heap())
-        val = gogo->backend()->indirect_expression(val, true, location);
+       {
+         Btype* bt = no->result_var_value()->type()->get_backend(gogo);
+         val = gogo->backend()->indirect_expression(bt, val, true, location);
+       }
       vals[i] = val;
     }
   return gogo->backend()->return_statement(this->fndecl_, vals, location);