Patchwork [gccgo] Avoid duplicate errors with ellipsis types

login
register
mail settings
Submitter Ian Taylor
Date Aug. 31, 2010, 9:47 p.m.
Message ID <mcrsk1ucv4t.fsf@google.com>
Download mbox | patch
Permalink /patch/63320/
State New
Headers show

Comments

Ian Taylor - Aug. 31, 2010, 9:47 p.m.
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

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*);