Determine call types even if first call result is not used.
authorIan Lance Taylor <ian@gcc.gnu.org>
Thu, 3 Mar 2011 02:08:28 +0000 (02:08 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Thu, 3 Mar 2011 02:08:28 +0000 (02:08 +0000)
From-SVN: r170637

gcc/go/gofrontend/expressions.cc
gcc/go/gofrontend/expressions.h

index a45e7acc247bbcfa5d7eaf4c87af68d21fb6c2f6..28b7ee669bfbb7c306ec32220641c66f898ad59d 100644 (file)
@@ -7250,6 +7250,9 @@ Builtin_call_expression::do_type()
 void
 Builtin_call_expression::do_determine_type(const Type_context* context)
 {
+  if (!this->determining_types())
+    return;
+
   this->fn()->determine_type_no_context();
 
   const Expression_list* args = this->args();
@@ -8486,6 +8489,9 @@ Call_expression::do_type()
 void
 Call_expression::do_determine_type(const Type_context*)
 {
+  if (!this->determining_types())
+    return;
+
   this->fn_->determine_type_no_context();
   Function_type* fntype = this->get_function_type();
   const Typed_identifier_list* parameters = NULL;
@@ -8512,6 +8518,21 @@ Call_expression::do_determine_type(const Type_context*)
     }
 }
 
+// Called when determining types for a Call_expression.  Return true
+// if we should go ahead, false if they have already been determined.
+
+bool
+Call_expression::determining_types()
+{
+  if (this->types_are_determined_)
+    return false;
+  else
+    {
+      this->types_are_determined_ = true;
+      return true;
+    }
+}
+
 // Check types for parameter I.
 
 bool
@@ -9004,8 +9025,7 @@ Call_result_expression::do_check_types(Gogo*)
 void
 Call_result_expression::do_determine_type(const Type_context*)
 {
-  if (this->index_ == 0)
-    this->call_->determine_type_no_context();
+  this->call_->determine_type_no_context();
 }
 
 // Return the tree.
index c050a4a9c0c15b7f69f46e5e2b75f49202f6c9b5..b6fc9c012d93296641239aee4c56d59dce1b5665 100644 (file)
@@ -1161,7 +1161,7 @@ class Call_expression : public Expression
                  source_location location)
     : Expression(EXPRESSION_CALL, location),
       fn_(fn), args_(args), type_(NULL), tree_(NULL), is_varargs_(is_varargs),
-      is_value_discarded_(false), varargs_are_lowered_(false),
+      varargs_are_lowered_(false), types_are_determined_(false),
       is_deferred_(false)
   { }
 
@@ -1220,7 +1220,7 @@ class Call_expression : public Expression
 
   void
   do_discarding_value()
-  { this->is_value_discarded_ = true; }
+  { }
 
   virtual Type*
   do_type();
@@ -1263,6 +1263,11 @@ class Call_expression : public Expression
   lower_varargs(Gogo*, Named_object* function, Type* varargs_type,
                size_t param_count);
 
+  // Let a builtin expression check whether types have been
+  // determined.
+  bool
+  determining_types();
+
  private:
   bool
   check_argument_type(int, const Type*, const Type*, source_location, bool);
@@ -1286,10 +1291,10 @@ class Call_expression : public Expression
   tree tree_;
   // True if the last argument is a varargs argument (f(a...)).
   bool is_varargs_;
-  // True if the value is being discarded.
-  bool is_value_discarded_;
   // True if varargs have already been lowered.
   bool varargs_are_lowered_;
+  // True if types have been determined.
+  bool types_are_determined_;
   // True if the call is an argument to a defer statement.
   bool is_deferred_;
 };