This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Go patch committed: Fix indirection through circular type
- From: Ian Lance Taylor <iant at google dot com>
- To: gcc-patches at gcc dot gnu dot org, gofrontend-dev at googlegroups dot com
- Date: Wed, 29 Feb 2012 21:59:37 -0800
- Subject: Go patch committed: Fix indirection through circular type
- Authentication-results: mr.google.com; spf=pass (google.com: domain of iant@google.com designates 10.68.125.168 as permitted sender) smtp.mail=iant@google.com; dkim=pass header.i=iant@google.com
This patch to the Go frontend fixes the handling of pointer indirection
through a circular type. The gcc middle-end can not represent a
circular type, as such a construct can not exist in C (in Go you get one
by writing "type T *T"). We handle this by using void* and introducing
a type cast on the indirection. With the use of the Gcc_backend
interface, we now use a general void* rather than specifically
ptr_type_node which is what we used before. This patch updates the
handling of pointer indirection to check for this case. Bootstrapped
and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to
mainline.
Ian
diff -r 520f034862ee go/expressions.cc
--- a/go/expressions.cc Wed Feb 29 21:08:49 2012 -0800
+++ b/go/expressions.cc Wed Feb 29 21:56:03 2012 -0800
@@ -4705,29 +4705,33 @@
// need to check for nil. We don't bother to check for small
// structs because we expect the system to crash on a nil
// pointer dereference.
- HOST_WIDE_INT s = int_size_in_bytes(TREE_TYPE(TREE_TYPE(expr)));
- if (s == -1 || s >= 4096)
+ tree target_type_tree = TREE_TYPE(TREE_TYPE(expr));
+ if (!VOID_TYPE_P(target_type_tree))
{
- if (!DECL_P(expr))
- expr = save_expr(expr);
- tree compare = fold_build2_loc(loc.gcc_location(), EQ_EXPR,
- boolean_type_node,
- expr,
- fold_convert(TREE_TYPE(expr),
- null_pointer_node));
- tree crash = Gogo::runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
- loc);
- expr = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR,
- TREE_TYPE(expr), build3(COND_EXPR,
- void_type_node,
- compare, crash,
- NULL_TREE),
- expr);
+ HOST_WIDE_INT s = int_size_in_bytes(target_type_tree);
+ if (s == -1 || s >= 4096)
+ {
+ if (!DECL_P(expr))
+ expr = save_expr(expr);
+ tree compare = fold_build2_loc(loc.gcc_location(), EQ_EXPR,
+ boolean_type_node,
+ expr,
+ fold_convert(TREE_TYPE(expr),
+ null_pointer_node));
+ tree crash = Gogo::runtime_error(RUNTIME_ERROR_NIL_DEREFERENCE,
+ loc);
+ expr = fold_build2_loc(loc.gcc_location(), COMPOUND_EXPR,
+ TREE_TYPE(expr), build3(COND_EXPR,
+ void_type_node,
+ compare, crash,
+ NULL_TREE),
+ expr);
+ }
}
// If the type of EXPR is a recursive pointer type, then we
// need to insert a cast before indirecting.
- if (TREE_TYPE(TREE_TYPE(expr)) == ptr_type_node)
+ if (VOID_TYPE_P(target_type_tree))
{
Type* pt = this->expr_->type()->points_to();
tree ind = type_to_tree(pt->get_backend(context->gogo()));