On 12/10/20 4:44 PM, Rainer Orth wrote:
I'm attaching the -save-temps output, so you can work on the real data
rather than trying to figure things out from the Illumos repos.

Thanks, that was helpful. I also have successfully acquired access to
gcc211, so I should be self sufficient moving forward. Thanks again for
the pointer to the compile farm.

I believe the attached patch will fix the issue. There are a few parts
to the fix:

  * Typedefs whose name matches the underlying struct tag, as in

        typedef struct FILE {} FILE;
are suppressed, so that we output the interesting "struct FILE {}"
    definition and not the useless "typedef FILE FILE" definition.

  * Rewriting of _in6_addr to [16]byte is applied to all type
    definitions, rather than to an enumerated subset. This follows the
    approach used for timeval/timespec.

    The old approach could not handle cases like:

        type _mld2mar struct { addr _in6_addr /* ... */}
        type _mld2mar_t _mld2mar
The old approach would filter out type _mld2mar but understandably
    was not smart enough to filter out mld2mar_t, resulting in a
    reference to non-existent type _mld2mar.

  * Handling of _timestruc_t when it is just an alias for timespec.

  * Inclusion of stdio.h to avoid an incomplete definition of the type
    __FILE.

There are a few more hurdles before this patch is ready for commit. The
changes to godump.c deserve new test cases. And the changes to the
mk[r]sysinfo.sh scripts will need to go upstream first. Hopefully I'll
get to that soon. I wanted to send along what I had in the meantime.

