]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: Accept trailing comma after varargs parameter.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 13 Dec 2012 22:20:23 +0000 (22:20 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 13 Dec 2012 22:20:23 +0000 (22:20 +0000)
Also fix handling of interfaces seen only in a function or
method declaration.

From-SVN: r194492

gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h
gcc/go/gofrontend/parse.cc
gcc/go/gofrontend/types.cc
gcc/go/gofrontend/types.h
gcc/testsuite/go.test/test/fixedbugs/bug228.go

index 0f63afb53cbf6281557e430f3179bd7a1d6d35ae..41f9665e7240e1fb4eff700bcca5a7d5982ef985 100644 (file)
@@ -1764,6 +1764,26 @@ Finalize_methods::type(Type* t)
              }
          }
 
+       // Finalize the types of all methods that are declared but not
+       // defined, since we won't see the declarations otherwise.
+       if (nt->named_object()->package() == NULL
+           && nt->local_methods() != NULL)
+         {
+           const Bindings* methods = nt->local_methods();
+           for (Bindings::const_declarations_iterator p =
+                  methods->begin_declarations();
+                p != methods->end_declarations();
+                p++)
+             {
+               if (p->second->is_function_declaration())
+                 {
+                   Type* mt = p->second->func_declaration_value()->type();
+                   if (Type::traverse(mt, this) == TRAVERSE_EXIT)
+                     return TRAVERSE_EXIT;
+                 }
+             }
+         }
+
        return TRAVERSE_SKIP_COMPONENTS;
       }
 
@@ -4491,7 +4511,7 @@ Type_declaration::has_methods() const
 void
 Type_declaration::define_methods(Named_type* nt)
 {
-  for (Methods::const_iterator p = this->methods_.begin();
+  for (std::vector<Named_object*>::const_iterator p = this->methods_.begin();
        p != this->methods_.end();
        ++p)
     nt->add_existing_method(*p);
@@ -5230,8 +5250,7 @@ Bindings::traverse(Traverse* traverse, bool is_global)
     }
 
   // If we need to traverse types, check the function declarations,
-  // which have types.  We don't need to check the type declarations,
-  // as those are just names.
+  // which have types.  Also check any methods of a type declaration.
   if ((traverse_mask & e_or_t) != 0)
     {
       for (Bindings::const_declarations_iterator p =
@@ -5246,6 +5265,27 @@ Bindings::traverse(Traverse* traverse, bool is_global)
                  == TRAVERSE_EXIT)
                return TRAVERSE_EXIT;
            }
+         else if (p->second->is_type_declaration())
+           {
+             const std::vector<Named_object*>* methods =
+               p->second->type_declaration_value()->methods();
+             for (std::vector<Named_object*>::const_iterator pm =
+                    methods->begin();
+                  pm != methods->end();
+                  pm++)
+               {
+                 Named_object* no = *pm;
+                 Type *t;
+                 if (no->is_function())
+                   t = no->func_value()->type();
+                 else if (no->is_function_declaration())
+                   t = no->func_declaration_value()->type();
+                 else
+                   continue;
+                 if (Type::traverse(t, traverse) == TRAVERSE_EXIT)
+                   return TRAVERSE_EXIT;
+               }
+           }
        }
     }
 
index 4fbd6374331aea95085924eb89a4104e8935bd24..cffdd2191186c6e66aec75fb9fee85325737e760 100644 (file)
@@ -37,8 +37,6 @@ class Channel_type;
 class Interface_type;
 class Named_type;
 class Forward_declaration_type;
-class Method;
-class Methods;
 class Named_object;
 class Label;
 class Translate_context;
@@ -1738,6 +1736,11 @@ class Type_declaration
   bool
   has_methods() const;
 
+  // Return the methods.
+  const std::vector<Named_object*>*
+  methods() const
+  { return &this->methods_; }
+
   // Define methods when the real type is known.
   void
   define_methods(Named_type*);
@@ -1748,8 +1751,6 @@ class Type_declaration
   using_type();
 
  private:
-  typedef std::vector<Named_object*> Methods;
-
   // The location of the type declaration.
   Location location_;
   // If this type is declared in a function, a pointer back to the
