diff mbox

Go patch committed: Remove old varargs passing approach

Message ID mcrr5b47ir9.fsf@google.com
State New
Headers show

Commit Message

Ian Lance Taylor Feb. 19, 2011, 4:25 a.m. UTC
Go used to support passing a varargs argument directly to a function
which took varargs, without additional wrapping, just by naming the
argument.  That has now been replaced by requiring an explicit ellipsis
after the varargs function name.  This patch removes the old mechanism
from the Go frontend.  I also updated a couple of test cases which still
worked the old way; the update was just to replace them with the current
version of the tests in the master source.  Bootstrapped and ran Go
testsuite on x86_64-unknown-linux-gnu.  Committed to mainline.

Ian
diff mbox

Patch

diff -r 58016ddf4369 go/expressions.cc
--- a/go/expressions.cc	Fri Feb 18 20:00:17 2011 -0800
+++ b/go/expressions.cc	Fri Feb 18 20:06:22 2011 -0800
@@ -8306,11 +8306,6 @@ 
 	  this->report_error(_("too many arguments"));
 	  return this;
 	}
-      else if (pa + 1 == old_args->end()
-	       && this->is_compatible_varargs_argument(function, *pa,
-						       varargs_type,
-						       &issued_error))
-	new_args->push_back(*pa);
       else
 	{
 	  Type* element_type = varargs_type->array_type()->element_type();
@@ -8348,84 +8343,6 @@ 
   return ret;
 }
 
-// Return true if ARG is a varargs argment which should be passed to
-// the varargs parameter of type PARAM_TYPE without wrapping.  ARG
-// will be the last argument passed in the call, and PARAM_TYPE will
-// be the type of the last parameter of the varargs function being
-// called.
-
-bool
-Call_expression::is_compatible_varargs_argument(Named_object* function,
-						Expression* arg,
-						Type* param_type,
-						bool* issued_error)
-{
-  *issued_error = false;
-
-  Type* var_type = NULL;
-
-  // The simple case is passing the varargs parameter of the caller.
-  Var_expression* ve = arg->var_expression();
-  if (ve != NULL && ve->named_object()->is_variable())
-    {
-      Variable* var = ve->named_object()->var_value();
-      if (var->is_varargs_parameter())
-	var_type = var->type();
-    }
-
-  // The complex case is passing the varargs parameter of some
-  // enclosing function.  This will look like passing down *c.f where
-  // c is the closure variable and f is a field in the closure.
-  if (function != NULL
-      && function->func_value()->needs_closure()
-      && arg->classification() == EXPRESSION_UNARY)
-    {
-      Unary_expression* ue = static_cast<Unary_expression*>(arg);
-      if (ue->op() == OPERATOR_MULT)
-	{
-	  Field_reference_expression* fre =
-	    ue->operand()->deref()->field_reference_expression();
-	  if (fre != NULL)
-	    {
-	      Var_expression* ve = fre->expr()->deref()->var_expression();
-	      if (ve != NULL)
-		{
-		  Named_object* no = ve->named_object();
-		  Function* f = function->func_value();
-		  if (no == f->closure_var())
-		    {
-		      // At this point we know that this indeed a
-		      // reference to some enclosing variable.  Now we
-		      // need to figure out whether that variable is a
-		      // varargs parameter.
-		      Named_object* enclosing =
-			f->enclosing_var(fre->field_index());
-		      Variable* var = enclosing->var_value();
-		      if (var->is_varargs_parameter())
-			var_type = var->type();
-		    }
-		}
-	    }
-	}
-    }
-
-  if (var_type == NULL)
-    return false;
-
-  // We only match if the parameter is the same, with an identical
-  // type.
-  Array_type* var_at = var_type->array_type();
-  gcc_assert(var_at != NULL);
-  Array_type* param_at = param_type->array_type();
-  if (param_at != NULL
-      && Type::are_identical(var_at->element_type(),
-			     param_at->element_type(), true, NULL))
-    return true;
-  error_at(arg->location(), "... mismatch: passing ...T as ...");
-  *issued_error = true;
-  return false;
-}
-
 // Get the function type.  Returns NULL if we don't know the type.  If
 // this returns NULL, and if_ERROR is true, issues an error.
 
