]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
compiler: traverse expressions when exporting constants
authorJulia Lapenko <julia.lapenko@gmail.com>
Mon, 16 May 2022 07:37:49 +0000 (10:37 +0300)
committerIan Lance Taylor <iant@golang.org>
Thu, 19 May 2022 02:34:49 +0000 (19:34 -0700)
When exporting a constant A that is expressed through a constant
B from another package, it is necessary to traverse an expression
representing the constant A to generate a sequence of type casts
from the constant B. Current implementation doesn't collect types
of constants contained in such expressions. This change fetches
these types.

Fixes golang/go#51291

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

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

index 5fa8becde3e4ef8e8af40f3205d99d472ecc0b69..2cf7141c4fa3fc13896a32aceba9bbfd7c4c3792 100644 (file)
@@ -1,4 +1,4 @@
-9d07072e58ca4f9f05343dfd3475b9f49dae5ec5
+0058658a9efb6e5c5faa6f0f65949beea5ddbc98
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 70d3f708d3265fab60b042bb442e8b98b7a2c95a..a30b11af31e4647c3c8460963ba6f23bc2c7c32e 100644 (file)
@@ -124,6 +124,11 @@ class Collect_export_references : public Traverse
   void
   prepare_types(const std::vector<Named_object*>& sorted_exports);
 
+  // Third entry point (called after the method above), to find
+  // all types in expressions referenced by exports.
+  void
+  prepare_expressions(const std::vector<Named_object*>& sorted_exports);
+
  protected:
   // Override of parent class method.
   int
@@ -281,6 +286,28 @@ Collect_export_references::expression(Expression** pexpr)
   return TRAVERSE_CONTINUE;
 }
 
+// Collect up the set of types mentioned in expressions of things we're exporting,
+// and collect all the packages encountered during type traversal, to make sure
+// we can declare things referered to indirectly (for example, in the body of an
+// exported inline function from another package).
+
+void
+Collect_export_references::prepare_expressions(const std::vector<Named_object*>& sorted_exports)
+{
+  for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin();
+       p != sorted_exports.end();
+       ++p)
+    {
+      Named_object* no = *p;
+      if (no->classification() == Named_object::NAMED_OBJECT_CONST)
+        {
+          Expression* e = no->const_value()->expr();
+          if (e != NULL)
+            Expression::traverse(&e, this);
+        }
+    }
+}
+
 // Collect up the set of types mentioned in things we're exporting, and collect
 // all the packages encountered during type traversal, to make sure we can
 // declare things referered to indirectly (for example, in the body of an
@@ -891,6 +918,7 @@ Export::export_globals(const std::string& package_name,
   // Collect up the set of types mentioned in things we're exporting,
   // and any packages that may be referred to indirectly.
   collect.prepare_types(sorted_exports);
+  collect.prepare_expressions(sorted_exports);
 
   // Assign indexes to all exported types and types referenced by
   // things we're exporting.  Return value is index of first non-exported