@@ -1758,7 +1759,7 @@ class Type_declaration
   // The index of this type in IN_FUNCTION_.
   unsigned int in_function_index_;
   // Methods defined before the type is defined.
-  Methods methods_;
+  std::vector<Named_object*> methods_;
   // True if we have issued a warning about a use of this type
   // declaration when it is undefined.
   bool issued_warning_;
index 8c00fa31da4879d44bd52c6a0bd7fbb3ede9cea7..d7a18d023be8d8379b854f8bfbe832cfa97be84b 100644 (file)
@@ -975,13 +975,13 @@ Parse::parameter_list(bool* is_varargs)
   this->parameter_decl(parameters_have_names, ret, is_varargs, &mix_error);
   while (this->peek_token()->is_op(OPERATOR_COMMA))
     {
+      if (this->advance_token()->is_op(OPERATOR_RPAREN))
+       break;
       if (is_varargs != NULL && *is_varargs)
        {
          error_at(this->location(), "%<...%> must be last parameter");
          saw_error = true;
        }
-      if (this->advance_token()->is_op(OPERATOR_RPAREN))
-       break;
       this->parameter_decl(parameters_have_names, ret, is_varargs, &mix_error);
     }
   if (mix_error)
index c79181b7a60ca88ed2d66fdfb35d39fe2f00a764..44d6a61f8e67cbf2d222ed01d9a85d5dfac21f04 100644 (file)
@@ -6500,6 +6500,24 @@ Type::make_channel_type(bool send, bool receive, Type* element_type)
 
 // Class Interface_type.
 
+// Return the list of methods.
+
+const Typed_identifier_list*
+Interface_type::methods() const
+{
+  go_assert(this->methods_are_finalized_ || saw_errors());
+  return this->all_methods_;
+}
+
+// Return the number of methods.
+
+size_t
+Interface_type::method_count() const
+{
+  go_assert(this->methods_are_finalized_ || saw_errors());
+  return this->all_methods_ == NULL ? 0 : this->all_methods_->size();
+}
+
 // Traversal.
 
 int
@@ -9630,6 +9648,19 @@ Forward_declaration_type::do_traverse(Traverse* traverse)
   return TRAVERSE_CONTINUE;
 }
 
+// Verify the type.
+
+bool
+Forward_declaration_type::do_verify()
+{
+  if (!this->is_defined() && !this->is_nil_constant_as_type())
+    {
+      this->warn();
+      return false;
+    }
+  return true;
+}
+
 // Get the backend representation for the type.
 
 Btype*
index fc84db039bbbffb70185b10274f05670a0192e54..ba918c9602396add9052d4d7f0873444ddfff1a8 100644 (file)
@@ -2534,19 +2534,11 @@ class Interface_type : public Type
   // Return the list of methods.  This will return NULL for an empty
   // interface.
   const Typed_identifier_list*
-  methods() const
-  {
-    go_assert(this->methods_are_finalized_);
-    return this->all_methods_;
-  }
+  methods() const;
 
   // Return the number of methods.
   size_t
-  method_count() const
-  {
-    go_assert(this->methods_are_finalized_);
-    return this->all_methods_ == NULL ? 0 : this->all_methods_->size();
-  }
+  method_count() const;
 
   // Return the method NAME, or NULL.
   const Typed_identifier*
@@ -3023,6 +3015,9 @@ class Forward_declaration_type : public Type
   int
   do_traverse(Traverse* traverse);
 
+  bool
+  do_verify();
+
   bool
   do_has_pointer() const
   { return this->real_type()->has_pointer(); }
index 3d23609dde406a1e29b04933db405fe8fc716dea..f2dd54556bfa8f2bd6b90d681930fc41e5968b65 100644 (file)
@@ -8,7 +8,7 @@ package main
 
 func f(x int, y ...int)        // ok
 
-func g(x int, y float) (...)   // ERROR "[.][.][.]" "final argument"
+func g(x int, y float32) (...) // ERROR "[.][.][.]" "final argument"
 
 func h(x, y ...int)            // ERROR "[.][.][.]"