Nikhil
diff --git a/gcc/godump.c b/gcc/godump.c
index 033b2c5..c3f4b7b 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -1155,15 +1155,25 @@ go_output_typedef (class godump_container *container, 
tree decl)
     {
       void **slot;
       const char *type;
+      tree original_type;
 
       type = IDENTIFIER_POINTER (DECL_NAME (decl));
+      original_type = DECL_ORIGINAL_TYPE (decl);
+
+      /* Suppress typedefs where the type name matches the underlying
+        struct/union/enum tag. This way we'll emit the struct definition
+        instead of an invalid recursive type.  */
+      if (TYPE_IDENTIFIER (original_type) != NULL
+         && IDENTIFIER_POINTER (TYPE_IDENTIFIER (original_type)) == type)
+       return;
+
       /* If type defined already, skip.  */
       slot = htab_find_slot (container->type_hash, type, INSERT);
       if (*slot != NULL)
        return;
       *slot = CONST_CAST (void *, (const void *) type);
 
-      if (!go_format_type (container, DECL_ORIGINAL_TYPE (decl), true, false,
+      if (!go_format_type (container, original_type, true, false,
                           NULL, false))
        {
          fprintf (go_dump_file, "// ");
@@ -1174,7 +1184,8 @@ go_output_typedef (class godump_container *container, 
tree decl)
               IDENTIFIER_POINTER (DECL_NAME (decl)));
       go_output_type (container);
 
-      if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
+      if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
+         || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
        {
          HOST_WIDE_INT size = int_size_in_bytes (TREE_TYPE (decl));
 
@@ -1187,7 +1198,9 @@ go_output_typedef (class godump_container *container, 
tree decl)
 
       container->decls_seen.add (decl);
     }
-  else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
+  else if ((RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl))
+           || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
+          && TYPE_NAME (TREE_TYPE (decl)) != NULL)
     {
        void **slot;
        const char *type;
diff --git a/libgo/mkrsysinfo.sh b/libgo/mkrsysinfo.sh
index c28f0e5..29ca1ab 100755
--- a/libgo/mkrsysinfo.sh
+++ b/libgo/mkrsysinfo.sh
@@ -24,11 +24,16 @@ grep -v '^// ' gen-sysinfo.go | \
   grep -v '^type _timespec ' | \
   grep -v '^type _epoll_' | \
   grep -v '^type _*locale[_ ]' | \
-  grep -v 'in6_addr' | \
+  grep -v '^type _in6_addr' | \
   grep -v 'sockaddr_in6' | \
   sed -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1timeval\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timeval$/\1timeval/g' \
       -e 's/\([^a-zA-Z0-9_]\)_timespec_t\([^a-zA-Z0-9_]\)/\1timespec\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timespec_t$/\1timespec_t/g' \
       -e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1timespec\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timespec$/\1timespec/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_in6_addr\([^a-zA-Z0-9_]\)/\1[16]byte\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_in6_addr$/\1[16]byte/g' \
     >> ${OUT}
 
 # The C long type, needed because that is the type that ptrace returns.
@@ -44,16 +49,6 @@ else
   exit 1
 fi
 
-# On AIX, the _arpcom struct, is filtered by the above grep sequence, as it as
-# a field of type _in6_addr, but other types depend on _arpcom, so we need to
-# put it back.
-grep '^type _arpcom ' gen-sysinfo.go | \
-  sed -e 's/_in6_addr/[16]byte/' >> ${OUT}
-
-# Same on Solaris for _mld_hdr_t.
-grep '^type _mld_hdr_t ' gen-sysinfo.go | \
-  sed -e 's/_in6_addr/[16]byte/' >> ${OUT}
-
 # The time structures need special handling: we need to name the
 # types, so that we can cast integers to the right types when
 # assigning to the structures.
@@ -174,31 +169,6 @@ if grep "^// type _upad128_t" gen-sysinfo.go > /dev/null 
2>&1; then
   echo "type _upad128_t struct { _l [4]uint32; }" >> ${OUT}
 fi
 
-# The Solaris 11 Update 1 _zone_net_addr_t struct.
-grep '^type _zone_net_addr_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr/[16]byte/' \
-    >> ${OUT}
-
-# The Solaris 11.4 _flow_arp_desc_t struct.
-grep '^type _flow_arp_desc_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr_t/[16]byte/g' \
-    >> ${OUT}
-
-# The Solaris 11.4 _flow_l3_desc_t struct.
-grep '^type _flow_l3_desc_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr_t/[16]byte/g' \
-    >> ${OUT}
-
-# The Solaris 11.3 _mac_ipaddr_t struct.
-grep '^type _mac_ipaddr_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr_t/[16]byte/g' \
-    >> ${OUT}
-
-# The Solaris 11.3 _mactun_info_t struct.
-grep '^type _mactun_info_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr_t/[16]byte/g' \
-    >> ${OUT}
-
 # The Solaris port_event_t struct.
 grep '^type _port_event_t ' gen-sysinfo.go | \
     sed -e s'/_port_event_t/portevent/' \
diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh
index b32a026..c4df522 100755
--- a/libgo/mksysinfo.sh
+++ b/libgo/mksysinfo.sh
@@ -36,24 +36,20 @@ grep -v '^// ' gen-sysinfo.go | \
   grep -v '^type _timestruc_t ' | \
   grep -v '^type _epoll_' | \
   grep -v '^type _*locale[_ ]' | \
-  grep -v 'in6_addr' | \
+  grep -v '^type _in6_addr' | \
   grep -v 'sockaddr_in6' | \
   sed -e 's/\([^a-zA-Z0-9_]\)_timeval\([^a-zA-Z0-9_]\)/\1Timeval\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timeval$/\1Timeval/g' \
       -e 's/\([^a-zA-Z0-9_]\)_timespec_t\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timespec_t$/\1Timespec/g' \
       -e 's/\([^a-zA-Z0-9_]\)_timespec\([^a-zA-Z0-9_]\)/\1Timespec\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timespec$/\1Timespec/g' \
       -e 's/\([^a-zA-Z0-9_]\)_timestruc_t\([^a-zA-Z0-9_]\)/\1Timestruc\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_timestruc_t$/\1Timestruc/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_in6_addr\([^a-zA-Z0-9_]\)/\1[16]byte\2/g' \
+      -e 's/\([^a-zA-Z0-9_]\)_in6_addr$/\1[16]byte/g' \
     >> ${OUT}
 
-# On AIX, the _arpcom struct, is filtered by the above grep sequence, as it as
-# a field of type _in6_addr, but other types depend on _arpcom, so we need to
-# put it back.
-grep '^type _arpcom ' gen-sysinfo.go | \
-  sed -e 's/_in6_addr/[16]byte/' >> ${OUT}
-
-# Same on Solaris for _mld_hdr_t.
-grep '^type _mld_hdr_t ' gen-sysinfo.go | \
-  sed -e 's/_in6_addr/[16]byte/' >> ${OUT}
-
 # The errno constants.  These get type Errno.
 egrep '#define E[A-Z0-9_]+ [0-9E]' errno.i | \
   sed -e 's/^#define \(E[A-Z0-9_]*\) .*$/const \1 = Errno(_\1)/' >> ${OUT}
@@ -483,7 +479,9 @@ echo $timespec | \
       -e 's/tv_nsec *[a-zA-Z0-9_]*/Nsec Timespec_nsec_t/' >> ${OUT}
 
 timestruc=`grep '^type _timestruc_t ' gen-sysinfo.go || true`
-if test "$timestruc" != ""; then
+if test "$timestruc" = "type _timestruc_t _timespec"; then
+  echo "type Timestruc Timespec" >> ${OUT}
+elif test "$timestruc" != ""; then
   timestruc_sec=`echo $timestruc | sed -n -e 's/^.*tv_sec \([^ ]*\);.*$/\1/p'`
   timestruc_nsec=`echo $timestruc | sed -n -e 's/^.*tv_nsec \([^ 
]*\);.*$/\1/p'`
   echo "type Timestruc_sec_t = $timestruc_sec" >> ${OUT}
@@ -1523,31 +1521,6 @@ if ! grep 'const SizeofICMPv6Filter ' ${OUT} >/dev/null 
2>&1; then
     echo 'const SizeofICMPv6Filter = 32' >> ${OUT}
 fi
 
-# The Solaris 11 Update 1 _zone_net_addr_t struct.
-grep '^type _zone_net_addr_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr/[16]byte/' \
-    >> ${OUT}
-
-# The Solaris 11.4 _flow_arp_desc_t struct.
-grep '^type _flow_arp_desc_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr_t/[16]byte/g' \
-    >> ${OUT}
-
-# The Solaris 11.4 _flow_l3_desc_t struct.
-grep '^type _flow_l3_desc_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr_t/[16]byte/g' \
-    >> ${OUT}
-
-# The Solaris 11.3 _mac_ipaddr_t struct.
-grep '^type _mac_ipaddr_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr_t/[16]byte/g' \
-    >> ${OUT}
-
-# The Solaris 11.3 _mactun_info_t struct.
-grep '^type _mactun_info_t ' gen-sysinfo.go | \
-    sed -e 's/_in6_addr_t/[16]byte/g' \
-    >> ${OUT}
-
 # Type 'uint128' is needed in a couple of type definitions on arm64,such
 # as _user_fpsimd_struct, _elf_fpregset_t, etc.
 if ! grep '^type uint128' ${OUT} > /dev/null 2>&1; then
diff --git a/libgo/sysinfo.c b/libgo/sysinfo.c
index a060ea8..8ce061e 100644
--- a/libgo/sysinfo.c
+++ b/libgo/sysinfo.c
@@ -11,6 +11,7 @@
 
 #include <stddef.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <sys/types.h>
 #include <dirent.h>
 #include <errno.h>

Reply via email to