On 12/16/20 3:13 PM, Nikhil Benesch wrote:
On 12/16/20 2:20 PM, Rainer Orth wrote:
Hi Nikhil,

On 12/15/20 3:00 AM, Nikhil Benesch wrote:
If this patch looks good, I'll submit it upstream tomorrow.

Assuming no news is good news, I sent
https://go-review.googlesource.com/c/gofrontend/+/278672.

sorry for the delay, but unfortunately news is not so good: I get

runtime_sysinfo.go:315:18: error: use of undefined type '_ucontext'
   315 | type _ucontext_t _ucontext
       |                  ^

No problem, Rainer. I figured there would be some hiccups. The somewhat good 
news
is that this error appears to be independent of the patch I sent upstream.

I suspect what is happening here is that godump sees "typedef ucontext_t struct
ucontext" and outputs the typedef immediately. Only later does it observe that
"struct ucontext" is invalid. At that point it is too late to comment out the
typedef for _ucontext_t.

Oh, wait, Rainer, did you apply *both* solaris-godump.patch and
invalid-dummy.patch? I think if you apply only the former (i.e., only
solaris-godump.patch), which is the only bit I've submitted upstream,
all will be well.

For good measure, I've also fixed the issue in invalid-dummy.patch
and attached a new version. But I'm still not sure whether it is a
worthwhile change, and it's something we can discuss separately from
solaris-godump.patch.

Nikhil
diff --git a/gcc/godump.c b/gcc/godump.c
index ff3a4a9c52c..b4cbdf275f2 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -670,6 +670,8 @@ go_force_record_alignment (struct obstack *ob, const char 
*type_string,
   return index;
 }
 
+static void go_output_typedef (class godump_container *container, tree decl);
+
 /* Write the Go version of TYPE to CONTAINER->TYPE_OBSTACK.
    USE_TYPE_NAME is true if we can simply use a type name here without
    needing to define it.  IS_FUNC_OK is true if we can output a func
@@ -705,6 +707,7 @@ go_format_type (class godump_container *container, tree 
type,
     {
       tree name;
       void **slot;
+      void **islot;
 
       /* References to complex builtin types cannot be translated to
        Go.  */
@@ -714,10 +717,32 @@ go_format_type (class godump_container *container, tree 
type,
 
       name = TYPE_IDENTIFIER (type);
 
-      slot = htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER 
(name),
+
+      slot = htab_find_slot (container->type_hash, IDENTIFIER_POINTER (name),
                             NO_INSERT);
-      if (slot != NULL)
-       ret = false;
+      islot = htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER 
(name),
+                            NO_INSERT);
+      if (islot != NULL)
+       {
+         /* The named type is known to be invalid.  */
+         ret = false;
+       }
+      else if (slot == NULL)
+       {
+         size_t pos;
+
+         /* The named type is not known to be either valid or invalid.
+            Check to see if the named type is valid. Doing so requires
+            formatting the type and throwing away the result, which is
+            a bit silly.  */
+
+         pos = obstack_object_size (ob);
+
+         if (!go_format_type (container, type, false, false, NULL, false))
+           ret = false;
+
+         ob->next_free = ob->object_base + pos;
+       }
 
       /* References to incomplete structs are permitted in many
         contexts, like behind a pointer or inside of a typedef. So
@@ -1351,11 +1376,9 @@ find_dummy_types (const char *const &ptr, 
godump_container *adata)
   class godump_container *data = (class godump_container *) adata;
   const char *type = (const char *) ptr;
   void **slot;
-  void **islot;
 
   slot = htab_find_slot (data->type_hash, type, NO_INSERT);
-  islot = htab_find_slot (data->invalid_hash, type, NO_INSERT);
-  if (slot == NULL || islot != NULL)
+  if (slot == NULL)
     fprintf (go_dump_file, "type _%s struct {}\n", type);
   return true;
 }
diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c 
b/gcc/testsuite/gcc.misc-tests/godump-1.c
index d37ab0b5af4..4492a6e4887 100644
--- a/gcc/testsuite/gcc.misc-tests/godump-1.c
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -304,6 +304,13 @@ long double ld_v1;
 ld_t ld_v2;
 /* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v2 
INVALID-float-\[0-9\]*$" } } */
 
+typedef struct ld_s ld_s_t1;
+typedef struct ld_s { long double ld_s_f; } ld_s_t2;
+/* { dg-final { scan-file godump-1.out "(?n)^// type _ld_s_t1 _ld_s$" } } *
+/* { dg-final { scan-file godump-1.out "(?n)^// type _ld_s struct \{ ld_s_f 
INVALID-float-\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// type _ld_s_t2 _ld_s$" } } *
+/* { dg-final { scan-file-not godump-1.out "(?n)^type _ld_s struct \{\}$" } } 
*/
+
 /*** complex types ***/
 typedef _Complex cx_t;
 /* { dg-final { scan-file godump-1.out "(?n)^type _cx_t complex\[0-9\]*$" } } 
*/
@@ -476,6 +483,8 @@ struct { double d; uint8_t : 0; } sd_not_equiv;
 /* { dg-final { scan-file godump-1.out "(?n)^var _sd_not_equiv struct \{ d 
float\[0-9\]*; \}$" } } */
 
 typedef struct s_undef_t s_undef_t2;
+/* { dg-final { scan-file godump-1.out "(?n)^type _s_undef_t2 _s_undef_t$" } } 
*/
+/* { dg-final { scan-file godump-1.out "(?n)^type _s_undef_t struct \{\}$" } } 
*/
 
 typedef struct s_fwd *s_fwd_p;
 /* { dg-final { scan-file godump-1.out "(?n)^type _s_fwd_p \\*_s_fwd$" } } */
@@ -816,6 +825,8 @@ union { uint64_t : 1; uint8_t ca[5]; } u2_size;
 /* { dg-final { scan-file godump-1.out "(?n)^var _u2_size struct \{ ca 
\\\[4\\+1\\\]uint8; \}$" } } */
 
 typedef union u_undef_t u_undef_t2;
+/* { dg-final { scan-file godump-1.out "(?n)^type _u_undef_t2 _u_undef_t$" } } 
*/
+/* { dg-final { scan-file godump-1.out "(?n)^type _u_undef_t struct \{\}$" } } 
*/
 
 typedef union { uint64_t b : 1; uint8_t ca[5]; } tu3_size;
 /* { dg-final { scan-file godump-1.out "(?n)^type _tu3_size struct \{ ca 
\\\[4\\+1\\\]uint8; Godump_0_pad \\\[.\\\]byte; Godump_1_align 
\\\[0\\\]u?int64; \}$" } } */

Reply via email to