compiler: include selected constant types during export processing
authorIan Lance Taylor <ian@gcc.gnu.org>
Fri, 4 Oct 2019 18:14:30 +0000 (18:14 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Fri, 4 Oct 2019 18:14:30 +0000 (18:14 +0000)
    The machinery that collects types referenced by expressions that are
    part of inlinable function bodies was missing the types of local named
    constants in certain cases. This patch updates the
    Collect_export_references::expression() hook to look for references to
    local named constants and include their types in the exported set.

    Fixes golang/go#34577.

    Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/198017

From-SVN: r276594

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

index bb509943d6e0d8e523fb65728fd5b790e191f179..1508eb166504666e548d5e177f4d31a664798323 100644 (file)
@@ -1,4 +1,4 @@
-441f3f1f350b532707c48273d7f454cf1c4e959f
+ddfb845fad1f2e8b84383f262ed5ea5be7b3e35a
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 32ab4982091b13cc4678cdc7e437b608780fe647..5aaa207ff5fbf69a19ae04bebe6f588f27558b8a 100644 (file)
@@ -249,6 +249,14 @@ Collect_export_references::expression(Expression** pexpr)
       return TRAVERSE_CONTINUE;
     }
 
+  const Named_object* nco = expr->named_constant();
+  if (nco != 0 && nco->package() == NULL)
+    {
+      const Named_constant *nc = nco->const_value();
+      Type::traverse(nc->type(), this);
+      return TRAVERSE_CONTINUE;
+    }
+
   return TRAVERSE_CONTINUE;
 }
 
@@ -322,6 +330,10 @@ Collect_export_references::type(Type* type)
   if (type->is_void_type())
     return TRAVERSE_SKIP_COMPONENTS;
 
+  // Skip the nil type, turns up in function bodies.
+  if (type->is_nil_type())
+    return TRAVERSE_SKIP_COMPONENTS;
+
   // Skip abstract types.  We should never see these in real code,
   // only in things like const declarations.
   if (type->is_abstract())
index 9babc3485951ee8452d2352a828e995b9e55ca44..b614921cf39e4ab07f823cc0dfb627d101a49717 100644 (file)
@@ -3234,6 +3234,10 @@ class Const_expression : public Expression
   named_object()
   { return this->constant_; }
 
+  const Named_object*
+  named_object() const
+  { return this->constant_; }
+
   // Check that the initializer does not refer to the constant itself.
   void
   check_for_init_loop();
@@ -16782,6 +16786,15 @@ Expression::is_local_variable() const
          || (no->is_variable() && !no->var_value()->is_global()));
 }
 
+const Named_object*
+Expression::named_constant() const
+{
+  if (this->classification() != EXPRESSION_CONST_REFERENCE)
+    return NULL;
+  const Const_expression* ce = static_cast<const Const_expression*>(this);
+  return ce->named_object();
+}
+
 // Class Type_guard_expression.
 
 // Traversal.
index 2e3d1e0ccf6b6750fc171d37bf89b9e0dee9e37d..a0370e1ac9b5248f676f263cab5bc8cd297c5b61 100644 (file)
@@ -587,6 +587,11 @@ class Expression
   boolean_constant_value(bool* val) const
   { return this->do_boolean_constant_value(val); }
 
+  // If this is a const reference expression, return the named
+  // object to which the expression refers, otherwise return NULL.
+  const Named_object*
+  named_constant() const;
+
   // This is called if the value of this expression is being
   // discarded.  This issues warnings about computed values being
   // unused.  This returns true if all is well, false if it issued an