Patchwork Go patch committed: Check for errors from call_builtin

login
register
mail settings
Submitter Ian Taylor
Date Dec. 16, 2010, 12:44 a.m.
Message ID <mcripyuzguz.fsf@google.com>
Download mbox | patch
Permalink /patch/75710/
State New
Headers show

Comments

Ian Taylor - Dec. 16, 2010, 12:44 a.m.
This patch changes the Go frontend to check for errors from
Gogo::call_builtin when it matters, rather than assuming that the call
was OK.  Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

Patch

diff -r 7cbfd72b9af4 go/expressions.cc
--- a/go/expressions.cc	Wed Dec 15 16:14:11 2010 -0800
+++ b/go/expressions.cc	Wed Dec 15 16:35:50 2010 -0800
@@ -505,6 +505,8 @@ 
 				     lhs_type_descriptor,
 				     TREE_TYPE(rhs_type_descriptor),
 				     rhs_type_descriptor);
+      if (call == error_mark_node)
+	return error_mark_node;
       // This will panic if the interface conversion fails.
       TREE_NOTHROW(assert_interface_decl) = 0;
       elt->value = fold_convert_loc(location, TREE_TYPE(field), call);
@@ -535,6 +537,8 @@ 
 				     lhs_type_descriptor,
 				     TREE_TYPE(rhs_type_descriptor),
 				     rhs_type_descriptor);
+      if (call == error_mark_node)
+	return error_mark_node;
       // This will panic if the interface conversion fails.
       TREE_NOTHROW(convert_interface_decl) = 0;
       elt->value = fold_convert_loc(location, TREE_TYPE(field), call);
@@ -599,6 +603,8 @@ 
 				 rhs_type_descriptor,
 				 TREE_TYPE(rhs_inter_descriptor),
 				 rhs_inter_descriptor);
+  if (call == error_mark_node)
+    return error_mark_node;
   // This call will panic if the conversion is invalid.
   TREE_NOTHROW(check_interface_type_decl) = 0;
 
@@ -6012,6 +6018,8 @@ 
 					 descriptor,
 					 ptr_type_node,
 					 arg);
+	  if (left_tree == error_mark_node)
+	    return error_mark_node;
 	  // This can panic if the type is not comparable.
 	  TREE_NOTHROW(empty_interface_value_compare_decl) = 0;
 	}
@@ -6029,6 +6037,8 @@ 
 					 descriptor,
 					 ptr_type_node,
 					 arg);
+	  if (left_tree == error_mark_node)
+	    return error_mark_node;
 	  // This can panic if the type is not comparable.
 	  TREE_NOTHROW(interface_value_compare_decl) = 0;
 	}
@@ -6054,6 +6064,8 @@ 
 					 left_tree,
 					 TREE_TYPE(right_tree),
 					 right_tree);
+	  if (left_tree == error_mark_node)
+	    return error_mark_node;
 	  // This can panic if the type is uncomparable.
 	  TREE_NOTHROW(empty_interface_compare_decl) = 0;
 	}
@@ -6070,6 +6082,8 @@ 
 					 left_tree,
 					 TREE_TYPE(right_tree),
 					 right_tree);
+	  if (left_tree == error_mark_node)
+	    return error_mark_node;
 	  // This can panic if the type is uncomparable.
 	  TREE_NOTHROW(interface_compare_decl) = 0;
 	}
@@ -7415,6 +7429,8 @@ 
 						   "__go_print_space",
 						   0,
 						   void_type_node);
+		    if (call == error_mark_node)
+		      return error_mark_node;
 		    append_to_statement_list(call, &stmt_list);
 		  }
 
@@ -7513,8 +7529,9 @@ 
 					       void_type_node,
 					       TREE_TYPE(arg),
 					       arg);
-		if (call != error_mark_node)
-		  append_to_statement_list(call, &stmt_list);
+		if (call == error_mark_node)
+		  return error_mark_node;
+		append_to_statement_list(call, &stmt_list);
 	      }
 	  }
 
@@ -7526,6 +7543,8 @@ 
 					   "__go_print_nl",
 					   0,
 					   void_type_node);
+	    if (call == error_mark_node)
+	      return error_mark_node;
 	    append_to_statement_list(call, &stmt_list);
 	  }
 
@@ -7552,6 +7571,8 @@ 
 				       void_type_node,
 				       TREE_TYPE(arg_tree),
 				       arg_tree);
+	if (call == error_mark_node)
+	  return error_mark_node;
 	// This function will throw an exception.
 	TREE_NOTHROW(panic_fndecl) = 0;
 	// This function will not return.
@@ -7604,6 +7625,8 @@ 
 				      0,
 				      empty_tree);
 	  }
+	if (call == error_mark_node)
+	  return error_mark_node;
 	return fold_build3_loc(location, COND_EXPR, empty_tree, arg_tree,
 			       call, empty_nil_tree);
       }
@@ -9404,6 +9427,8 @@ 
 				    start_tree,
 				    length_type,
 				    end_tree);
+      if (ret == error_mark_node)
+	return error_mark_node;
       // This will panic if the bounds are out of range for the
       // string.
       TREE_NOTHROW(strslice_fndecl) = 0;
@@ -9573,6 +9598,8 @@ 
 				 (insert
 				  ? boolean_true_node
 				  : boolean_false_node));
+  if (call == error_mark_node)
+    return error_mark_node;
   // This can panic on a map of interface type if the interface holds
   // an uncomparable or unhashable type.
   TREE_NOTHROW(map_index_fndecl) = 0;
@@ -11129,6 +11156,8 @@ 
 				 TYPE_SIZE_UNIT(TREE_TYPE(val_field)),
 				 const_ptr_type_node,
 				 fold_convert(const_ptr_type_node, valaddr));
