public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [gccgo] Fix for type assertions
@ 2010-09-09  1:58 Ian Lance Taylor
  0 siblings, 0 replies; only message in thread
From: Ian Lance Taylor @ 2010-09-09  1:58 UTC (permalink / raw)
  To: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 350 bytes --]

This gccgo patch does three things.  It fixes type assertions for global
variables, by not creating an unnecessary temporary variable.  It fixes
the unsafe.Pointer checks for type assertions, by only permitting a
conversion to uintptr.  It gives an error for impossible type assertions
that can never be satisfied.  Committed to gccgo  branch.

Ian


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: assertions --]
[-- Type: text/x-diff, Size: 3261 bytes --]

diff -r 1c23caeb2ccd go/expressions.cc
--- a/go/expressions.cc	Wed Sep 08 16:24:55 2010 -0700
+++ b/go/expressions.cc	Wed Sep 08 17:35:24 2010 -0700
@@ -704,25 +704,16 @@
   tree val = build3(COMPONENT_REF, TREE_TYPE(rhs_field), rhs_tree, rhs_field,
 		    NULL_TREE);
 
-  // If the value is a pointer, then we can just get it from the
-  // interface.  Otherwise we have to make a copy.
-  if (lhs_type->points_to() != NULL)
-    return build2(COMPOUND_EXPR, lhs_type_tree, call,
-		  fold_convert_loc(location, lhs_type_tree, val));
-
-  tree tmp = create_tmp_var(lhs_type_tree, NULL);
-  DECL_IGNORED_P(tmp) = 0;
-
-  tree make_tmp = fold_build1_loc(location, DECL_EXPR, void_type_node, tmp);
-  tree s = build2(COMPOUND_EXPR, void_type_node, call, make_tmp);
-
-  val = fold_convert_loc(location, build_pointer_type(lhs_type_tree), val);
-  val = build_fold_indirect_ref_loc(location, val);
-  tree set = fold_build2_loc(location, MODIFY_EXPR, void_type_node,
-			     tmp, val);
-  s = build2(COMPOUND_EXPR, void_type_node, s, set);
-
-  return build2(COMPOUND_EXPR, lhs_type_tree, s, tmp);
+  // If the value is a pointer, then it is the value we want.
+  // Otherwise it points to the value.
+  if (lhs_type->points_to() == NULL)
+    {
+      val = fold_convert_loc(location, build_pointer_type(lhs_type_tree), val);
+      val = build_fold_indirect_ref_loc(location, val);
+    }
+
+  return build2(COMPOUND_EXPR, lhs_type_tree, call,
+		fold_convert_loc(location, lhs_type_tree, val));
 }
 
 // Convert an expression to a tree.  This is implemented by the child
@@ -11459,18 +11450,40 @@
   if (expr_type->is_unsafe_pointer_type())
     {
       if (this->type_->points_to() == NULL
-	  && this->type_->integer_type() == NULL)
-	this->report_error(_("invalid unsafe.pointer conversion"));
+	  && (this->type_->integer_type() == NULL
+	      || (this->type_->forwarded()
+		  != Type::lookup_integer_type("uintptr"))))
+	this->report_error(_("invalid unsafe.Pointer conversion"));
     }
   else if (this->type_->is_unsafe_pointer_type())
     {
-      if (expr_type->interface_type() == NULL
-	  && expr_type->points_to() == NULL
-	  && expr_type->integer_type() == NULL)
-	this->report_error(_("invalid unsafe.pointer conversion"));
+      if (expr_type->points_to() == NULL
+	  && (expr_type->integer_type() == NULL
+	      || (expr_type->forwarded()
+		  != Type::lookup_integer_type("uintptr"))))
+	this->report_error(_("invalid unsafe.Pointer conversion"));
     }
   else if (expr_type->interface_type() == NULL)
-    this->report_error(_("type guard only valid for interface types"));
+    this->report_error(_("type assertion only valid for interface types"));
+  else if (this->type_->interface_type() == NULL)
+    {
+      std::string reason;
+      if (!expr_type->interface_type()->implements_interface(this->type_,
+							     &reason))
+	{
+	  if (reason.empty())
+	    this->report_error(_("impossible type assertion: "
+				 "type does not implement interface"));
+	  else
+	    {
+	      error_at(this->location(),
+		       ("impossible type assertion: "
+			"type does not implement interface (%s)"),
+		       reason.c_str());
+	      this->set_is_error();
+	    }
+	}
+    }
 }
 
 // Return a tree for a type guard expression.

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2010-09-09  0:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-09  1:58 [gccgo] Fix for type assertions Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).