diff mbox

[gccgo] Avoid duplicate errors with ellipsis types

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

Commit Message

Ian Lance Taylor Aug. 31, 2010, 9:47 p.m. UTC
This gccgo patch avoids issuing duplicate errors for ellipsis types.  If
we've already reported one error, we don't need to report another.
Committed to gccgo branch.

Ian
diff mbox

Patch

diff -r 165da9b304ae go/expressions.cc
--- a/go/expressions.cc	Tue Aug 31 14:13:03 2010 -0700
+++ b/go/expressions.cc	Tue Aug 31 14:45:13 2010 -0700
@@ -7736,9 +7736,11 @@ 
 
       // We have reached the varargs parameter.
 
+      bool issued_error = false;
       if (pa != old_args->end()
 	  && pa + 1 == old_args->end()
-	  && this->is_compatible_varargs_argument(function, *pa, varargs_type))
+	  && this->is_compatible_varargs_argument(function, *pa, varargs_type,
+						  &issued_error))
 	new_args->push_back(*pa);
       else if (pa == old_args->end())
 	push_empty_arg = true;
@@ -7766,15 +7768,16 @@ 
 	      if (element_type != NULL)
 		{
 		  if (!this->check_argument_type(i, element_type, patype,
-						 paloc))
+						 paloc, issued_error))
 		    continue;
 		}
 	      else
 		{
 		  if (patype->is_nil_type())
 		    {
-		      error_at((*pa)->location(),
-			       "invalid use of %<nil%> for %<...%> argument");
+		      if (!issued_error)
+			error_at((*pa)->location(),
+				 "invalid use of %<nil%> for %<...%> argument");
 		      continue;
 		    }
 		  if (patype->is_abstract())
@@ -7835,8 +7838,11 @@ 
 bool
 Call_expression::is_compatible_varargs_argument(Named_object* function,
 						Expression* arg,
-						Type* param_type)
-{
+						Type* param_type,
+						bool* issued_error)
+{
+  *issued_error = false;
+
   Type* var_type = NULL;
 
   // The simple case is passing the varargs parameter of the caller.
@@ -7894,6 +7900,7 @@ 
       if (param_type->interface_type() != NULL)
 	return true;
       error_at(arg->location(), "... mismatch: passing ... as ...T");
+      *issued_error = true;
       return false;
     }
   else
@@ -7908,6 +7915,7 @@ 
 				 param_at->element_type(), NULL))
 	return true;
       error_at(arg->location(), "... mismatch: passing ...T as ...");
+      *issued_error = true;
       return false;
     }
 }
@@ -8027,16 +8035,21 @@ 
 bool
 Call_expression::check_argument_type(int i, const Type* parameter_type,
 				     const Type* argument_type,
-				     source_location argument_location)
+				     source_location argument_location,
+				     bool issued_error)
 {
   std::string reason;
   if (!Type::are_assignable(parameter_type, argument_type, &reason))
     {
-      if (reason.empty())
-	error_at(argument_location, "argument %d has incompatible type", i);
-      else
-	error_at(argument_location, "argument %d has incompatible type (%s)",
-		 i, reason.c_str());
+      if (!issued_error)
+	{
+	  if (reason.empty())
+	    error_at(argument_location, "argument %d has incompatible type", i);
+	  else
+	    error_at(argument_location,
+		     "argument %d has incompatible type (%s)",
+		     i, reason.c_str());
+	}
       this->set_is_error();
       return false;
     }
@@ -8113,7 +8126,7 @@ 
 	      return;
 	    }
 	  this->check_argument_type(i + 1, pt->type(), (*pa)->type(),
-				    (*pa)->location());
+				    (*pa)->location(), false);
 	}
       if (pt != parameters->end())
 	this->report_error(_("not enough arguments"));
diff -r 165da9b304ae go/expressions.h
--- a/go/expressions.h	Tue Aug 31 14:13:03 2010 -0700
+++ b/go/expressions.h	Tue Aug 31 14:45:13 2010 -0700
@@ -1231,10 +1231,10 @@ 
   lower_varargs(Gogo*, Named_object*);
 
   bool
-  is_compatible_varargs_argument(Named_object*, Expression*, Type*);
+  is_compatible_varargs_argument(Named_object*, Expression*, Type*, bool*);
 
   bool
-  check_argument_type(int, const Type*, const Type*, source_location);
+  check_argument_type(int, const Type*, const Type*, source_location, bool);
 
   tree
   bound_method_function(Translate_context*, Bound_method_expression*, tree*);