compiler: Check the type in function declarations.
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 31 Jul 2015 22:16:12 +0000 (22:16 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 31 Jul 2015 22:16:12 +0000 (22:16 +0000)
    Function declarations don't create a block where the variables listed
    in the parameter list are declared.  Because there are no variables
    declared, the types of the parameter variables is unchecked, allowing
    for invalid values to be used as the type.  This patch adds a special
    case to the check_types pass for function declarations.

    Fixes golang/go#11567.

    Reviewed-on: https://go-review.googlesource.com/12662

From-SVN: r226456

gcc/go/gofrontend/MERGE
gcc/go/gofrontend/gogo.cc
gcc/go/gofrontend/gogo.h

index 6afd1efdbeaa5055bc6855f10b5f300a08e50b7c..732b33d36a08c8407d968887bdac242185bc056a 100644 (file)
@@ -1,4 +1,4 @@
-19f0ec56bf278a9cbb100c6b24ec1a12c95ec41a
+bc4dda16f8686ab6e7335adfdfd2c6cc81cb2eb5
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 0824102ccc16b4011729fd9f254aebb4671c9ee0..77b4d52650751599007c6e8a8c38207e8e3619d9 100644 (file)
@@ -3258,6 +3258,17 @@ Gogo::check_types()
 {
   Check_types_traverse traverse(this);
   this->traverse(&traverse);
+
+  Bindings* bindings = this->current_bindings();
+  for (Bindings::const_declarations_iterator p = bindings->begin_declarations();
+       p != bindings->end_declarations();
+       ++p)
+    {
+      // Also check the types in a function declaration's signature.
+      Named_object* no = p->second;
+      if (no->is_function_declaration())
+        no->func_declaration_value()->check_types();
+    }
 }
 
 // Check the types in a single block.
@@ -5297,6 +5308,26 @@ Function_declaration::build_backend_descriptor(Gogo* gogo)
     }
 }
 
+// Check that the types used in this declaration's signature are defined.
+// Reports errors for any undefined type.
+
+void
+Function_declaration::check_types() const
+{
+  // Calling Type::base will give errors for any undefined types.
+  Function_type* fntype = this->type();
+  if (fntype->receiver() != NULL)
+    fntype->receiver()->type()->base();
+  if (fntype->parameters() != NULL)
+    {
+      const Typed_identifier_list* params = fntype->parameters();
+      for (Typed_identifier_list::const_iterator p = params->begin();
+           p != params->end();
+           ++p)
+        p->type()->base();
+    }
+}
+
 // Return the function's decl after it has been built.
 
 Bfunction*
index 51f628fa3b201242004cc2118ede0ffae317cb99..ece7e0f2e1ce356da26bfb916cd338fa75df6a7b 100644 (file)
@@ -1394,6 +1394,10 @@ class Function_declaration
   export_func(Export* exp, const std::string& name) const
   { Function::export_func_with_type(exp, name, this->fntype_); }
 
+  // Check that the types used in this declaration's signature are defined.
+  void
+  check_types() const;
+
  private:
   // The type of the function.
   Function_type* fntype_;