Remove old mechanism for passing varargs argument to varargs function.
authorIan Lance Taylor <ian@gcc.gnu.org>
Sat, 19 Feb 2011 04:25:43 +0000 (04:25 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Sat, 19 Feb 2011 04:25:43 +0000 (04:25 +0000)
From-SVN: r170304

gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h
gcc/testsuite/go.test/test/ddd.go
gcc/testsuite/go.test/test/fixedbugs/bug252.go

index c17cc9efc002dae974eca3c01ca893da7586c4d5..ebe4f282f8f1e8ecb0823dc6fb178a423e1728b6 100644 (file)
@@ -8306,11 +8306,6 @@ Call_expression::lower_varargs(Gogo* gogo, Named_object* function,
          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 @@ Call_expression::lower_varargs(Gogo* gogo, Named_object* function,
   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.
 
index fe4ade2c99d9a993378b77c51543d1b6042b4c35..c050a4a9c0c15b7f69f46e5e2b75f49202f6c9b5 100644 (file)
@@ -1264,9 +1264,6 @@ class Call_expression : public Expression
                size_t param_count);
 
  private:
-  bool
-  is_compatible_varargs_argument(Named_object*, Expression*, Type*, bool*);
-
   bool
   check_argument_type(int, const Type*, const Type*, source_location, bool);
 
index c9949c36e2079d058aa9cb00d9e63429de5f2868..b95d6e883f9786446480339be4df0119922ccdd2 100644 (file)
@@ -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 bd11b86ebf688aee9e81bd6d5624c6a64099d690..6df94241a0c8e4eba434a39d4512df1c4675d9db 100644 (file)
@@ -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"
 }