diff -r 58016ddf4369 go/expressions.h
--- a/go/expressions.h	Fri Feb 18 20:00:17 2011 -0800
+++ b/go/expressions.h	Fri Feb 18 20:06:22 2011 -0800
@@ -1265,9 +1265,6 @@ 
 
  private:
   bool
-  is_compatible_varargs_argument(Named_object*, Expression*, Type*, bool*);
-
-  bool
   check_argument_type(int, const Type*, const Type*, source_location, bool);
 
   tree
Index: gcc/testsuite/go.test/test/ddd.go
===================================================================
--- gcc/testsuite/go.test/test/ddd.go	(revision 169848)
+++ gcc/testsuite/go.test/test/ddd.go	(working copy)
@@ -14,13 +14,13 @@  func sum(args ...int) int {
 	return s
 }
 
-func sumC(args ...int) int { return func() int { return sum(args) }() }
+func sumC(args ...int) int { return func() int { return sum(args...) }() }
 
-var sumD = func(args ...int) int { return sum(args) }
+var sumD = func(args ...int) int { return sum(args...) }
 
-var sumE = func() func(...int) int { return func(args ...int) int { return sum(args) } }()
+var sumE = func() func(...int) int { return func(args ...int) int { return sum(args...) } }()
 
-var sumF = func(args ...int) func() int { return func() int { return sum(args) } }
+var sumF = func(args ...int) func() int { return func() int { return sum(args...) } }
 
 func sumA(args []int) int {
 	s := 0
@@ -30,10 +30,14 @@  func sumA(args []int) int {
 	return s
 }
 
-func sum2(args ...int) int { return 2 * sum(args) }
+func sumB(args []int) int { return sum(args...) }
+
+func sum2(args ...int) int { return 2 * sum(args...) }
 
 func sum3(args ...int) int { return 3 * sumA(args) }
 
+func sum4(args ...int) int { return 4 * sumB(args) }
+
 func intersum(args ...interface{}) int {
 	s := 0
 	for _, v := range args {
@@ -46,9 +50,9 @@  type T []T
 
 func ln(args ...T) int { return len(args) }
 
-func ln2(args ...T) int { return 2 * ln(args) }
+func ln2(args ...T) int { return 2 * ln(args...) }
 
-func (*T) Sum(args ...int) int { return sum(args) }
+func (*T) Sum(args ...int) int { return sum(args...) }
 
 type U struct {
 	*T
@@ -119,6 +123,22 @@  func main() {
 		println("sum 9", x)
 		panic("fail")
 	}
+	if x := sum4(1, 2, 3); x != 4*6 {
+		println("sum 6", x)
+		panic("fail")
+	}
+	if x := sum4(); x != 4*0 {
+		println("sum 0", x)
+		panic("fail")
+	}
+	if x := sum4(10); x != 4*10 {
+		println("sum 10", x)
+		panic("fail")
+	}
+	if x := sum4(1, 8); x != 4*9 {
+		println("sum 9", x)
+		panic("fail")
+	}
 	if x := intersum(1, 2, 3); x != 6 {
 		println("intersum 6", x)
 		panic("fail")
Index: gcc/testsuite/go.test/test/fixedbugs/bug252.go
===================================================================
--- gcc/testsuite/go.test/test/fixedbugs/bug252.go	(revision 169848)
+++ gcc/testsuite/go.test/test/fixedbugs/bug252.go	(working copy)
@@ -7,9 +7,9 @@ 
 package main
 
 func f(args ...int) {
-	g(args)	// ERROR "[.][.][.] mismatch"
+	g(args)
 }
 
 func g(args ...interface{}) {
-	f(args)	// ERROR "[.][.][.] mismatch"
+	f(args)	// ERROR "[.][.][.]|incompatible"
 }