+  if (call == error_mark_node)
+    return error_mark_node;
 
   tree ret;
   if (make_tmp == NULL)
diff -r 7cbfd72b9af4 go/gogo-tree.cc
--- a/go/gogo-tree.cc	Wed Dec 15 16:14:11 2010 -0800
+++ b/go/gogo-tree.cc	Wed Dec 15 16:35:50 2010 -0800
@@ -341,7 +341,8 @@ 
 				 void_type_node,
 				 build_pointer_type(root_list_type),
 				 build_fold_addr_expr(decl));
-  append_to_statement_list(call, init_stmt_list);
+  if (call != error_mark_node)
+    append_to_statement_list(call, init_stmt_list);
 }
 
 // Build the decl for the initialization function.
@@ -1684,7 +1685,8 @@ 
 				 void_type_node,
 				 ptr_type_node,
 				 this->defer_stack(end_loc));
-  append_to_statement_list(call, &stmt_list);
+  if (call != error_mark_node)
+    append_to_statement_list(call, &stmt_list);
 
   tree retval = this->return_value(gogo, named_function, end_loc, &stmt_list);
   tree set;
@@ -1723,7 +1725,8 @@ 
 				    void_type_node,
 				    ptr_type_node,
 				    this->defer_stack(end_loc));
-  TREE_NOTHROW(undefer_fndecl) = 0;
+  if (undefer_fndecl != NULL_TREE)
+    TREE_NOTHROW(undefer_fndecl) = 0;
 
   tree defer = Gogo::call_builtin(&check_fndecl,
 				  end_loc,
@@ -2867,6 +2870,8 @@ 
 				void_type_node,
 				integer_type_node,
 				build_int_cst(integer_type_node, code));
+  if (ret == error_mark_node)
+    return error_mark_node;
   // The runtime error function panics and does not return.
   TREE_NOTHROW(runtime_error_fndecl) = 0;
   TREE_THIS_VOLATILE(runtime_error_fndecl) = 1;
@@ -2904,6 +2909,8 @@ 
 					(for_select
 					 ? boolean_true_node
 					 : boolean_false_node));
+	  if (ret == error_mark_node)
+	    return error_mark_node;
 	  // This can panic if there are too many operations on a
 	  // closed channel.
 	  TREE_NOTHROW(send_small_fndecl) = 0;
@@ -2922,6 +2929,8 @@ 
 					channel,
 					uint64_type_node,
 					val);
+	  if (ret == error_mark_node)
+	    return error_mark_node;
 	  // This can panic if there are too many operations on a
 	  // closed channel.
 	  TREE_NOTHROW(send_nonblocking_small_fndecl) = 0;
@@ -2967,6 +2976,8 @@ 
 				    (for_select
 				     ? boolean_true_node
 				     : boolean_false_node));
+	  if (call == error_mark_node)
+	    return error_mark_node;
 	  // This can panic if there are too many operations on a
 	  // closed channel.
 	  TREE_NOTHROW(send_big_fndecl) = 0;
@@ -2984,6 +2995,8 @@ 
 				    channel,
 				    ptr_type_node,
 				    val);
+	  if (call == error_mark_node)
+	    return error_mark_node;
 	  // This can panic if there are too many operations on a
 	  // closed channel.
 	  TREE_NOTHROW(send_nonblocking_big_fndecl) = 0;
@@ -3025,6 +3038,8 @@ 
 				     (for_select
 				      ? boolean_true_node
 				      : boolean_false_node));
+      if (call == error_mark_node)
+	return error_mark_node;
       // This can panic if there are too many operations on a closed
       // channel.
       TREE_NOTHROW(receive_small_fndecl) = 0;
@@ -3057,6 +3072,8 @@ 
 				     (for_select
 				      ? boolean_true_node
 				      : boolean_false_node));
+      if (call == error_mark_node)
+	return error_mark_node;
       // This can panic if there are too many operations on a closed
       // channel.
       TREE_NOTHROW(receive_big_fndecl) = 0;
@@ -3114,6 +3131,8 @@ 
 			      ptr_type_node,
 			      fold_convert_loc(location, ptr_type_node,
 					       closure));
+  if (x == error_mark_node)
+    return error_mark_node;
 
   x = save_expr(x);
 
diff -r 7cbfd72b9af4 go/statements.cc
--- a/go/statements.cc	Wed Dec 15 16:14:11 2010 -0800
+++ b/go/statements.cc	Wed Dec 15 16:35:50 2010 -0800
@@ -4216,6 +4216,8 @@ 
 				 chans_arg,
 				 pointer_boolean_type_tree,
 				 is_sends_arg);
+  if (call == error_mark_node)
+    return error_mark_node;
 
   tree stmt_list = NULL_TREE;
 
diff -r 7cbfd72b9af4 go/types.cc
--- a/go/types.cc	Wed Dec 15 16:14:11 2010 -0800
+++ b/go/types.cc	Wed Dec 15 16:35:50 2010 -0800
@@ -5094,6 +5094,8 @@ 
 				context->gogo()->map_descriptor(this),
 				sizetype,
 				expr_tree);
+  if (ret == error_mark_node)
+    return error_mark_node;
   // This can panic if the capacity is out of range.
   TREE_NOTHROW(new_map_fndecl) = 0;
 
@@ -5344,6 +5346,8 @@ 
 				element_size_tree,
 				sizetype,
 				expr_tree);
+  if (ret == error_mark_node)
+    return error_mark_node;
   // This can panic if the capacity is out of range.
   TREE_NOTHROW(new_channel_fndecl) = 0;