public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH 0/9] Gccgo port to s390[x] -- part I
@ 2014-09-09 12:44 Dominik Vogt
  2014-09-09 12:48 ` [PATCH 1/9] " Dominik Vogt
                   ` (9 more replies)
  0 siblings, 10 replies; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 12:44 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

The following series' of patches introduce s390[x] support for
Gccgo.  For practical reasons they will be submitted in separate
parts.  This is the first part of the submissions with
architecture independent bug fixes and enhancements that affect
the following directories:

  gcc                           (Gcc)
  gcc/testsuite/gcc.misc-tests  (Gcc)
  gcc/go/gofrontend             (gofrontend)
  gcc/testsuite/go.test         (golang)
  libgo                         (Gcc?)
  libgo/go                      (gofrontend)
  libgo/runtime                 (gofrontend)

It seemed infeasible to split this patch series and send the
patches only to the "right" places.  The following s390[x] patch
series' depend on all of them.

Summary of this series:

0001: Fix for bug #60406. (gofrontend)
0002: Test case for 0001. (golang)
0003: Bug fix for opening s390 libs. (gofrontend)
0004: Libgo compile fix. (gofrontend)
0005: Cleanup of x86 relocations in libgo. (gofrontend, optional)
0006: Fix in libgo/runtime/proc.c (Gcc?)
0007: Extend -fdump-go-spec (bitfields, unions and a bugfix) (Gcc)
0008: Extend -fdump-go-spec (complex types) (Gcc, optional)
0009: Fix handling of whitespace in configure script. (Gcc?)

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 1/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
@ 2014-09-09 12:48 ` Dominik Vogt
  2014-09-09 12:49 ` [PATCH 2/9] " Dominik Vogt
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 12:48 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 1273 bytes --]

This patch fixes bug 60406 in an architecture independent way.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60406

The key change in this patch is to use
_Unwind_FindEnclosingFunction() to identify the defering function.
However, this does not work on platforms that still use SJLJ
exceptions.

ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * libgo/runtime/proc.c (runtime_main): Initialize new structure fields.
        * libgo/runtime/go-recover.c (__go_can_recover): Rewrite logic to detect
        recover by return address.
        * libgo/runtime/go-defer.c (__go_set_defer_retaddr): Removed.
        (__go_set_defering_fn): Replacement for __go_set_defer_retaddr.
        (__go_defer): Initialize new structure fields.
        * libgo/runtime/go-defer.h (struct __go_defer_stack): Replace __retaddr
        with __defering_fn.

gcc/go/ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * gofrontend/statements.cc (build_thunk): The thunk uses the new
        libgo runtime runctions __go_set_defering_fn and no longer depends
        on the fake label and fake return value.
        * gofrontend/runtime.def: Replace SET_DEFER_RETADDR with
        SET_DEFERING_FN.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0001-GO-Fix-recover-logic-in-libgo-and-gofrontend.patch --]
[-- Type: text/x-diff, Size: 8287 bytes --]

From e6bbac3a00095f86535eceb5bdc87bca2ec406c9 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:30:14 +0100
Subject: [PATCH 1/9] GO: Fix recover logic in libgo and gofrontend.

1) Fix recover logic in libgo.
2) Fix recover logic in gofrontend.
---
 gcc/go/gofrontend/runtime.def   |  5 ++---
 gcc/go/gofrontend/statements.cc | 25 +++++--------------------
 libgo/runtime/go-defer.c        | 17 ++++++++---------
 libgo/runtime/go-defer.h        | 11 ++++++-----
 libgo/runtime/go-recover.c      | 40 +++++++++++++++++++++-------------------
 libgo/runtime/proc.c            |  2 +-
 6 files changed, 43 insertions(+), 57 deletions(-)

diff --git a/gcc/go/gofrontend/runtime.def b/gcc/go/gofrontend/runtime.def
index 8c6e82b..0cd045a 100644
--- a/gcc/go/gofrontend/runtime.def
+++ b/gcc/go/gofrontend/runtime.def
@@ -190,9 +190,8 @@ DEF_GO_RUNTIME(CAN_RECOVER, "__go_can_recover", P1(POINTER), R1(BOOL))
 // Get the return address of the function.
 DEF_GO_RUNTIME(RETURN_ADDRESS, "__go_return_address", P1(INT), R1(POINTER))
 
-// Set the return address for defer in a defer thunk.
-DEF_GO_RUNTIME(SET_DEFER_RETADDR, "__go_set_defer_retaddr", P1(POINTER),
-	       R1(BOOL))
+// Set the function address for defer in a defer thunk.
+DEF_GO_RUNTIME(SET_DEFERING_FN, "__go_set_defering_fn", P1(POINTER), R0())
 
 // Check for a deferred function in an exception handler.
 DEF_GO_RUNTIME(CHECK_DEFER, "__go_check_defer", P1(BOOLPTR), R0())
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 090c193..6f906fc 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -2348,25 +2348,14 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
   gogo->start_block(location);
 
   // For a defer statement, start with a call to
-  // __go_set_defer_retaddr.  */
-  Label* retaddr_label = NULL;
+  // __go_set_defering_fn.  */
   if (may_call_recover)
     {
-      retaddr_label = gogo->add_label_reference("retaddr", location, false);
-      Expression* arg = Expression::make_label_addr(retaddr_label, location);
-      Expression* call = Runtime::make_call(Runtime::SET_DEFER_RETADDR,
+      Expression* arg =
+	Expression::make_func_code_reference(function, location);
+      Expression* call = Runtime::make_call(Runtime::SET_DEFERING_FN,
 					    location, 1, arg);
-
-      // This is a hack to prevent the middle-end from deleting the
-      // label.
-      gogo->start_block(location);
-      gogo->add_statement(Statement::make_goto_statement(retaddr_label,
-							 location));
-      Block* then_block = gogo->finish_block(location);
-      then_block->determine_types();
-
-      Statement* s = Statement::make_if_statement(call, then_block, NULL,
-						  location);
+      Statement* s = Statement::make_statement(call, true);
       s->determine_types();
       gogo->add_statement(s);
     }
@@ -2455,12 +2444,8 @@ Thunk_statement::build_thunk(Gogo* gogo, const std::string& thunk_name)
 
   gogo->add_statement(call_statement);
 
-  // If this is a defer statement, the label comes immediately after
-  // the call.
   if (may_call_recover)
     {
-      gogo->add_label_definition("retaddr", location);
-
       Expression_list* vals = new Expression_list();
       vals->push_back(Expression::make_boolean(false, location));
       gogo->add_statement(Statement::make_return_statement(vals, location));
diff --git a/libgo/runtime/go-defer.c b/libgo/runtime/go-defer.c
index 5dd8c31..c0da2dc 100644
--- a/libgo/runtime/go-defer.c
+++ b/libgo/runtime/go-defer.c
@@ -26,7 +26,7 @@ __go_defer (_Bool *frame, void (*pfn) (void *), void *arg)
   n->__panic = g->panic;
   n->__pfn = pfn;
   n->__arg = arg;
-  n->__retaddr = NULL;
+  n->__defering_fn = NULL;
   n->__makefunc_can_recover = 0;
   n->__special = 0;
   g->defer = n;
@@ -69,17 +69,16 @@ __go_undefer (_Bool *frame)
     }
 }
 
-/* This function is called to record the address to which the deferred
-   function returns.  This may in turn be checked by __go_can_recover.
-   The frontend relies on this function returning false.  */
+/* This function is called to record the address of the function
+   to which the deferred function returns.  This may in turn be
+   checked by __go_can_recover.  */
 
-_Bool
-__go_set_defer_retaddr (void *retaddr)
+void
+__go_set_defering_fn (void *defering_fn)
 {
   G *g;
-
   g = runtime_g ();
   if (g->defer != NULL)
-    g->defer->__retaddr = retaddr;
-  return 0;
+    g->defer->__defering_fn = defering_fn;
+  return;
 }
diff --git a/libgo/runtime/go-defer.h b/libgo/runtime/go-defer.h
index acf2d40..c6d8b4a 100644
--- a/libgo/runtime/go-defer.h
+++ b/libgo/runtime/go-defer.h
@@ -30,14 +30,15 @@ struct __go_defer_stack
   /* The argument to pass to the function.  */
   void *__arg;
 
-  /* The return address that a recover thunk matches against.  This is
-     set by __go_set_defer_retaddr which is called by the thunks
-     created by defer statements.  */
-  const void *__retaddr;
+  /* The address of the function enclosing the return address that
+     a recover thunk matches against.  This is set by
+     __go_set_defering_fn which is called by the thunks created by
+     defer statements.  */
+  const void *__defering_fn;
 
   /* Set to true if a function created by reflect.MakeFunc is
      permitted to recover.  The return address of such a function
-     function will be somewhere in libffi, so __retaddr is not
+     function will be somewhere in libffi, so __defering_fn is not
      useful.  */
   _Bool __makefunc_can_recover;
 
diff --git a/libgo/runtime/go-recover.c b/libgo/runtime/go-recover.c
index 2d3db55..85ebf52 100644
--- a/libgo/runtime/go-recover.c
+++ b/libgo/runtime/go-recover.c
@@ -8,6 +8,8 @@
 #include "interface.h"
 #include "go-panic.h"
 #include "go-defer.h"
+#include <stdint.h>
+#include "unwind-generic.h"
 
 /* This is called by a thunk to see if the real function should be
    permitted to recover a panic value.  Recovering a value is
@@ -20,8 +22,6 @@ __go_can_recover (const void *retaddr)
 {
   G *g;
   struct __go_defer_stack *d;
-  const char* ret;
-  const char* dret;
   Location loc;
   const byte *name;
 
@@ -38,24 +38,26 @@ __go_can_recover (const void *retaddr)
   if (d->__panic == g->panic)
     return 0;
 
-  /* D->__RETADDR is the address of a label immediately following the
-     call to the thunk.  We can recover a panic if that is the same as
-     the return address of the thunk.  We permit a bit of slack in
-     case there is any code between the function return and the label,
-     such as an instruction to adjust the stack pointer.  */
+  /* D->__DEFERING_FN is the address of the function that called
+     D->defer (or NULL if defer was not called).  We can recover a
+     D->panic if that is the same as the caller of the thunk.  */
 
-  ret = (const char *) retaddr;
-
-#ifdef __sparc__
-  /* On SPARC the address we get, from __builtin_return_address, is
-     the address of the call instruction.  Adjust forward, also
-     skipping the delayed instruction following the call.  */
-  ret += 8;
-#endif
-
-  dret = (const char *) d->__retaddr;
-  if (ret <= dret && ret + 16 >= dret)
-    return 1;
+  if (d->__defering_fn != NULL)
+    {
+      void *real_retaddr;
+
+      real_retaddr = __builtin_extract_return_addr ((void *)(uintptr_t)retaddr);
+      /* If the return address is before the defering function
+	 start skip the more expensive calculations.  */
+      if ((uintptr_t)real_retaddr >= (uintptr_t)d->__defering_fn)
+	{
+	  const void *caller;
+
+	  caller = _Unwind_FindEnclosingFunction (real_retaddr);
+	  if (caller == (const void *)d->__defering_fn)
+	    return 1;
+	}
+    }
 
   /* If the function calling recover was created by reflect.MakeFunc,
      then RETADDR will be somewhere in libffi.  Our caller is
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index 4195aff..6f656d8 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -561,7 +561,7 @@ runtime_main(void* dummy __attribute__((unused)))
 	d.__next = g->defer;
 	d.__arg = (void*)-1;
 	d.__panic = g->panic;
-	d.__retaddr = nil;
+	d.__defering_fn = nil;
 	d.__makefunc_can_recover = 0;
 	d.__frame = &frame;
 	d.__special = true;
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 2/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
  2014-09-09 12:48 ` [PATCH 1/9] " Dominik Vogt
@ 2014-09-09 12:49 ` Dominik Vogt
  2014-10-09 18:56   ` [gofrontend-dev] " Ian Lance Taylor
  2014-09-09 12:51 ` [PATCH 3/9] " Dominik Vogt
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 12:49 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 285 bytes --]

A test case added to golang for the previous patch.

gcc/testsuite/ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * go.test/test/recover.go (test1): Test recover() from deferred
        recursive function.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0002-TEST-Add-a-recover-test.patch --]
[-- Type: text/x-diff, Size: 1087 bytes --]

From a3cc3d043d580d083f5dd573cb66d299cd985604 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Tue, 9 Sep 2014 09:30:09 +0100
Subject: [PATCH 2/9] TEST: Add a recover test.

---
 gcc/testsuite/go.test/test/recover.go | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/gcc/testsuite/go.test/test/recover.go b/gcc/testsuite/go.test/test/recover.go
index 071be66..b31b5ac 100644
--- a/gcc/testsuite/go.test/test/recover.go
+++ b/gcc/testsuite/go.test/test/recover.go
@@ -113,10 +113,23 @@ func withoutRecover() {
 	mustNotRecover() // because it's a sub-call
 }
 
+func withoutRecoverRecursive(n int) {
+	if (n == 0) {
+		withoutRecoverRecursive(1)
+	} else {
+		v := recover()
+		if v != nil {
+			println("spurious recover (recursive)", v)
+			die()
+		}
+	}
+}
+
 func test1() {
 	defer mustNotRecover() // because mustRecover will squelch it
 	defer mustRecover(1)   // because of panic below
 	defer withoutRecover() // should be no-op, leaving for mustRecover to find
+	defer withoutRecoverRecursive(0) // ditto
 	panic(1)
 }
 
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 3/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
  2014-09-09 12:48 ` [PATCH 1/9] " Dominik Vogt
  2014-09-09 12:49 ` [PATCH 2/9] " Dominik Vogt
@ 2014-09-09 12:51 ` Dominik Vogt
  2014-10-03 18:28   ` [gofrontend-dev] " Ian Lance Taylor
  2014-09-09 12:53 ` [PATCH 4/9] " Dominik Vogt
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 12:51 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 342 bytes --]

The current Gccgo cannot handle 64 bit symbol tables on s390[x].
The attached patch fixes that.

gcc/go/ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * gofrontend/import-archive.cc (interpret_header): Recognize 64-bit
        symbol tables ("/SYM64/         ").

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0003-GO-Recognize-64-bit-symbol-tables-with-SYM64.patch --]
[-- Type: text/x-diff, Size: 1049 bytes --]

From 1e5e9f90a690ad87a357c54f212886114e6b098e Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:30:32 +0100
Subject: [PATCH 3/9] GO: Recognize 64-bit symbol tables with /SYM64/.

---
 gcc/go/gofrontend/import-archive.cc | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/gcc/go/gofrontend/import-archive.cc b/gcc/go/gofrontend/import-archive.cc
index 34fb528..4305755 100644
--- a/gcc/go/gofrontend/import-archive.cc
+++ b/gcc/go/gofrontend/import-archive.cc
@@ -295,6 +295,15 @@ Archive_file::interpret_header(const Archive_header* hdr, off_t off,
       // This is the symbol table.
       pname->clear();
     }
+  else if (hdr->ar_name[1] == 'S' && hdr->ar_name[2] == 'Y'
+	   && hdr->ar_name[3] == 'M' && hdr->ar_name[4] == '6'
+	   && hdr->ar_name[5] == '4' && hdr->ar_name[6] == '/'
+	   && hdr->ar_name[7] == ' '
+	  )
+    {
+      // 64-bit symbol table.
+      pname->clear();
+    }
   else if (hdr->ar_name[1] == '/')
     {
       // This is the extended name table.
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 4/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
                   ` (2 preceding siblings ...)
  2014-09-09 12:51 ` [PATCH 3/9] " Dominik Vogt
@ 2014-09-09 12:53 ` Dominik Vogt
  2014-10-04  1:19   ` [gofrontend-dev] " Ian Lance Taylor
  2014-09-09 12:56 ` [PATCH 5/9] " Dominik Vogt
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 12:53 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 553 bytes --]

This patch fixes the compiler flags in libgo/mksysinfo.sh.  In one
place, some compiler flags were missing that are consistently used
elswhere, resulting in an error message.

ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * libgo/mksysinfo.sh (OUT):
        Add the same compile flags that configure uses to detect whether off64_t
        is present or not when generating the go structures for the C types.
        Otherwise the go type for off64_t may not be generated.


Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0004-LIBGO-Fix-generation-of-off64_t.patch --]
[-- Type: text/x-diff, Size: 846 bytes --]

From c22cbdd9aeaf69da3b85e2814178200f5cd6bac7 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:30:37 +0100
Subject: [PATCH 4/9] LIBGO: Fix generation of off64_t.

Use -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE as elsewhere to make sure off64_t
is generated.
---
 libgo/mksysinfo.sh | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/libgo/mksysinfo.sh b/libgo/mksysinfo.sh
index e188155..71044c1 100755
--- a/libgo/mksysinfo.sh
+++ b/libgo/mksysinfo.sh
@@ -195,7 +195,8 @@ enum {
 };
 EOF
 
-${CC} -fdump-go-spec=gen-sysinfo.go -std=gnu99 -S -o sysinfo.s sysinfo.c
+${CC} -D_GNU_SOURCE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE \
+  -fdump-go-spec=gen-sysinfo.go -std=gnu99 -S -o sysinfo.s sysinfo.c
 
 echo 'package syscall' > ${OUT}
 echo 'import "unsafe"' >> ${OUT}
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 5/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
                   ` (3 preceding siblings ...)
  2014-09-09 12:53 ` [PATCH 4/9] " Dominik Vogt
@ 2014-09-09 12:56 ` Dominik Vogt
  2014-10-04  1:26   ` [gofrontend-dev] " Ian Lance Taylor
  2014-09-09 12:58 ` [PATCH 6/9] " Dominik Vogt
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 12:56 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 505 bytes --]

This optional cleanup patch fixes some sloppy programming in the
x86 libgo/go/debug/elf library that had given me a very hard time
to debug and fix when porting the code to s390[x].  See commit
comment for details.

ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * libgo/go/debug/elf/file.go (applyRelocationsAMD64):
        Fix the calculation of some relocations; do not assume that the symbol
        value is always zero.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0005-LIBGO-Fix-some-relocations-in-libgo-elf-for-amd64.patch --]
[-- Type: text/x-diff, Size: 1349 bytes --]

From 4fce3090be0efb0160cef859e1df6e06196b24e0 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:30:48 +0100
Subject: [PATCH 5/9] LIBGO: Fix some relocations in libgo/elf for amd64.

Adding sym.Value is not really necessary on amd64 as it's always 0 there.  But
on one hand this may change in the future, breaking this code, and on the other
soemone might copy this code for a different platform where sym.Value is not 0.
---
 libgo/go/debug/elf/file.go | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/libgo/go/debug/elf/file.go b/libgo/go/debug/elf/file.go
index 38269aa..c70c7b3 100644
--- a/libgo/go/debug/elf/file.go
+++ b/libgo/go/debug/elf/file.go
@@ -562,12 +562,12 @@ func (f *File) applyRelocationsAMD64(dst []byte, rels []byte) error {
 			if rela.Off+8 >= uint64(len(dst)) || rela.Addend < 0 {
 				continue
 			}
-			f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend))
+			f.ByteOrder.PutUint64(dst[rela.Off:rela.Off+8], uint64(rela.Addend) + uint64(sym.Value))
 		case R_X86_64_32:
 			if rela.Off+4 >= uint64(len(dst)) || rela.Addend < 0 {
 				continue
 			}
-			f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend))
+			f.ByteOrder.PutUint32(dst[rela.Off:rela.Off+4], uint32(rela.Addend) + uint32(sym.Value))
 		}
 	}
 
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 6/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
                   ` (4 preceding siblings ...)
  2014-09-09 12:56 ` [PATCH 5/9] " Dominik Vogt
@ 2014-09-09 12:58 ` Dominik Vogt
  2014-10-16 22:59   ` [gofrontend-dev] " Ian Lance Taylor
  2014-09-09 13:02 ` [PATCH 7/9] " Dominik Vogt
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 12:58 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 323 bytes --]

Eases the rediculously tight minimum stack size for goprocesses on
64 bit systems.

ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * libgo/runtime/proc.c (runtime_newosproc): Set the thread stack size
        explicitly only on 32 bit systems.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0006-LIBGO-Set-a-small-default-stack-size-only-for-32-bit.patch --]
[-- Type: text/x-diff, Size: 2380 bytes --]

From a1691a4c61114124a4d41754bca5a47bf7102b71 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:30:52 +0100
Subject: [PATCH 6/9] LIBGO: Set a small default stack size only for 32 bit.

On 64 bit systems there should be plenty of space in the memory map to give
each thread the maximum possible stack size.  This is the default when unsing
glibc.
---
 libgo/runtime/proc.c | 29 ++++++++++++++++++-----------
 1 file changed, 18 insertions(+), 11 deletions(-)

diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index 6f656d8..f67849f 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -175,7 +175,6 @@ static void
 runtime_newosproc(M *mp)
 {
 	pthread_attr_t attr;
-	size_t stacksize;
 	sigset_t clear, old;
 	pthread_t tid;
 	int ret;
@@ -185,18 +184,26 @@ runtime_newosproc(M *mp)
 	if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
 		runtime_throw("pthread_attr_setdetachstate");
 
-	stacksize = PTHREAD_STACK_MIN;
+	// For 32 bit systems, start with a small stack size and rely on the
+	// split stack feature to increase the stack on demand.  This conserves
+	// the available space in the memory map.
+	if (sizeof(char *) < 8)
+	{
+		size_t stacksize;
+
+		stacksize = PTHREAD_STACK_MIN;
 
-	// With glibc before version 2.16 the static TLS size is taken
-	// out of the stack size, and we get an error or a crash if
-	// there is not enough stack space left.  Add it back in if we
-	// can, in case the program uses a lot of TLS space.  FIXME:
-	// This can be disabled in glibc 2.16 and later, if the bug is
-	// indeed fixed then.
-	stacksize += tlssize;
+		// With glibc before version 2.16 the static TLS size is taken
+		// out of the stack size, and we get an error or a crash if
+		// there is not enough stack space left.  Add it back in if we
+		// can, in case the program uses a lot of TLS space.  FIXME:
+		// This can be disabled in glibc 2.16 and later, if the bug is
+		// indeed fixed then.
+		stacksize += tlssize;
 
-	if(pthread_attr_setstacksize(&attr, stacksize) != 0)
-		runtime_throw("pthread_attr_setstacksize");
+		if(pthread_attr_setstacksize(&attr, stacksize) != 0)
+			runtime_throw("pthread_attr_setstacksize");
+	}
 
 	// Block signals during pthread_create so that the new thread
 	// starts with signals disabled.  It will enable them in minit.
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
                   ` (5 preceding siblings ...)
  2014-09-09 12:58 ` [PATCH 6/9] " Dominik Vogt
@ 2014-09-09 13:02 ` Dominik Vogt
  2014-10-16 23:46   ` [gofrontend-dev] " Ian Lance Taylor
  2014-10-29 16:43   ` Andreas Schwab
  2014-09-09 13:04 ` [PATCH 8/9] " Dominik Vogt
                   ` (2 subsequent siblings)
  9 siblings, 2 replies; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 13:02 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 1806 bytes --]

This patch extends the -fdump-go-spec option to handle bitfields
and unions and fixes handlinx of zero length arrays.  All of this
is necessary for s390[x] since the system headers use these
features.  Please check the commit comment for a detailed
description of the patch.

gcc/ChangeLog
-------------
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * godump.c (precision_to_units): New helper function.
        (go_append_artificial_name): Ditto.
        (go_append_decl_name): Ditto.
        (go_append_bitfield): Ditto.
        (go_get_uinttype_for_precision): Ditto.
        (go_append_padding): Ditto.
        (go_force_record_alignment): Ditto.
        (go_format_type): Represent unions with an array of uints of the size
        of the alignment in go.  This fixes the 'random' size of the union's
        representation using just the first field.
        (go_format_type): Add argument that indicates whether a record is
        nested (used for generation of artificial go names).
        (go_output_fndecl): Adapt to new go_format_type signature.
        (go_output_typedef): Ditto.
        (go_output_var): Ditto.
        (go_output_var): Prefer to output type as alias (typedef).
        (go_format_type): Bitfields in records are simulated as arrays of bytes
        in go.

2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * godump.c (go_format_type): Fix handling of arrays with zero elements.

gcc/testsuite/ChangeLog
-----------------------
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * gcc.misc-tests/godump-1.c: Add tests for bitfields and unions.

2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * gcc.misc-tests/godump.exp: New.
        * gcc.misc-tests/godump-1.c: New.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0007-godump-Support-bitfields-and-unions-in-go_format_typ.patch --]
[-- Type: text/x-diff, Size: 47685 bytes --]

From 01b400c36daba0ef3f96fd9d98d9becbc5b15080 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:30:56 +0100
Subject: [PATCH 7/9] godump: Support bitfields and unions in go_format_type.

1) Fix handling of arrays with zero elements.

2) Support bitfields and unions in go_format_type.

Bitfields are replaced by byte arrays with synthetic names that cover the space
occupied by the bitfield and any padding after it.

Unions are represented by a struct with a single field that has the name of the
first field of the original record (or "Godump_<n>" if the first field has no
name).  This field is a byte array with the size of the largest field of the
original union.  If alignment of the union does not match the size of the byte
array, an array of integers with the alignment of the union and zero elements is
added at the end of the record to enforce proper alignment (name
"Godump_<n>_align").

Placement of the fields of a record is derived using the internal placement
algorithm in stor.layout.c.  In some cases byte arrays of proper size are
inserted into records to get the alignment right.  Also, if the representation
of a record in Go does not have the proper alignment after all fields have been
converted to Go, an array of integers with the alignment of the recordn and
zero elements is added at the end of the record (name "Godump_<n>_align").

When translating a VAR_DECL, a type that is aliased with typedef (or a struct
or union) is used literally, if possible, and not resolved to builtin types.

Packed records are (still) not supported.

3) Add godump testsuite.
---
 gcc/godump.c                            | 356 +++++++++++++++++-------
 gcc/testsuite/gcc.misc-tests/godump-1.c | 472 ++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.misc-tests/godump.exp |  36 +++
 3 files changed, 770 insertions(+), 94 deletions(-)
 create mode 100644 gcc/testsuite/gcc.misc-tests/godump-1.c
 create mode 100644 gcc/testsuite/gcc.misc-tests/godump.exp

diff --git a/gcc/godump.c b/gcc/godump.c
index 7566f4d..4f3e69d 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "obstack.h"
 #include "debug.h"
 #include "wide-int-print.h"
+#include "stor-layout.h"
+#include "defaults.h"
 
 /* We dump this information from the debug hooks.  This gives us a
    stable and maintainable API to hook into.  In order to work
@@ -73,6 +75,14 @@ struct macro_hash_value
   char *value;
 };
 
+/* Returns the number of units necessary to represent an integer with the given
+   PRECISION (in bits).  */
+static inline unsigned int
+precision_to_units (unsigned int precision)
+{
+  return (precision + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+}
+
 /* Calculate the hash value for an entry in the macro hash table.  */
 
 static hashval_t
@@ -552,19 +562,129 @@ go_append_string (struct obstack *ob, tree id)
   obstack_grow (ob, IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
 }
 
+/* Given an integer PRECISION in bits, returns a constant string that is the
+   matching go int or uint type (depending on the IS_UNSIGNED flag).  Returns a
+   NULL pointer if there is no matching go type.  */
+static const char *
+go_get_uinttype_for_precision (unsigned int precision, bool is_unsigned)
+{
+  switch (precision)
+    {
+    case 8:
+      return (is_unsigned) ? "uint8" : "int8";
+    case 16:
+      return (is_unsigned) ? "uint16" : "int16";
+    case 32:
+      return (is_unsigned) ? "uint32" : "int32";
+    case 64:
+      return (is_unsigned) ? "uint64" : "int64";
+    default:
+      return NULL;
+    }
+}
+
+/* Append an artificial variable name with the suffix _INDEX to OB.  Returns
+   INDEX + 1.  */
+
+static unsigned int
+go_append_artificial_name (struct obstack *ob, unsigned int index)
+{
+  char buf[100];
+
+#if 1 /*!!!todo: identifier may not be unique???*/
+#endif
+  obstack_grow (ob, "Godump_", 7);
+  snprintf (buf, sizeof buf, "%u", index);
+  obstack_grow (ob, buf, strlen (buf));
+
+  return index + 1;
+}
+
+/* Append the variable name from DECL to OB.  If the name is in the
+   KEYWORD_HASH, prepend an '_'.  */
+
+static void
+go_append_decl_name (struct obstack *ob, tree decl, htab_t keyword_hash)
+{
+  const char *var_name;
+  void **slot;
+
+  /* Start variable name with an underscore if a keyword.  */
+  var_name = IDENTIFIER_POINTER (DECL_NAME (decl));
+  slot = htab_find_slot (keyword_hash, var_name, NO_INSERT);
+  if (slot != NULL)
+    obstack_1grow (ob, '_');
+  go_append_string (ob, DECL_NAME (decl));
+}
+
+/* Appends a byte array with the necessary number of elements and the name
+   "Godump_INDEX_pad" to pad from FROM_OFFSET to TO_OFFSET to OB assuming that
+   the next field is automatically aligned to ALIGN_UNITS.  Returns INDEX + 1,
+   or INDEX if no padding had to be appended.  The resulting offset where the
+   next field is allocated is returned through RET_OFFSET.  */
+
+static unsigned int
+go_append_padding (struct obstack *ob, unsigned int from_offset,
+		   unsigned int to_offset, unsigned int align_units,
+		   unsigned int index, unsigned int *ret_offset)
+{
+  if (from_offset % align_units > 0)
+    from_offset += align_units - (from_offset % align_units);
+  gcc_assert (to_offset >= from_offset);
+  if (to_offset > from_offset)
+    {
+      char buf[100];
+
+      index = go_append_artificial_name (ob, index);
+      snprintf (buf, sizeof buf, "_pad [%u]byte; ", to_offset - from_offset);
+      obstack_grow (ob, buf, strlen (buf));
+    }
+  *ret_offset = to_offset;
+
+  return index;
+}
+
+/* Appends an array of type TYPE_STRING with zero elements and the name
+   "Godump_INDEX_align" to OB.  If TYPE_STRING is a null pointer, ERROR_STRING
+   is appended instead of the type.  Returns INDEX + 1.  */
+
+static unsigned int
+go_force_record_alignment (struct obstack *ob, const char *type_string,
+			   unsigned int index, const char *error_string)
+{
+  index = go_append_artificial_name (ob, index);
+  obstack_grow (ob, "_align ", 7);
+  if (type_string == NULL)
+    {
+      obstack_grow (ob, error_string, strlen (error_string));
+    }
+  else
+    {
+      obstack_grow (ob, "[0]", 3);
+      obstack_grow (ob, type_string, strlen (type_string));
+    }
+  obstack_grow (ob, "; ", 2);
+
+  return index;
+}
+
 /* 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
-   type here; the "func" keyword will already have been added.  Return
-   true if the type can be represented in Go, false otherwise.  */
+   type here; the "func" keyword will already have been added.  If IS_NESTED is
+   true, the type is contained in a record or union.  Return true if the type
+   can be represented in Go, false otherwise.  */
 
 static bool
 go_format_type (struct godump_container *container, tree type,
-		bool use_type_name, bool is_func_ok)
+		bool use_type_name, bool is_func_ok, bool is_nested)
 {
   bool ret;
   struct obstack *ob;
+  static unsigned int art_i = 0;
 
+  if (is_nested == false)
+    art_i = 0;
   ret = true;
   ob = &container->type_obstack;
 
@@ -618,27 +738,15 @@ go_format_type (struct godump_container *container, tree type,
 	const char *s;
 	char buf[100];
 
-	switch (TYPE_PRECISION (type))
+	s = go_get_uinttype_for_precision
+	  (TYPE_PRECISION (type), TYPE_UNSIGNED (type));
+	if (s == NULL)
 	  {
-	  case 8:
-	    s = TYPE_UNSIGNED (type) ? "uint8" : "int8";
-	    break;
-	  case 16:
-	    s = TYPE_UNSIGNED (type) ? "uint16" : "int16";
-	    break;
-	  case 32:
-	    s = TYPE_UNSIGNED (type) ? "uint32" : "int32";
-	    break;
-	  case 64:
-	    s = TYPE_UNSIGNED (type) ? "uint64" : "int64";
-	    break;
-	  default:
 	    snprintf (buf, sizeof buf, "INVALID-int-%u%s",
 		      TYPE_PRECISION (type),
 		      TYPE_UNSIGNED (type) ? "u" : "");
 	    s = buf;
 	    ret = false;
-	    break;
 	  }
 	obstack_grow (ob, s, strlen (s));
       }
@@ -710,7 +818,7 @@ go_format_type (struct godump_container *container, tree type,
       else
 	{
 	  if (!go_format_type (container, TREE_TYPE (type), use_type_name,
-			       true))
+			       true, false))
 	    ret = false;
 	}
       break;
@@ -732,64 +840,60 @@ go_format_type (struct godump_container *container, tree type,
 		    tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (type))));
 	  obstack_grow (ob, buf, strlen (buf));
 	}
+      else
+	obstack_1grow (ob, '0');
       obstack_1grow (ob, ']');
-      if (!go_format_type (container, TREE_TYPE (type), use_type_name, false))
+      if (!go_format_type (container, TREE_TYPE (type), use_type_name, false,
+			   false))
 	ret = false;
       break;
 
-    case UNION_TYPE:
     case RECORD_TYPE:
       {
+	unsigned int prev_field_end;
+	unsigned int most_strict_known_alignment;
 	tree field;
-	int i;
 
+	layout_type (type);
+	prev_field_end = 0;
+	most_strict_known_alignment = 1;
 	obstack_grow (ob, "struct { ", 9);
-	i = 0;
 	for (field = TYPE_FIELDS (type);
 	     field != NULL_TREE;
 	     field = TREE_CHAIN (field))
 	  {
-	    struct obstack hold_type_obstack;
 	    bool field_ok;
 
-	    if (TREE_CODE (type) == UNION_TYPE)
-	      {
-		hold_type_obstack = container->type_obstack;
-		obstack_init (&container->type_obstack);
-	      }
-
+	    if (TREE_CODE (field) != FIELD_DECL)
+	      continue;
 	    field_ok = true;
-
-	    if (DECL_NAME (field) == NULL)
-	      {
-		char buf[100];
-
-		obstack_grow (ob, "Godump_", 7);
-		snprintf (buf, sizeof buf, "%d", i);
-		obstack_grow (ob, buf, strlen (buf));
-		i++;
-	      }
-	    else
-              {
-		const char *var_name;
-		void **slot;
-
-		/* Start variable name with an underscore if a keyword.  */
-		var_name = IDENTIFIER_POINTER (DECL_NAME (field));
-		slot = htab_find_slot (container->keyword_hash, var_name,
-				       NO_INSERT);
-		if (slot != NULL)
-		  obstack_1grow (ob, '_');
-		go_append_string (ob, DECL_NAME (field));
-	      }
-	    obstack_1grow (ob, ' ');
 	    if (DECL_BIT_FIELD (field))
-	      {
-		obstack_grow (ob, "INVALID-bit-field", 17);
-		field_ok = false;
-	      }
+	      continue;
 	    else
               {
+		{
+		  unsigned int decl_align_unit;
+		  unsigned int decl_offset;
+
+		  decl_align_unit = precision_to_units (DECL_ALIGN (field));
+		  decl_offset =
+		    TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
+		    + precision_to_units
+		    (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)));
+		  if (decl_align_unit > most_strict_known_alignment)
+		    most_strict_known_alignment = decl_align_unit;
+		  art_i = go_append_padding
+		    (ob, prev_field_end, decl_offset, decl_align_unit, art_i,
+		     &prev_field_end);
+		  if (DECL_SIZE_UNIT (field))
+		    prev_field_end += TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
+		}
+		if (DECL_NAME (field) == NULL)
+		  art_i = go_append_artificial_name (ob, art_i);
+		else
+		  go_append_decl_name (ob, field, container->keyword_hash);
+		obstack_1grow (ob, ' ');
+
 		/* Do not expand type if a record or union type or a
 		   function pointer.  */
 		if (TYPE_NAME (TREE_TYPE (field)) != NULL_TREE
@@ -815,40 +919,76 @@ go_format_type (struct godump_container *container, tree type,
 		else
 		  {
 		    if (!go_format_type (container, TREE_TYPE (field), true,
-					 false))
+					 false, true))
 		      field_ok = false;
 		  }
+		obstack_grow (ob, "; ", 2);
               }
-	    obstack_grow (ob, "; ", 2);
+	    if (!field_ok)
+	      ret = false;
+	  }
+	/* Alignment and padding as necessary.  */
+	{
+	  unsigned int type_align_unit;
+
+	  type_align_unit = precision_to_units (TYPE_ALIGN (type));
+	  /* Padding.  */
+	  art_i = go_append_padding
+	    (ob, prev_field_end, TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)),
+	     type_align_unit, art_i, &prev_field_end);
+	  if (most_strict_known_alignment < type_align_unit)
+	  {
+	    const char *s;
+	    char buf[100];
 
-	    /* Only output the first successful field of a union, and
-	       hope for the best.  */
-	    if (TREE_CODE (type) == UNION_TYPE)
+	    /* Enforce proper record alignment.  */
+	    s = go_get_uinttype_for_precision
+	      (TYPE_ALIGN (type), TYPE_UNSIGNED (type));
+	    if (s == NULL)
 	      {
-		if (!field_ok && TREE_CHAIN (field) == NULL_TREE)
-		  {
-		    field_ok = true;
-		    ret = false;
-		  }
-		if (field_ok)
-		  {
-		    unsigned int sz;
-
-		    sz = obstack_object_size (&container->type_obstack);
-		    obstack_grow (&hold_type_obstack,
-				  obstack_base (&container->type_obstack),
-				  sz);
-		  }
-		obstack_free (&container->type_obstack, NULL);
-		container->type_obstack = hold_type_obstack;
-		if (field_ok)
-		  break;
+		snprintf (buf, sizeof buf, "INVALID-int-%u%s",
+			  TYPE_ALIGN (type), TYPE_UNSIGNED (type) ? "u" : "");
+		s = buf;
+		ret = false;
 	      }
+	    art_i = go_force_record_alignment (ob, s, art_i, buf);
+	  }
+	}
+	obstack_1grow (ob, '}');
+      }
+      break;
+
+    case UNION_TYPE:
+      {
+	const char *s;
+	unsigned int sz_units;
+
+	layout_type (type);
+	sz_units = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
+	s = go_get_uinttype_for_precision (TYPE_ALIGN (type), true);
+	obstack_grow (ob, "struct { ", 9);
+	if (s == NULL)
+	  {
+	    ret = false;
+	    s = "INVALID-union-alignment";
+	    obstack_grow (ob, s, strlen (s));
+	  }
+	else
+	  {
+	    char buf[100];
+	    tree field;
+
+	    field = TYPE_FIELDS (type);
+	    /* Use the same index as the byte field's artificial name for
+	       padding.  */
+	    if (field != NULL_TREE && DECL_NAME (field) != NULL)
+	      go_append_decl_name (ob, field, container->keyword_hash);
 	    else
-	      {
-		if (!field_ok)
-		  ret = false;
-	      }
+	      art_i = go_append_artificial_name (ob, art_i);
+	    obstack_grow (ob, " [", 2);
+	    snprintf (buf, sizeof buf, "%u", sz_units);
+	    obstack_grow (ob, buf, strlen (buf));
+	    obstack_grow (ob, "]byte; ", 7);
 	  }
 	obstack_1grow (ob, '}');
       }
@@ -879,7 +1019,7 @@ go_format_type (struct godump_container *container, tree type,
 	      break;
 	    if (seen_arg)
 	      obstack_grow (ob, ", ", 2);
-	    if (!go_format_type (container, arg_type, true, false))
+	    if (!go_format_type (container, arg_type, true, false, false))
 	      ret = false;
 	    seen_arg = true;
 	  }
@@ -895,7 +1035,8 @@ go_format_type (struct godump_container *container, tree type,
 	if (!VOID_TYPE_P (result))
 	  {
 	    obstack_1grow (ob, ' ');
-	    if (!go_format_type (container, result, use_type_name, false))
+	    if (!go_format_type (container, result, use_type_name, false,
+				 false))
 	      ret = false;
 	  }
       }
@@ -929,7 +1070,7 @@ go_output_type (struct godump_container *container)
 static void
 go_output_fndecl (struct godump_container *container, tree decl)
 {
-  if (!go_format_type (container, TREE_TYPE (decl), false, true))
+  if (!go_format_type (container, TREE_TYPE (decl), false, true, false))
     fprintf (go_dump_file, "// ");
   fprintf (go_dump_file, "func _%s ",
 	   IDENTIFIER_POINTER (DECL_NAME (decl)));
@@ -1004,7 +1145,7 @@ go_output_typedef (struct godump_container *container, tree decl)
 	return;
       *slot = CONST_CAST (void *, (const void *) type);
 
-      if (!go_format_type (container, TREE_TYPE (decl), false, false))
+      if (!go_format_type (container, TREE_TYPE (decl), false, false, false))
 	{
 	  fprintf (go_dump_file, "// ");
 	  slot = htab_find_slot (container->invalid_hash, type, INSERT);
@@ -1040,7 +1181,7 @@ go_output_typedef (struct godump_container *container, tree decl)
          return;
        *slot = CONST_CAST (void *, (const void *) type);
 
-       if (!go_format_type (container, TREE_TYPE (decl), false, false))
+       if (!go_format_type (container, TREE_TYPE (decl), false, false, false))
 	 {
 	   fprintf (go_dump_file, "// ");
 	   slot = htab_find_slot (container->invalid_hash, type, INSERT);
@@ -1069,6 +1210,8 @@ static void
 go_output_var (struct godump_container *container, tree decl)
 {
   bool is_valid;
+  tree type_name;
+  tree id;
 
   if (container->decls_seen.contains (decl)
       || container->decls_seen.contains (DECL_NAME (decl)))
@@ -1076,7 +1219,34 @@ go_output_var (struct godump_container *container, tree decl)
   container->decls_seen.add (decl);
   container->decls_seen.add (DECL_NAME (decl));
 
-  is_valid = go_format_type (container, TREE_TYPE (decl), true, false);
+  type_name = TYPE_NAME (TREE_TYPE (decl));
+  id = NULL_TREE;
+  if (type_name != NULL_TREE && TREE_CODE (type_name) == IDENTIFIER_NODE)
+    id = type_name;
+  else if (type_name != NULL_TREE && TREE_CODE (type_name) == TYPE_DECL
+	   && DECL_SOURCE_LOCATION (type_name) != BUILTINS_LOCATION
+	   && DECL_NAME (type_name))
+    id = DECL_NAME (type_name);
+  if (id != NULL_TREE &&
+      (  !htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
+			  NO_INSERT)
+       || htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (id),
+			  NO_INSERT)))
+    {
+      id = NULL_TREE;
+    }
+  if (id != NULL_TREE)
+    {
+      struct obstack *ob;
+
+      ob = &container->type_obstack;
+      obstack_1grow (ob, '_');
+      go_append_string (ob, id);
+      is_valid = htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
+				 NO_INSERT) != NULL;
+    }
+  else
+    is_valid = go_format_type (container, TREE_TYPE (decl), true, false, false);
   if (is_valid
       && htab_find_slot (container->type_hash,
 			 IDENTIFIER_POINTER (DECL_NAME (decl)),
@@ -1096,10 +1266,8 @@ go_output_var (struct godump_container *container, tree decl)
 
   /* Sometimes an extern variable is declared with an unknown struct
      type.  */
-  if (TYPE_NAME (TREE_TYPE (decl)) != NULL_TREE
-      && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
+  if (type_name != NULL_TREE && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
     {
-      tree type_name = TYPE_NAME (TREE_TYPE (decl));
       if (TREE_CODE (type_name) == IDENTIFIER_NODE)
 	container->pot_dummy_types.add (IDENTIFIER_POINTER (type_name));
       else if (TREE_CODE (type_name) == TYPE_DECL)
diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c b/gcc/testsuite/gcc.misc-tests/godump-1.c
new file mode 100644
index 0000000..2a8a0fd
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -0,0 +1,472 @@
+/* Test -fdump-go-specs option.  */
+
+/* { dg-options "-c -fdump-go-spec=godump-1.out" } */
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+/* integer based types */
+typedef char c_t;
+char c_v1;
+c_t c_v2;
+typedef short s_t;
+short s_v1;
+s_t s_v2;
+typedef int i_t;
+int i_v1;
+i_t i_v2;
+typedef long l_t;
+long l_v1;
+l_t l_v2;
+typedef long long ll_t;
+long long ll_v1;
+ll_t ll_v2;
+typedef unsigned char uc_t;
+unsigned char uc_v1;
+uc_t uc_v2;
+typedef unsigned short us_t;
+unsigned short us_v1;
+us_t us_v2;
+typedef unsigned int ui_t;
+unsigned int ui_v1;
+ui_t ui_v2;
+typedef unsigned long ul_t;
+unsigned long ul_v1;
+ul_t ul_v2;
+typedef unsigned long long ull_t;
+unsigned long long ull_v1;
+ull_t ull_v2;
+typedef signed char sc_t;
+signed char sc_v1;
+sc_t sc_v2;
+typedef signed short ss_t;
+signed short ss_v1;
+ss_t ss_v2;
+typedef signed int si_t;
+signed int si_v1;
+si_t si_v2;
+typedef signed long sl_t;
+signed long sl_v1;
+sl_t sl_v2;
+typedef signed long long sll_t;
+signed long long sll_v1;
+sll_t sll_v2;
+typedef int8_t i8_t;
+int8_t i8_v1;
+i8_t i8_v2;
+typedef int16_t i16_t;
+int16_t i16_v1;
+i16_t i16_v2;
+typedef int32_t i32_t;
+int32_t i32_v1;
+i32_t i32_v2;
+typedef int64_t i64_t;
+int64_t i64_v1;
+i64_t i64_v2;
+typedef uint8_t ui8_t;
+uint8_t ui8_v1;
+ui8_t ui8_v2;
+typedef uint16_t iu16_t;
+uint16_t iu16_v1;
+iu16_t iu16_v2;
+typedef uint32_t iu32_t;
+uint32_t iu32_v1;
+iu32_t iu32_v2;
+typedef uint64_t iu64_t;
+uint64_t iu64_v1;
+iu64_t iu64_v2;
+typedef const char cc_t;
+const char cc_v1;
+cc_t cc_v2;
+
+/* pointer and array types */
+typedef void *vp_t;
+void *vp_v1;
+vp_t vp_v2;
+typedef int **ipp_t;
+int **ipp_v1;
+ipp_t ipp_v2;
+typedef char ca_t[];
+char ca_v1[]; /* { dg-warning "array 'ca_v1' assumed to have one element" } */
+char ca_v1b[2];
+ca_t ca_v2; /* { dg-warning "array 'ca_v2' assumed to have one element" } */
+typedef short sa2_t[2];
+short sa2_v1[2];
+sa2_t sa2_v2;
+
+/* floating point types */
+typedef float f_t;
+float f_v1;
+f_t f_v2;
+typedef double d_t;
+double d_v1;
+d_t d_v2;
+typedef long double ld_t;
+long double ld_v1;
+ld_t ld_v2;
+
+/* nested typedefs */
+typedef int ni_t;
+typedef ni_t ni2_t;
+ni2_t ni2_v2;
+typedef ni2_t ni3_t;
+ni3_t ni3_v2;
+
+/* enums */
+enum { E11 };
+enum { EV11 } e1_v1;
+enum { E21, E22 };
+enum { EV21, EV22 } e2_v1;
+enum { EN1 = 3, EN2 = 77, EN3 = -1, EN4 };
+typedef enum { ET1, ET2 } et_t;
+enum { ETV1, ETV2 } et_v1;
+et_t et_v2;
+
+/* simple structs */
+typedef struct { } ts0e;
+struct { } s0e;
+typedef struct { int8_t e1; } ts1e;
+struct { int8_t e1; } s1e;
+typedef struct { int8_t e1; void *e2; } ts2el;
+struct { int8_t e1; void *e2; } s2el;
+typedef struct { void *e1; int8_t e2; } ts2eg;
+struct { void *e1; int8_t e2; } s2eg;
+typedef struct { int64_t l; int8_t c; int32_t i; int16_t s; } tsme;
+struct { int64_t l; int8_t c; int32_t i; int16_t s; } sme;
+typedef struct { int16_t sa[3]; int8_t ca[3]; } tsae;
+struct { int16_t sa[3]; int8_t ca[3]; } sae;
+typedef struct { float f; } tsf_equiv;
+struct { float f; } sf_equiv;
+typedef struct { float f; uint8_t : 0; } tsf_not_equiv;
+struct { float f; uint8_t : 0; } sf_not_equiv;
+typedef struct { double d; } tsd_equiv;
+struct { double d; } sd_equiv;
+typedef struct { double d; uint8_t : 0; } tsd_not_equiv;
+struct { double d; uint8_t : 0; } sd_not_equiv;
+
+/* nested structs */
+typedef struct { struct { uint8_t ca[3]; } s; uint32_t i; } tsn;
+struct { struct { uint8_t ca[3]; } s; uint32_t i; } sn;
+typedef struct { struct { uint8_t a; uint16_t s; }; uint8_t b; } tsn_anon;
+struct { struct { uint8_t a; uint16_t s; }; uint8_t b; } sn_anon;
+
+/* structs with bitfields */
+typedef struct { uint8_t : 0; uint8_t c; } tsbf_anon_pad1;
+struct { uint8_t : 0; uint8_t c; } sbf_anon_pad1;
+typedef struct { uint8_t : 1; uint8_t c; } tsbf_anon_pad2;
+struct { uint8_t : 1; uint8_t c; } sbf_anon_pad2;
+typedef struct { uint8_t : 7; uint8_t c; } tsbf_anon_pad3;
+struct { uint8_t : 7; uint8_t c; } sbf_anon_pad3;
+typedef struct { uint8_t : 8; uint8_t c; } tsbf_anon_pad4;
+struct { uint8_t : 8; uint8_t c; } sbf_anon_pad4;
+typedef struct { uint64_t : 0; uint8_t c; } tsbf_anon_pad5;
+struct { uint64_t : 0; uint8_t c; } sbf_anon_pad5;
+typedef struct { uint64_t : 1; uint8_t c; } tsbf_anon_pad6;
+struct { uint64_t : 1; uint8_t c; } sbf_anon_pad6;
+typedef struct { uint64_t : 63; uint8_t c; } tsbf_anon_pad7;
+struct { uint64_t : 63; uint8_t c; } sbf_anon_pad7;
+typedef struct { uint64_t : 64; uint8_t c; } tsbf_anon_pad8;
+struct { uint64_t : 64; uint8_t c; } sbf_anon_pad8;
+typedef struct { uint8_t bf : 1; uint8_t c; } tsbf_pad8_1;
+struct { uint8_t bf : 1; uint8_t c; } sbf_pad8_1;
+typedef struct { uint8_t bf : 7; uint8_t c; } tsbf_pad8_2;
+struct { uint8_t bf : 7; uint8_t c; } sbf_pad8_2;
+typedef struct { uint8_t bf : 8; uint8_t c; } tsbf_pad8_3;
+struct { uint8_t bf : 8; uint8_t c; } sbf_pad8_3;
+typedef struct { uint16_t bf : 1; uint8_t c; } tsbf_pad16_1;
+struct { uint16_t bf : 1; uint8_t c; } sbf_pad16_1;
+typedef struct { uint16_t bf : 15; uint8_t c; } tsbf_pad16_2;
+struct { uint16_t bf : 15; uint8_t c; } sbf_pad16_2;
+typedef struct { uint16_t bf : 16; uint8_t c; } tsbf_pad16_3;
+struct { uint16_t bf : 16; uint8_t c; } sbf_pad16_3;
+typedef struct { uint32_t bf : 1; uint8_t c; } tsbf_pad32_1;
+struct { uint32_t bf : 1; uint8_t c; } sbf_pad32_1;
+typedef struct { uint32_t bf : 31; uint8_t c; } tsbf_pad32_2;
+struct { uint32_t bf : 31; uint8_t c; } sbf_pad32_2;
+typedef struct { uint32_t bf : 32; uint8_t c; } tsbf_pad32_3;
+struct { uint32_t bf : 32; uint8_t c; } sbf_pad32_3;
+typedef struct { uint64_t bf : 1; uint8_t c; } tsbf_pad64_1;
+struct { uint64_t bf : 1; uint8_t c; } sbf_pad64_1;
+typedef struct { uint64_t bf : 63; uint8_t c; } tsbf_pad64_2;
+struct { uint64_t bf : 63; uint8_t c; } sbf_pad64_2;
+typedef struct { uint64_t bf : 64; uint8_t c; } tsbf_pad64_3;
+struct { uint64_t bf : 64; uint8_t c; } sbf_pad64_3;
+typedef struct { uint8_t b1 : 1; } tsbf_1b;
+struct { uint8_t b1 : 1; } sbf_1b;
+typedef struct
+{
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+} tsbf_8b;
+struct
+{
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+} sbf_8b;
+typedef struct {
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+  uint8_t b9 : 1;
+} tsbf_9b;
+struct {
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+  uint8_t b9 : 1;
+} sbf_9b;
+typedef struct {
+  uint8_t b1 : 7; uint8_t b2 : 7; uint8_t b3 : 2;
+} tsbf_18b;
+struct {
+  uint8_t b1 : 7; uint8_t b2 : 7; uint8_t b3 : 2;
+} sbf_18b;
+struct
+{
+  uint16_t bf1 : 8;
+  uint8_t c;
+  uint16_t bf2 : 8;
+  uint32_t bf3 : 12;
+  uint16_t s;
+} sbf_gaps;
+typedef struct
+{
+  uint16_t bf1 : 8;
+  uint8_t c;
+  uint16_t bf2 : 8;
+  uint32_t bf3 : 12;
+  uint16_t s;
+} tsbf_gaps;
+
+/* unions */
+typedef union { } tue;
+union { } ue;
+typedef union { uint8_t c; uint64_t l; } tu1;
+union { uint8_t c; uint64_t l; } u1;
+typedef union { uint64_t l; uint8_t c; } tu2;
+union { uint64_t l; uint8_t c; } u2;
+typedef struct { union { uint8_t c; uint64_t l; }; } tsu_anon;
+struct { union { uint8_t c; uint64_t l; }; } su_anon;
+typedef union { uint64_t bf : 1; uint8_t ca[5]; } tu_size;
+union { uint64_t bf : 1; uint8_t ca[5]; } u_size;
+typedef union { uint64_t : 1; uint8_t ca[5]; } tu2_size;
+union { uint64_t : 1; uint8_t ca[5]; } u2_size;
+
+/* functions */
+extern uint32_t func1(uint8_t c);
+typedef int8_t (*func_t)(void *p);
+
+/* Necessary quoting in the regexp patters:
+
+     (?n) at beginning of pattern to make ^ and $ work.
+     "     ->  \"
+     *, +  ->  "*", "+"
+     [, ]  ->  "\[", "\]"
+     (, )  ->  "\[(\]", "\[)\]"
+     {, }  ->  "\{", "\}"
+*/
+
+/* { dg-final { scan-file godump-1.out "(?n)^type _c_t u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _s_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _l_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ll_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _uc_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _us_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ui_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ul_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ull_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sc_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ss_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _si_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sl_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sll_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i8_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i16_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i32_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i64_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ui8_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu16_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu32_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu64_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _cc_t u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _vp_t \\*byte$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ipp_t \\*\\*int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ca_t \\\[0\\\]uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sa2_t \\\[1\\+1\\\]int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _f_t float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _d_t float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// type _ld_t INVALID-float-128$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni2_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni3_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _et_t int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts0e struct \{ \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts1e struct \{ e1 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts2el struct \{ e1 int\[0-9\]*; e2 \\*byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts2eg struct \{ e1 \\*byte; e2 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsme struct \{ l int\[0-9\]*; c int\[0-9\]*; i int\[0-9\]*; s int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsae struct \{ sa \\\[2\\+1\\\]int\[0-9\]*; ca \\\[2\\+1\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsf_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsf_not_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsd_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsd_not_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsn struct \{ s struct \{ ca \\\[2\\+1\\\]uint\[0-9\]*; \}; i uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsn_anon struct \{ Godump_0 struct \{ a uint\[0-9\]*; s uint\[0-9\]*; \}; b uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad1 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad3 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad4 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad5 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad6 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad7 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad8 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_2 struct \{ Godump_0_pad \\\[2\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_2 struct \{ Godump_0_pad \\\[4\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_2 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_1b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_8b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_9b struct \{ Godump_0_pad \\\[2\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_18b struct \{ Godump_0_pad \\\[3\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_gaps struct \{ bf1 uint\[0-9\]*; c uint\[0-9\]*; bf2 uint\[0-9\]*; Godump_0_pad \\\[2\\\]byte; s uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tue struct \{ Godump_0 \\\[0\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu1 struct \{ c \\\[8\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu2 struct \{ l \\\[8\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsu_anon struct \{ Godump_0 struct \{ c \\\[8\\\]byte; \}; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu_size struct \{ bf \\\[8\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu2_size struct \{ Godump_0 \\\[5\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _func_t func\[(\]\\*byte\[)\] int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _c_v1 u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _c_v2 _c_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s_v2 _s_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i_v2 _i_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _l_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _l_v2 _l_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ll_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ll_v2 _ll_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _uc_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _uc_v2 _uc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _us_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _us_v2 _us_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui_v2 _ui_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ul_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ul_v2 _ul_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ull_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ull_v2 _ull_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sc_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sc_v2 _sc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ss_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ss_v2 _ss_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _si_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _si_v2 _si_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sl_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sl_v2 _sl_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sll_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sll_v2 _sll_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i8_v1 _int8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i8_v2 _i8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i16_v1 _int16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i16_v2 _i16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i32_v1 _int32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i32_v2 _i32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i64_v1 _int64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i64_v2 _i64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui8_v1 _uint8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui8_v2 _ui8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu16_v1 _uint16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu16_v2 _iu16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu32_v1 _uint32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu32_v2 _iu32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu64_v1 _uint64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu64_v2 _iu64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cc_v1 u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cc_v2 _cc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _vp_v1 \\*byte$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _vp_v2 _vp_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ipp_v1 \\*\\*int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ipp_v2 _ipp_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v1 \\\[0\\+1\\\]uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v1b \\\[1\\+1\\\]uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v2 \\\[0\\+1\\\]uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sa2_v1 \\\[1\\+1\\\]int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sa2_v2 _sa2_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _f_v1 float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _f_v2 _f_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _d_v1 float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _d_v2 _d_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v1 INVALID-float-128$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v2 INVALID-float-128$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ni2_v2 _ni2_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ni3_v2 _ni3_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _e1_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _e2_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _et_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _et_v2 _et_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s0e struct \{ \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s1e struct \{ e1 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s2el struct \{ e1 int\[0-9\]*; e2 \\*byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s2eg struct \{ e1 \\*byte; e2 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sme struct \{ l int\[0-9\]*; c int\[0-9\]*; i int\[0-9\]*; s int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sae struct \{ sa \\\[2\\+1\\\]int\[0-9\]*; ca \\\[2\\+1\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sf_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sf_not_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sd_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sd_not_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sn struct \{ s struct \{ ca \\\[2\\+1\\\]uint\[0-9\]*; \}; i uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sn_anon struct \{ Godump_0 struct \{ a uint\[0-9\]*; s uint\[0-9\]*; \}; b uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad1 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad3 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad4 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad5 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad6 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad7 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad8 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_2 struct \{ Godump_0_pad \\\[2\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_2 struct \{ Godump_0_pad \\\[4\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_2 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_1b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_8b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_9b struct \{ Godump_0_pad \\\[2\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_18b struct \{ Godump_0_pad \\\[3\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_gaps struct \{ bf1 uint\[0-9\]*; c uint\[0-9\]*; bf2 uint\[0-9\]*; Godump_0_pad \\\[2\\\]byte; s uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ue struct \{ Godump_0 \\\[0\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u1 struct \{ c \\\[8\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u2 struct \{ l \\\[8\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _su_anon struct \{ Godump_0 struct \{ c \\\[8\\\]byte; \}; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u_size struct \{ bf \\\[8\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u2_size struct \{ Godump_0 \\\[5\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^func _func1 \[(\]uint\[0-9\]*\[)\] uint\[0-9\]* __asm__\[(\]\"func1\"\[)\]$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E11 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E21 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E22 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN1 = 3$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN2 = 77$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN3 = -1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN4 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ET1 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ET2 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ETV1 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ETV2 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV11 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV21 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV22 = 1$" } } */
diff --git a/gcc/testsuite/gcc.misc-tests/godump.exp b/gcc/testsuite/gcc.misc-tests/godump.exp
new file mode 100644
index 0000000..96812c4
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/godump.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/godump-*.c]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 8/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
                   ` (6 preceding siblings ...)
  2014-09-09 13:02 ` [PATCH 7/9] " Dominik Vogt
@ 2014-09-09 13:04 ` Dominik Vogt
  2014-10-17  0:03   ` [gofrontend-dev] " Ian Lance Taylor
  2014-09-09 13:06 ` [PATCH 9/9] " Dominik Vogt
  2014-10-17  0:45 ` [gofrontend-dev] [PATCH 0/9] " Ian Lance Taylor
  9 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 13:04 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 586 bytes --]

This is an optional extension of the -fgo-dump-spec option to
handle copmplex data types.  It is not necessary for s390[x] but
was easy to write on top of the previous patch.

gcc/ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * godump.c (go_format_type): Represent "float _Complex" and
        "double _Complex" as complex64 or complex128 in Go, as appropriate.

gcc/testsuite/ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * gcc.misc-tests/godump-1.c: Add tests for complex types.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0008-godump-Support-_Complex-types-in-go_format_type.patch --]
[-- Type: text/x-diff, Size: 4471 bytes --]

From 3eb21882fc7848eefb9c14cfbb0b4c69f8851ad3 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:31:01 +0100
Subject: [PATCH 8/9] godump: Support _Complex types in go_format_type.

1) float/double _Complex are represented as complex64/complex128 in Go as
appropriate.

2) Add tests.
---
 gcc/godump.c                            | 34 +++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.misc-tests/godump-1.c | 30 +++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)

diff --git a/gcc/godump.c b/gcc/godump.c
index 4f3e69d..6b39eba 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -776,6 +776,40 @@ go_format_type (struct godump_container *container, tree type,
       }
       break;
 
+    case COMPLEX_TYPE:
+      {
+	const char *s;
+	char buf[100];
+	tree real_type;
+
+	real_type = TREE_TYPE (type);
+	if (TREE_CODE (real_type) == REAL_TYPE)
+	  {
+	    switch (TYPE_PRECISION (real_type))
+	      {
+	      case 32:
+		s = "complex64";
+		break;
+	      case 64:
+		s = "complex128";
+		break;
+	      default:
+		snprintf (buf, sizeof buf, "INVALID-complex-%u",
+			  2 * TYPE_PRECISION (real_type));
+		s = buf;
+		ret = false;
+		break;
+	      }
+	  }
+	else
+	  {
+	    s = "INVALID-complex-non-real";
+	    ret = false;
+	  }
+	obstack_grow (ob, s, strlen (s));
+      }
+      break;
+
     case BOOLEAN_TYPE:
       obstack_grow (ob, "bool", 4);
       break;
diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c b/gcc/testsuite/gcc.misc-tests/godump-1.c
index 2a8a0fd..c6a3ca5 100644
--- a/gcc/testsuite/gcc.misc-tests/godump-1.c
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -104,6 +104,21 @@ d_t d_v2;
 typedef long double ld_t;
 long double ld_v1;
 ld_t ld_v2;
+typedef _Complex cx_t;
+_Complex cx_v1;
+cx_t cx_v2;
+typedef float _Complex fcx_t;
+float _Complex fcx_v1;
+fcx_t fcx_v2;
+typedef double _Complex dcx_t;
+double _Complex dcx_v1;
+dcx_t dcx_v2;
+typedef long double _Complex ldcx_t;
+long double _Complex ldcx_v1;
+ldcx_t ldcx_v2;
+typedef int _Complex icx_t;
+int _Complex icx_v1;
+icx_t icx_v2;
 
 /* nested typedefs */
 typedef int ni_t;
@@ -295,6 +310,11 @@ typedef int8_t (*func_t)(void *p);
 /* { dg-final { scan-file godump-1.out "(?n)^type _f_t float\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^type _d_t float\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^// type _ld_t INVALID-float-128$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _cx_t complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _fcx_t complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _dcx_t complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// type _ldcx_t INVALID-complex-256$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// type _icx_t INVALID-complex-non-real$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^type _ni_t int\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^type _ni2_t int\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^type _ni3_t int\[0-9\]*$" } } */
@@ -406,6 +426,16 @@ typedef int8_t (*func_t)(void *p);
 /* { dg-final { scan-file godump-1.out "(?n)^var _d_v2 _d_t$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v1 INVALID-float-128$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v2 INVALID-float-128$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cx_v1 complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cx_v2 _cx_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _fcx_v1 complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _fcx_v2 _fcx_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _dcx_v1 complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _dcx_v2 _dcx_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ldcx_v1 INVALID-complex-256$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ldcx_v2 INVALID-complex-256$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _icx_v1 INVALID-complex-non-real$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _icx_v2 INVALID-complex-non-real$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^var _ni2_v2 _ni2_t$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^var _ni3_v2 _ni3_t$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^var _e1_v1 int$" } } */
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 9/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
                   ` (7 preceding siblings ...)
  2014-09-09 13:04 ` [PATCH 8/9] " Dominik Vogt
@ 2014-09-09 13:06 ` Dominik Vogt
  2014-10-17  0:07   ` [gofrontend-dev] " Ian Lance Taylor
  2014-10-17  0:45 ` [gofrontend-dev] [PATCH 0/9] " Ian Lance Taylor
  9 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-09-09 13:06 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 508 bytes --]

Quote shell variables that may contain whitespace in the configure
file.  I cannot remember exactly whether I actually ran into a
problem, but the patch won't hurt anyway.

ChangeLog
2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * libgo/configure.ac (GO_SYSCALL_OS_ARCH_FILE): Use double quotes around
        path names.
        (GO_SYSCALL_OS_FILE): Ditto.
        (GO_LIBCALL_OS_ARCH_FILE): Ditto.
        (GO_LIBCALL_OS_FILE): Ditto.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0009-LIBGO-Fix-handling-of-path-names-with-whitespace.patch --]
[-- Type: text/x-diff, Size: 3062 bytes --]

From 11938b5b3303b5b8df8914d59dcceea38c0a0a0c Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:31:05 +0100
Subject: [PATCH 9/9] LIBGO: Fix handling of path names with whitespace.

Paths and filenames need to be quoted in case they contain whitespace or other
dangerous characters.
---
 libgo/configure    | 16 ++++++++--------
 libgo/configure.ac | 16 ++++++++--------
 2 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/libgo/configure b/libgo/configure
index 08ddb18..53202e4 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -13886,17 +13886,17 @@ GO_LIBCALL_OS_FILE=
 GO_LIBCALL_OS_ARCH_FILE=
 GO_SYSCALL_OS_FILE=
 GO_SYSCALL_OS_ARCH_FILE=
-if test -f ${srcdir}/go/syscall/libcall_${GOOS}.go; then
-  GO_LIBCALL_OS_FILE=go/syscall/libcall_${GOOS}.go
+if test -f "${srcdir}/go/syscall/libcall_${GOOS}.go"; then
+  GO_LIBCALL_OS_FILE="go/syscall/libcall_${GOOS}.go"
 fi
-if test -f ${srcdir}/go/syscall/libcall_${GOOS}_${GOARCH}.go; then
-  GO_LIBCALL_OS_ARCH_FILE=go/syscall/libcall_${GOOS}_${GOARCH}.go
+if test -f "${srcdir}/go/syscall/libcall_${GOOS}_${GOARCH}.go"; then
+  GO_LIBCALL_OS_ARCH_FILE="go/syscall/libcall_${GOOS}_${GOARCH}.go"
 fi
-if test -f ${srcdir}/go/syscall/syscall_${GOOS}.go; then
-  GO_SYSCALL_OS_FILE=go/syscall/syscall_${GOOS}.go
+if test -f "${srcdir}/go/syscall/syscall_${GOOS}.go"; then
+  GO_SYSCALL_OS_FILE="go/syscall/syscall_${GOOS}.go"
 fi
-if test -f ${srcdir}/go/syscall/syscall_${GOOS}_${GOARCH}.go; then
-  GO_SYSCALL_OS_ARCH_FILE=go/syscall/syscall_${GOOS}_${GOARCH}.go
+if test -f "${srcdir}/go/syscall/syscall_${GOOS}_${GOARCH}.go"; then
+  GO_SYSCALL_OS_ARCH_FILE="go/syscall/syscall_${GOOS}_${GOARCH}.go"
 fi
 
 
diff --git a/libgo/configure.ac b/libgo/configure.ac
index 5e1e4d9..d29db0c 100644
--- a/libgo/configure.ac
+++ b/libgo/configure.ac
@@ -306,17 +306,17 @@ GO_LIBCALL_OS_FILE=
 GO_LIBCALL_OS_ARCH_FILE=
 GO_SYSCALL_OS_FILE=
 GO_SYSCALL_OS_ARCH_FILE=
-if test -f ${srcdir}/go/syscall/libcall_${GOOS}.go; then
-  GO_LIBCALL_OS_FILE=go/syscall/libcall_${GOOS}.go
+if test -f "${srcdir}/go/syscall/libcall_${GOOS}.go"; then
+  GO_LIBCALL_OS_FILE="go/syscall/libcall_${GOOS}.go"
 fi
-if test -f ${srcdir}/go/syscall/libcall_${GOOS}_${GOARCH}.go; then
-  GO_LIBCALL_OS_ARCH_FILE=go/syscall/libcall_${GOOS}_${GOARCH}.go
+if test -f "${srcdir}/go/syscall/libcall_${GOOS}_${GOARCH}.go"; then
+  GO_LIBCALL_OS_ARCH_FILE="go/syscall/libcall_${GOOS}_${GOARCH}.go"
 fi
-if test -f ${srcdir}/go/syscall/syscall_${GOOS}.go; then
-  GO_SYSCALL_OS_FILE=go/syscall/syscall_${GOOS}.go
+if test -f "${srcdir}/go/syscall/syscall_${GOOS}.go"; then
+  GO_SYSCALL_OS_FILE="go/syscall/syscall_${GOOS}.go"
 fi
-if test -f ${srcdir}/go/syscall/syscall_${GOOS}_${GOARCH}.go; then
-  GO_SYSCALL_OS_ARCH_FILE=go/syscall/syscall_${GOOS}_${GOARCH}.go
+if test -f "${srcdir}/go/syscall/syscall_${GOOS}_${GOARCH}.go"; then
+  GO_SYSCALL_OS_ARCH_FILE="go/syscall/syscall_${GOOS}_${GOARCH}.go"
 fi
 AC_SUBST(GO_LIBCALL_OS_FILE)
 AC_SUBST(GO_LIBCALL_OS_ARCH_FILE)
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 3/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:51 ` [PATCH 3/9] " Dominik Vogt
@ 2014-10-03 18:28   ` Ian Lance Taylor
  0 siblings, 0 replies; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-03 18:28 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 5:51 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> The current Gccgo cannot handle 64 bit symbol tables on s390[x].
> The attached patch fixes that.
>
> gcc/go/ChangeLog
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * gofrontend/import-archive.cc (interpret_header): Recognize 64-bit
>         symbol tables ("/SYM64/         ").

Thanks.  Committed.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 4/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:53 ` [PATCH 4/9] " Dominik Vogt
@ 2014-10-04  1:19   ` Ian Lance Taylor
  2014-10-06  6:52     ` Dominik Vogt
  0 siblings, 1 reply; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-04  1:19 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 5:53 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
>
> This patch fixes the compiler flags in libgo/mksysinfo.sh.  In one
> place, some compiler flags were missing that are consistently used
> elswhere, resulting in an error message.
>
> ChangeLog
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * libgo/mksysinfo.sh (OUT):
>         Add the same compile flags that configure uses to detect whether off64_t
>         is present or not when generating the go structures for the C types.
>         Otherwise the go type for off64_t may not be generated.

I don't understand why this patch is necessary.  The invocation of
mksysinfo in libgo/Makefile.am sets the CC environment variable to
include $(OSCFLAGS), and OSCFLAGS should include those three options.

Trying to list the flags separately in mksysinfo.sh is going to be
incomplete on some systems--see OSCFLAGS in libgo/configure.ac.

Can you explain further why this patch is required?  Thanks.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 5/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:56 ` [PATCH 5/9] " Dominik Vogt
@ 2014-10-04  1:26   ` Ian Lance Taylor
  2014-10-06  7:42     ` Dominik Vogt
  0 siblings, 1 reply; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-04  1:26 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 5:56 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> This optional cleanup patch fixes some sloppy programming in the
> x86 libgo/go/debug/elf library that had given me a very hard time
> to debug and fix when porting the code to s390[x].  See commit
> comment for details.
>
> ChangeLog
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * libgo/go/debug/elf/file.go (applyRelocationsAMD64):
>         Fix the calculation of some relocations; do not assume that the symbol
>         value is always zero.

The code checks that it is using only STT_SECTION symbols.  An
STT_SECTION symbol in an object file can be reasonably expected to
have a value of zero.  Since in practice this only applies to debug
sections, I doubt it would work at all if the STT_SECTION symbol had a
non-zero value and that value were added in.  So I'm not convinced
that this patch is necessary.

I'm sorry that the code gave you a hard time, but as far as I can see
it's not sloppy and it's not wrong.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 4/9] Gccgo port to s390[x] -- part I
  2014-10-04  1:19   ` [gofrontend-dev] " Ian Lance Taylor
@ 2014-10-06  6:52     ` Dominik Vogt
  0 siblings, 0 replies; 38+ messages in thread
From: Dominik Vogt @ 2014-10-06  6:52 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev

On Fri, Oct 03, 2014 at 06:19:46PM -0700, Ian Lance Taylor wrote:
> On Tue, Sep 9, 2014 at 5:53 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> > This patch fixes the compiler flags in libgo/mksysinfo.sh.  In one
> > place, some compiler flags were missing that are consistently used
> > elswhere, resulting in an error message.
> >
> > ChangeLog
> > 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
> >
> >         * libgo/mksysinfo.sh (OUT):
> >         Add the same compile flags that configure uses to detect whether off64_t
> >         is present or not when generating the go structures for the C types.
> >         Otherwise the go type for off64_t may not be generated.
> 
> I don't understand why this patch is necessary.  The invocation of
> mksysinfo in libgo/Makefile.am sets the CC environment variable to
> include $(OSCFLAGS), and OSCFLAGS should include those three options.
> 
> Trying to list the flags separately in mksysinfo.sh is going to be
> incomplete on some systems--see OSCFLAGS in libgo/configure.ac.

With gcc-4.8 compilation failed on s390 (i.e. 31 bit) without it.
It seems that this patch is no longer necessary with gcc-5.0, so
it can be dropped.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 5/9] Gccgo port to s390[x] -- part I
  2014-10-04  1:26   ` [gofrontend-dev] " Ian Lance Taylor
@ 2014-10-06  7:42     ` Dominik Vogt
  2014-10-06 14:29       ` Ian Lance Taylor
  0 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-10-06  7:42 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev

On Fri, Oct 03, 2014 at 06:25:55PM -0700, Ian Lance Taylor wrote:
> On Tue, Sep 9, 2014 at 5:56 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> >         * libgo/go/debug/elf/file.go (applyRelocationsAMD64):
> >         Fix the calculation of some relocations; do not assume that the symbol
> >         value is always zero.
> 
> The code checks that it is using only STT_SECTION symbols.  An
> STT_SECTION symbol in an object file can be reasonably expected to
> have a value of zero.  Since in practice this only applies to debug
> sections, I doubt it would work at all if the STT_SECTION symbol had a
> non-zero value and that value were added in.  So I'm not convinced
> that this patch is necessary.

Well, my x86 knowledge is limited, and the patch is neither
required for the s390[x] port nor (at the moment) for x64_64.

On s390[x] the symbol value of a section symbol is definitely not
zero.  In the amd64 Abi I cannot see anything that would enforce
that sym.Value is 0 for section symbols, although it seems to be
the case on the tested x86_64 system.  In any case, if the patch
is not committed, we should at least add a comment that the symbol
value is omitted from the calculation because it is assumed to be
zero.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 5/9] Gccgo port to s390[x] -- part I
  2014-10-06  7:42     ` Dominik Vogt
@ 2014-10-06 14:29       ` Ian Lance Taylor
  2014-10-07 10:45         ` Dominik Vogt
  0 siblings, 1 reply; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-06 14:29 UTC (permalink / raw)
  To: vogt, Ian Lance Taylor, gcc-patches, gofrontend-dev

On Mon, Oct 6, 2014 at 12:42 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
>
> On s390[x] the symbol value of a section symbol is definitely not
> zero.

Is true even in an object file?  I agree that in an executable a
section symbol will have a non-zero value, but that case doesn't arise
since an executable won't have (non-dynamic) relocations.  But I'm
quite surprised that hear that the section symbol would be non-zero in
an object file.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 5/9] Gccgo port to s390[x] -- part I
  2014-10-06 14:29       ` Ian Lance Taylor
@ 2014-10-07 10:45         ` Dominik Vogt
  2014-10-09 20:07           ` Ian Lance Taylor
  0 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-10-07 10:45 UTC (permalink / raw)
  To: Ian Lance Taylor; +Cc: gcc-patches, gofrontend-dev

On Mon, Oct 06, 2014 at 07:29:33AM -0700, Ian Lance Taylor wrote:
> On Mon, Oct 6, 2014 at 12:42 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> > On s390[x] the symbol value of a section symbol is definitely not
> > zero.
> 
> Is true even in an object file?

No.

> I agree that in an executable a
> section symbol will have a non-zero value, but that case doesn't arise
> since an executable won't have (non-dynamic) relocations.  But I'm
> quite surprised that hear that the section symbol would be non-zero in
> an object file.

I spent a day looking at that issue again, and while it's true
that section symbols don't necessarily have a zero value, that is
not the problem here.  The problem is about how cgo determines the
names of functions(?) from an object file.  On s390 we need to do
an indirect lookup of (non-section-)symbols to find the names, and
the symbol value is not zero.

The only points in that patch are that on one hand - as far as I
know - the Abi does not guarantee that section symbols are either
zero or not relocated, even if that may be the case in reality.
And on the other hand, if that code is ever modified to handle
non-section symbols, it's not obvious that you not only need to
remove the test for the symbol type but also modify the
calculations below.  So, apply the patch or drop it as you like,
but in any case, at least a comment in the code would improve
maintainability.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 2/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:49 ` [PATCH 2/9] " Dominik Vogt
@ 2014-10-09 18:56   ` Ian Lance Taylor
  0 siblings, 0 replies; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-09 18:56 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 5:49 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> A test case added to golang for the previous patch.
>
> gcc/testsuite/ChangeLog
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * go.test/test/recover.go (test1): Test recover() from deferred
>         recursive function.

Proposed for master testsuite as
http://codereview.appspot.com/151630043 .  I also included your later
test from PR 60406.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 5/9] Gccgo port to s390[x] -- part I
  2014-10-07 10:45         ` Dominik Vogt
@ 2014-10-09 20:07           ` Ian Lance Taylor
  0 siblings, 0 replies; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-09 20:07 UTC (permalink / raw)
  To: vogt, Ian Lance Taylor, gcc-patches, gofrontend-dev

On Tue, Oct 7, 2014 at 3:45 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
>
> The only points in that patch are that on one hand - as far as I
> know - the Abi does not guarantee that section symbols are either
> zero or not relocated, even if that may be the case in reality.
> And on the other hand, if that code is ever modified to handle
> non-section symbols, it's not obvious that you not only need to
> remove the test for the symbol type but also modify the
> calculations below.  So, apply the patch or drop it as you like,
> but in any case, at least a comment in the code would improve
> maintainability.

I proposed this patch for the master repository:

https://codereview.appspot.com/155190043

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 6/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:58 ` [PATCH 6/9] " Dominik Vogt
@ 2014-10-16 22:59   ` Ian Lance Taylor
  0 siblings, 0 replies; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-16 22:59 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 5:58 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> Eases the rediculously tight minimum stack size for goprocesses on
> 64 bit systems.
>
> ChangeLog
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * libgo/runtime/proc.c (runtime_newosproc): Set the thread stack size
>         explicitly only on 32 bit systems.

Thanks.  I think this whole idea was misguided, and was a leftover
from the time when gccgo put each goroutine on a separate thread.  Now
that goroutines are multiplexed onto threads, there aren't all that
many threads, and there is no particular reason to force them to have
small stacks.  We want goroutines to have small stacks, on systems
that support splitting that stack, but the goroutine stack is not the
thread stack.  The gc toolchain also does not put a limit on thread
stack size.

This patch simply removes the limit on thread stack size.
Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian


diff -r 4185806dae27 libgo/runtime/proc.c
--- a/libgo/runtime/proc.c	Thu Oct 16 12:54:41 2014 -0700
+++ b/libgo/runtime/proc.c	Thu Oct 16 15:17:39 2014 -0700
@@ -167,15 +167,11 @@
 	g = gp;
 }

-// The static TLS size.  See runtime_newm.
-static int tlssize;
-
 // Start a new thread.
 static void
 runtime_newosproc(M *mp)
 {
 	pthread_attr_t attr;
-	size_t stacksize;
 	sigset_t clear, old;
 	pthread_t tid;
 	int ret;
@@ -185,19 +181,6 @@
 	if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
 		runtime_throw("pthread_attr_setdetachstate");

-	stacksize = PTHREAD_STACK_MIN;
-
-	// With glibc before version 2.16 the static TLS size is taken
-	// out of the stack size, and we get an error or a crash if
-	// there is not enough stack space left.  Add it back in if we
-	// can, in case the program uses a lot of TLS space.  FIXME:
-	// This can be disabled in glibc 2.16 and later, if the bug is
-	// indeed fixed then.
-	stacksize += tlssize;
-
-	if(pthread_attr_setstacksize(&attr, stacksize) != 0)
-		runtime_throw("pthread_attr_setstacksize");
-
 	// Block signals during pthread_create so that the new thread
 	// starts with signals disabled.  It will enable them in minit.
 	sigfillset(&clear);
@@ -306,43 +289,6 @@
 	}
 }

-#ifdef HAVE_DL_ITERATE_PHDR
-
-// Called via dl_iterate_phdr.
-
-static int
-addtls(struct dl_phdr_info* info, size_t size __attribute__
((unused)), void *data)
-{
-	size_t *total = (size_t *)data;
-	unsigned int i;
-
-	for(i = 0; i < info->dlpi_phnum; ++i) {
-		if(info->dlpi_phdr[i].p_type == PT_TLS)
-			*total += info->dlpi_phdr[i].p_memsz;
-	}
-	return 0;
-}
-
-// Set the total TLS size.
-
-static void
-inittlssize()
-{
-	size_t total = 0;
-
-	dl_iterate_phdr(addtls, (void *)&total);
-	tlssize = total;
-}
-
-#else
-
-static void
-inittlssize()
-{
-}
-
-#endif
-
 // Goroutine scheduler
 // The scheduler's job is to distribute ready-to-run goroutines over
worker threads.
 //
@@ -481,7 +427,6 @@
 	g->m = m;

 	initcontext();
-	inittlssize();

 	runtime_sched.maxmcount = 10000;
 	runtime_precisestack = 0;

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-09-09 13:02 ` [PATCH 7/9] " Dominik Vogt
@ 2014-10-16 23:46   ` Ian Lance Taylor
  2014-10-28 14:40     ` Dominik Vogt
  2014-10-29 16:43   ` Andreas Schwab
  1 sibling, 1 reply; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-16 23:46 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 6:02 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:

> This patch extends the -fdump-go-spec option to handle bitfields
> and unions and fixes handlinx of zero length arrays.  All of this
> is necessary for s390[x] since the system headers use these
> features.  Please check the commit comment for a detailed
> description of the patch.
>
> gcc/ChangeLog
> -------------
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * godump.c (precision_to_units): New helper function.
>         (go_append_artificial_name): Ditto.
>         (go_append_decl_name): Ditto.
>         (go_append_bitfield): Ditto.
>         (go_get_uinttype_for_precision): Ditto.
>         (go_append_padding): Ditto.
>         (go_force_record_alignment): Ditto.
>         (go_format_type): Represent unions with an array of uints of the size
>         of the alignment in go.  This fixes the 'random' size of the union's
>         representation using just the first field.
>         (go_format_type): Add argument that indicates whether a record is
>         nested (used for generation of artificial go names).
>         (go_output_fndecl): Adapt to new go_format_type signature.
>         (go_output_typedef): Ditto.
>         (go_output_var): Ditto.
>         (go_output_var): Prefer to output type as alias (typedef).
>         (go_format_type): Bitfields in records are simulated as arrays of bytes
>         in go.
>
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * godump.c (go_format_type): Fix handling of arrays with zero elements.
>
> gcc/testsuite/ChangeLog
> -----------------------
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * gcc.misc-tests/godump-1.c: Add tests for bitfields and unions.
>
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * gcc.misc-tests/godump.exp: New.
>         * gcc.misc-tests/godump-1.c: New.


> +    case 8:
> +      return (is_unsigned) ? "uint8" : "int8";

No need to parenthesize is_unsigned here and in the following lines.

> +#if 1 /*!!!todo: identifier may not be unique???*/
> +#endif

I'm not sure what the #if 1 is about.  Just put a FIXME comment--see
other examples in the code base.


> +  static unsigned int art_i = 0;
>
> +  if (is_nested == false)
> +    art_i = 0;

Don't use a static variable.  Instead, pass down an int*.  It can be
NULL for the case where !is_nested.  (Also, in code like this, write
!is_nested rather than is_nested == false).


> +	layout_type (type);

Is this really necessary?  At this point the types should be laid out
already.


+		  decl_align_unit = precision_to_units (DECL_ALIGN (field));

You can just use DECL_ALIGN_UNIT.

> +	  type_align_unit = precision_to_units (TYPE_ALIGN (type));

You can just use TYPE_ALIGN_UNIT.


> +	    snprintf (buf, sizeof buf, "%u", sz_units);

This doesn't look right--shouldn't it be
    sz_units / TYPE_ALIGN_UNITS (type)
?  Using sz_units only looks right if go_get_uinttype_for_precision
returns byte.

> +      (  !htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),

Don't use these leading spaces after parens, just let emacs format
your code even if looks awkward.


Thanks.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 8/9] Gccgo port to s390[x] -- part I
  2014-09-09 13:04 ` [PATCH 8/9] " Dominik Vogt
@ 2014-10-17  0:03   ` Ian Lance Taylor
  2014-10-29  9:13     ` Dominik Vogt
  0 siblings, 1 reply; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-17  0:03 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 6:04 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> This is an optional extension of the -fgo-dump-spec option to
> handle copmplex data types.  It is not necessary for s390[x] but
> was easy to write on top of the previous patch.
>
> gcc/ChangeLog
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * godump.c (go_format_type): Represent "float _Complex" and
>         "double _Complex" as complex64 or complex128 in Go, as appropriate.
>
> gcc/testsuite/ChangeLog
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * gcc.misc-tests/godump-1.c: Add tests for complex types.

This is OK.

Thanks.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 9/9] Gccgo port to s390[x] -- part I
  2014-09-09 13:06 ` [PATCH 9/9] " Dominik Vogt
@ 2014-10-17  0:07   ` Ian Lance Taylor
  0 siblings, 0 replies; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-17  0:07 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 6:06 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
>
> Quote shell variables that may contain whitespace in the configure
> file.  I cannot remember exactly whether I actually ran into a
> problem, but the patch won't hurt anyway.
>
> ChangeLog
> 2014-09-05  Dominik Vogt  <vogt@linux.vnet.ibm.com>
>
>         * libgo/configure.ac (GO_SYSCALL_OS_ARCH_FILE): Use double quotes around
>         path names.
>         (GO_SYSCALL_OS_FILE): Ditto.
>         (GO_LIBCALL_OS_ARCH_FILE): Ditto.
>         (GO_LIBCALL_OS_FILE): Ditto.

Thanks.  Committed.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 0/9] Gccgo port to s390[x] -- part I
  2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
                   ` (8 preceding siblings ...)
  2014-09-09 13:06 ` [PATCH 9/9] " Dominik Vogt
@ 2014-10-17  0:45 ` Ian Lance Taylor
  9 siblings, 0 replies; 38+ messages in thread
From: Ian Lance Taylor @ 2014-10-17  0:45 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Tue, Sep 9, 2014 at 5:44 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
>
> The following series' of patches introduce s390[x] support for
> Gccgo.  For practical reasons they will be submitted in separate
> parts.  This is the first part of the submissions with
> architecture independent bug fixes and enhancements that affect
> the following directories:
>
>   gcc                           (Gcc)
>   gcc/testsuite/gcc.misc-tests  (Gcc)
>   gcc/go/gofrontend             (gofrontend)
>   gcc/testsuite/go.test         (golang)
>   libgo                         (Gcc?)
>   libgo/go                      (gofrontend)
>   libgo/runtime                 (gofrontend)
>
> It seemed infeasible to split this patch series and send the
> patches only to the "right" places.  The following s390[x] patch
> series' depend on all of them.
>
> Summary of this series:
>
> 0001: Fix for bug #60406. (gofrontend)
> 0002: Test case for 0001. (golang)
> 0003: Bug fix for opening s390 libs. (gofrontend)
> 0004: Libgo compile fix. (gofrontend)
> 0005: Cleanup of x86 relocations in libgo. (gofrontend, optional)
> 0006: Fix in libgo/runtime/proc.c (Gcc?)
> 0007: Extend -fdump-go-spec (bitfields, unions and a bugfix) (Gcc)
> 0008: Extend -fdump-go-spec (complex types) (Gcc, optional)
> 0009: Fix handling of whitespace in configure script. (Gcc?)

I think I've now replied to all the patches in this series.

Thanks very much for sending them.

It looks like you sent these messages by replying to earlier messages.
Next time I encourage you not to do that, as it puts all the messages,
and the replies to them, into a single thread in a threaded e-mail
reader.  That makes it hard to separate out the discussion about the
individual separate patches.  Better to send each patch as a separate
new e-mail message, not a reply, to start a new thread for each one.
Thanks.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-16 23:46   ` [gofrontend-dev] " Ian Lance Taylor
@ 2014-10-28 14:40     ` Dominik Vogt
  2014-10-28 17:37       ` Ian Taylor
  0 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-10-28 14:40 UTC (permalink / raw)
  To: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 2362 bytes --]

On Thu, Oct 16, 2014 at 04:45:03PM -0700, Ian Lance Taylor wrote:
> On Tue, Sep 9, 2014 at 6:02 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> > +    case 8:
> > +      return (is_unsigned) ? "uint8" : "int8";
> 
> No need to parenthesize is_unsigned here and in the following lines.

That's just my way of coding.  I always put conditions into
parentheses, but I don't care whether they are removed here.

> > +#if 1 /*!!!todo: identifier may not be unique???*/
> > +#endif
> 
> I'm not sure what the #if 1 is about.  Just put a FIXME comment--see
> other examples in the code base.

That's an accident.

> > +  static unsigned int art_i = 0;
> >
> > +  if (is_nested == false)
> > +    art_i = 0;
> 
> Don't use a static variable.  Instead, pass down an int*.  It can be
> NULL for the case where !is_nested.

Done.

>  (Also, in code like this, write
> !is_nested rather than is_nested == false).

Okay.

> > +	layout_type (type);
> Is this really necessary?

It seems so.  Without it, -fdump-go-specs triggers a core dump when
processing the s390x headers.  A file like this generates the core:

  typedef struct S T;

> +		  decl_align_unit = precision_to_units (DECL_ALIGN (field));
> You can just use DECL_ALIGN_UNIT.
> > +	  type_align_unit = precision_to_units (TYPE_ALIGN (type));
> You can just use TYPE_ALIGN_UNIT.

Okay.

> > +	    snprintf (buf, sizeof buf, "%u", sz_units);
> 
> This doesn't look right--shouldn't it be
>     sz_units / TYPE_ALIGN_UNITS (type)
> ?  Using sz_units only looks right if go_get_uinttype_for_precision
> returns byte.

The generated size is correct because sz_units is always in bytes,
and the code generates a *byte* array.  However, the alignment may
be wrong.  Given a C union

  union { uint8_t c; uint64_t ll; } u;

with size 8 and alignment 8, the generated Go struct is

  _u struct { c [8]byte; }

The alignment of this struct is 1 and the size is 8.  I've added an
alignment field at the end of the struct like this:

  _u struct { c [8]byte; Godump_<n>_align [0]uint64; }

and added more tests.

> > +      (  !htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
> 
> Don't use these leading spaces after parens, just let emacs format
> your code even if looks awkward.

Okay.

--

The attached patch contains all the discussed changes.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0001-godump-Support-bitfields-and-unions-in-go_format_typ.patch --]
[-- Type: text/x-diff, Size: 48980 bytes --]

From 5e1556d67febf91e066953a7c795f7855b8f841e Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:30:56 +0100
Subject: [PATCH] godump: Support bitfields and unions in go_format_type.

1) Fix handling of arrays with zero elements.

2) Support bitfields and unions in go_format_type.

Bitfields are replaced by byte arrays with synthetic names that cover the space
occupied by the bitfield and any padding after it.

Unions are represented by a struct with a single field that has the name of the
first field of the original record (or "Godump_<n>" if the first field has no
name).  This field is a byte array with the size of the largest field of the
original union.  If alignment of the union does not match the size of the byte
array, an array of integers with the alignment of the union and zero elements is
added at the end of the record to enforce proper alignment (name
"Godump_<n>_align").

Placement of the fields of a record is derived using the internal placement
algorithm in stor.layout.c.  In some cases byte arrays of proper size are
inserted into records to get the alignment right.  Also, if the representation
of a record in Go does not have the proper alignment after all fields have been
converted to Go, an array of integers with the alignment of the recordn and
zero elements is added at the end of the record (name "Godump_<n>_align").

When translating a VAR_DECL, a type that is aliased with typedef (or a struct
or union) is used literally, if possible, and not resolved to builtin types.

Packed records are (still) not supported.

3) Add godump testsuite.
---
 gcc/godump.c                            | 361 +++++++++++++++++-------
 gcc/testsuite/gcc.misc-tests/godump-1.c | 482 ++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.misc-tests/godump.exp |  36 +++
 3 files changed, 785 insertions(+), 94 deletions(-)
 create mode 100644 gcc/testsuite/gcc.misc-tests/godump-1.c
 create mode 100644 gcc/testsuite/gcc.misc-tests/godump.exp

diff --git a/gcc/godump.c b/gcc/godump.c
index 7566f4d..a124291 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "obstack.h"
 #include "debug.h"
 #include "wide-int-print.h"
+#include "stor-layout.h"
+#include "defaults.h"
 
 /* We dump this information from the debug hooks.  This gives us a
    stable and maintainable API to hook into.  In order to work
@@ -73,6 +75,14 @@ struct macro_hash_value
   char *value;
 };
 
+/* Returns the number of units necessary to represent an integer with the given
+   PRECISION (in bits).  */
+static inline unsigned int
+precision_to_units (unsigned int precision)
+{
+  return (precision + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+}
+
 /* Calculate the hash value for an entry in the macro hash table.  */
 
 static hashval_t
@@ -552,19 +562,135 @@ go_append_string (struct obstack *ob, tree id)
   obstack_grow (ob, IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
 }
 
+/* Given an integer PRECISION in bits, returns a constant string that is the
+   matching go int or uint type (depending on the IS_UNSIGNED flag).  Returns a
+   NULL pointer if there is no matching go type.  */
+static const char *
+go_get_uinttype_for_precision (unsigned int precision, bool is_unsigned)
+{
+  switch (precision)
+    {
+    case 8:
+      return is_unsigned ? "uint8" : "int8";
+    case 16:
+      return is_unsigned ? "uint16" : "int16";
+    case 32:
+      return is_unsigned ? "uint32" : "int32";
+    case 64:
+      return is_unsigned ? "uint64" : "int64";
+    default:
+      return NULL;
+    }
+}
+
+/* Append an artificial variable name with the suffix _INDEX to OB.  Returns
+   INDEX + 1.  */
+
+static unsigned int
+go_append_artificial_name (struct obstack *ob, unsigned int index)
+{
+  char buf[100];
+
+  /*FIXME: identifier may not be unique */
+  obstack_grow (ob, "Godump_", 7);
+  snprintf (buf, sizeof buf, "%u", index);
+  obstack_grow (ob, buf, strlen (buf));
+
+  return index + 1;
+}
+
+/* Append the variable name from DECL to OB.  If the name is in the
+   KEYWORD_HASH, prepend an '_'.  */
+
+static void
+go_append_decl_name (struct obstack *ob, tree decl, htab_t keyword_hash)
+{
+  const char *var_name;
+  void **slot;
+
+  /* Start variable name with an underscore if a keyword.  */
+  var_name = IDENTIFIER_POINTER (DECL_NAME (decl));
+  slot = htab_find_slot (keyword_hash, var_name, NO_INSERT);
+  if (slot != NULL)
+    obstack_1grow (ob, '_');
+  go_append_string (ob, DECL_NAME (decl));
+}
+
+/* Appends a byte array with the necessary number of elements and the name
+   "Godump_INDEX_pad" to pad from FROM_OFFSET to TO_OFFSET to OB assuming that
+   the next field is automatically aligned to ALIGN_UNITS.  Returns INDEX + 1,
+   or INDEX if no padding had to be appended.  The resulting offset where the
+   next field is allocated is returned through RET_OFFSET.  */
+
+static unsigned int
+go_append_padding (struct obstack *ob, unsigned int from_offset,
+		   unsigned int to_offset, unsigned int align_units,
+		   unsigned int index, unsigned int *ret_offset)
+{
+  if (from_offset % align_units > 0)
+    from_offset += align_units - (from_offset % align_units);
+  gcc_assert (to_offset >= from_offset);
+  if (to_offset > from_offset)
+    {
+      char buf[100];
+
+      index = go_append_artificial_name (ob, index);
+      snprintf (buf, sizeof buf, "_pad [%u]byte; ", to_offset - from_offset);
+      obstack_grow (ob, buf, strlen (buf));
+    }
+  *ret_offset = to_offset;
+
+  return index;
+}
+
+/* Appends an array of type TYPE_STRING with zero elements and the name
+   "Godump_INDEX_align" to OB.  If TYPE_STRING is a null pointer, ERROR_STRING
+   is appended instead of the type.  Returns INDEX + 1.  */
+
+static unsigned int
+go_force_record_alignment (struct obstack *ob, const char *type_string,
+			   unsigned int index, const char *error_string)
+{
+  index = go_append_artificial_name (ob, index);
+  obstack_grow (ob, "_align ", 7);
+  if (type_string == NULL)
+    {
+      obstack_grow (ob, error_string, strlen (error_string));
+    }
+  else
+    {
+      obstack_grow (ob, "[0]", 3);
+      obstack_grow (ob, type_string, strlen (type_string));
+    }
+  obstack_grow (ob, "; ", 2);
+
+  return index;
+}
+
 /* 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
-   type here; the "func" keyword will already have been added.  Return
-   true if the type can be represented in Go, false otherwise.  */
+   type here; the "func" keyword will already have been added.  If IS_NESTED is
+   true, the type is contained in a record or union.  Return true if the type
+   can be represented in Go, false otherwise.
+   P_ART_I is used for indexing artificial elements in nested structures and
+   should always be a NULL pointer when called, except by certain recursive
+   calls from go_format_type() itself.
+*/
 
 static bool
 go_format_type (struct godump_container *container, tree type,
-		bool use_type_name, bool is_func_ok)
+		bool use_type_name, bool is_func_ok, unsigned int *p_art_i)
 {
   bool ret;
   struct obstack *ob;
+  unsigned int art_i_dummy;
 
+  if (p_art_i == NULL)
+    {
+      art_i_dummy = 0;
+      p_art_i = &art_i_dummy;
+    }
   ret = true;
   ob = &container->type_obstack;
 
@@ -618,27 +744,15 @@ go_format_type (struct godump_container *container, tree type,
 	const char *s;
 	char buf[100];
 
-	switch (TYPE_PRECISION (type))
+	s = go_get_uinttype_for_precision
+	  (TYPE_PRECISION (type), TYPE_UNSIGNED (type));
+	if (s == NULL)
 	  {
-	  case 8:
-	    s = TYPE_UNSIGNED (type) ? "uint8" : "int8";
-	    break;
-	  case 16:
-	    s = TYPE_UNSIGNED (type) ? "uint16" : "int16";
-	    break;
-	  case 32:
-	    s = TYPE_UNSIGNED (type) ? "uint32" : "int32";
-	    break;
-	  case 64:
-	    s = TYPE_UNSIGNED (type) ? "uint64" : "int64";
-	    break;
-	  default:
 	    snprintf (buf, sizeof buf, "INVALID-int-%u%s",
 		      TYPE_PRECISION (type),
 		      TYPE_UNSIGNED (type) ? "u" : "");
 	    s = buf;
 	    ret = false;
-	    break;
 	  }
 	obstack_grow (ob, s, strlen (s));
       }
@@ -710,7 +824,7 @@ go_format_type (struct godump_container *container, tree type,
       else
 	{
 	  if (!go_format_type (container, TREE_TYPE (type), use_type_name,
-			       true))
+			       true, NULL))
 	    ret = false;
 	}
       break;
@@ -732,64 +846,60 @@ go_format_type (struct godump_container *container, tree type,
 		    tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (type))));
 	  obstack_grow (ob, buf, strlen (buf));
 	}
+      else
+	obstack_1grow (ob, '0');
       obstack_1grow (ob, ']');
-      if (!go_format_type (container, TREE_TYPE (type), use_type_name, false))
+      if (!go_format_type (container, TREE_TYPE (type), use_type_name, false,
+			   NULL))
 	ret = false;
       break;
 
-    case UNION_TYPE:
     case RECORD_TYPE:
       {
+	unsigned int prev_field_end;
+	unsigned int most_strict_known_alignment;
 	tree field;
-	int i;
 
+	layout_type (type);
+	prev_field_end = 0;
+	most_strict_known_alignment = 1;
 	obstack_grow (ob, "struct { ", 9);
-	i = 0;
 	for (field = TYPE_FIELDS (type);
 	     field != NULL_TREE;
 	     field = TREE_CHAIN (field))
 	  {
-	    struct obstack hold_type_obstack;
 	    bool field_ok;
 
-	    if (TREE_CODE (type) == UNION_TYPE)
-	      {
-		hold_type_obstack = container->type_obstack;
-		obstack_init (&container->type_obstack);
-	      }
-
+	    if (TREE_CODE (field) != FIELD_DECL)
+	      continue;
 	    field_ok = true;
-
-	    if (DECL_NAME (field) == NULL)
-	      {
-		char buf[100];
-
-		obstack_grow (ob, "Godump_", 7);
-		snprintf (buf, sizeof buf, "%d", i);
-		obstack_grow (ob, buf, strlen (buf));
-		i++;
-	      }
-	    else
-              {
-		const char *var_name;
-		void **slot;
-
-		/* Start variable name with an underscore if a keyword.  */
-		var_name = IDENTIFIER_POINTER (DECL_NAME (field));
-		slot = htab_find_slot (container->keyword_hash, var_name,
-				       NO_INSERT);
-		if (slot != NULL)
-		  obstack_1grow (ob, '_');
-		go_append_string (ob, DECL_NAME (field));
-	      }
-	    obstack_1grow (ob, ' ');
 	    if (DECL_BIT_FIELD (field))
-	      {
-		obstack_grow (ob, "INVALID-bit-field", 17);
-		field_ok = false;
-	      }
+	      continue;
 	    else
               {
+		{
+		  unsigned int decl_align_unit;
+		  unsigned int decl_offset;
+
+		  decl_align_unit = DECL_ALIGN_UNIT (field);
+		  decl_offset =
+		    TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
+		    + precision_to_units
+		    (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)));
+		  if (decl_align_unit > most_strict_known_alignment)
+		    most_strict_known_alignment = decl_align_unit;
+		  *p_art_i = go_append_padding
+		    (ob, prev_field_end, decl_offset, decl_align_unit, *p_art_i,
+		     &prev_field_end);
+		  if (DECL_SIZE_UNIT (field))
+		    prev_field_end += TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
+		}
+		if (DECL_NAME (field) == NULL)
+		  *p_art_i = go_append_artificial_name (ob, *p_art_i);
+		else
+		  go_append_decl_name (ob, field, container->keyword_hash);
+		obstack_1grow (ob, ' ');
+
 		/* Do not expand type if a record or union type or a
 		   function pointer.  */
 		if (TYPE_NAME (TREE_TYPE (field)) != NULL_TREE
@@ -815,40 +925,76 @@ go_format_type (struct godump_container *container, tree type,
 		else
 		  {
 		    if (!go_format_type (container, TREE_TYPE (field), true,
-					 false))
+					 false, p_art_i))
 		      field_ok = false;
 		  }
+		obstack_grow (ob, "; ", 2);
               }
-	    obstack_grow (ob, "; ", 2);
+	    if (!field_ok)
+	      ret = false;
+	  }
+	/* Alignment and padding as necessary.  */
+	{
+	  unsigned int type_align_unit;
+
+	  type_align_unit = TYPE_ALIGN_UNIT (type);
+	  /* Padding.  */
+	  *p_art_i = go_append_padding
+	    (ob, prev_field_end, TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)),
+	     type_align_unit, *p_art_i, &prev_field_end);
+	  if (most_strict_known_alignment < type_align_unit)
+	  {
+	    const char *s;
+	    char buf[100];
 
-	    /* Only output the first successful field of a union, and
-	       hope for the best.  */
-	    if (TREE_CODE (type) == UNION_TYPE)
+	    /* Enforce proper record alignment.  */
+	    s = go_get_uinttype_for_precision
+	      (TYPE_ALIGN (type), TYPE_UNSIGNED (type));
+	    if (s == NULL)
 	      {
-		if (!field_ok && TREE_CHAIN (field) == NULL_TREE)
-		  {
-		    field_ok = true;
-		    ret = false;
-		  }
-		if (field_ok)
-		  {
-		    unsigned int sz;
-
-		    sz = obstack_object_size (&container->type_obstack);
-		    obstack_grow (&hold_type_obstack,
-				  obstack_base (&container->type_obstack),
-				  sz);
-		  }
-		obstack_free (&container->type_obstack, NULL);
-		container->type_obstack = hold_type_obstack;
-		if (field_ok)
-		  break;
+		snprintf (buf, sizeof buf, "INVALID-int-%u%s",
+			  TYPE_ALIGN (type), TYPE_UNSIGNED (type) ? "u" : "");
+		s = buf;
+		ret = false;
 	      }
+	    *p_art_i = go_force_record_alignment (ob, s, *p_art_i, buf);
+	  }
+	}
+	obstack_1grow (ob, '}');
+      }
+      break;
+
+    case UNION_TYPE:
+      {
+	const char *s;
+	unsigned int sz_units;
+
+	layout_type (type);
+	sz_units = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
+	s = go_get_uinttype_for_precision (TYPE_ALIGN (type), true);
+	obstack_grow (ob, "struct { ", 9);
+	if (s == NULL)
+	  {
+	    ret = false;
+	    s = "INVALID-union-alignment";
+	    obstack_grow (ob, s, strlen (s));
+	  }
+	else
+	  {
+	    char buf[100];
+	    tree field;
+
+	    field = TYPE_FIELDS (type);
+	    /* Use the same index as the byte field's artificial name for
+	       padding.  */
+	    if (field != NULL_TREE && DECL_NAME (field) != NULL)
+	      go_append_decl_name (ob, field, container->keyword_hash);
 	    else
-	      {
-		if (!field_ok)
-		  ret = false;
-	      }
+	      *p_art_i = go_append_artificial_name (ob, *p_art_i);
+	    snprintf (buf, sizeof buf, " [%u]byte; ", sz_units);
+	    obstack_grow (ob, buf, strlen (buf));
+	    if (TYPE_ALIGN_UNIT (type) > 1)
+	      *p_art_i = go_force_record_alignment (ob, s, *p_art_i, NULL);
 	  }
 	obstack_1grow (ob, '}');
       }
@@ -879,7 +1025,7 @@ go_format_type (struct godump_container *container, tree type,
 	      break;
 	    if (seen_arg)
 	      obstack_grow (ob, ", ", 2);
-	    if (!go_format_type (container, arg_type, true, false))
+	    if (!go_format_type (container, arg_type, true, false, NULL))
 	      ret = false;
 	    seen_arg = true;
 	  }
@@ -895,7 +1041,7 @@ go_format_type (struct godump_container *container, tree type,
 	if (!VOID_TYPE_P (result))
 	  {
 	    obstack_1grow (ob, ' ');
-	    if (!go_format_type (container, result, use_type_name, false))
+	    if (!go_format_type (container, result, use_type_name, false, NULL))
 	      ret = false;
 	  }
       }
@@ -929,7 +1075,7 @@ go_output_type (struct godump_container *container)
 static void
 go_output_fndecl (struct godump_container *container, tree decl)
 {
-  if (!go_format_type (container, TREE_TYPE (decl), false, true))
+  if (!go_format_type (container, TREE_TYPE (decl), false, true, NULL))
     fprintf (go_dump_file, "// ");
   fprintf (go_dump_file, "func _%s ",
 	   IDENTIFIER_POINTER (DECL_NAME (decl)));
@@ -1004,7 +1150,7 @@ go_output_typedef (struct godump_container *container, tree decl)
 	return;
       *slot = CONST_CAST (void *, (const void *) type);
 
-      if (!go_format_type (container, TREE_TYPE (decl), false, false))
+      if (!go_format_type (container, TREE_TYPE (decl), false, false, NULL))
 	{
 	  fprintf (go_dump_file, "// ");
 	  slot = htab_find_slot (container->invalid_hash, type, INSERT);
@@ -1040,7 +1186,7 @@ go_output_typedef (struct godump_container *container, tree decl)
          return;
        *slot = CONST_CAST (void *, (const void *) type);
 
-       if (!go_format_type (container, TREE_TYPE (decl), false, false))
+       if (!go_format_type (container, TREE_TYPE (decl), false, false, NULL))
 	 {
 	   fprintf (go_dump_file, "// ");
 	   slot = htab_find_slot (container->invalid_hash, type, INSERT);
@@ -1069,6 +1215,8 @@ static void
 go_output_var (struct godump_container *container, tree decl)
 {
   bool is_valid;
+  tree type_name;
+  tree id;
 
   if (container->decls_seen.contains (decl)
       || container->decls_seen.contains (DECL_NAME (decl)))
@@ -1076,7 +1224,34 @@ go_output_var (struct godump_container *container, tree decl)
   container->decls_seen.add (decl);
   container->decls_seen.add (DECL_NAME (decl));
 
-  is_valid = go_format_type (container, TREE_TYPE (decl), true, false);
+  type_name = TYPE_NAME (TREE_TYPE (decl));
+  id = NULL_TREE;
+  if (type_name != NULL_TREE && TREE_CODE (type_name) == IDENTIFIER_NODE)
+    id = type_name;
+  else if (type_name != NULL_TREE && TREE_CODE (type_name) == TYPE_DECL
+	   && DECL_SOURCE_LOCATION (type_name) != BUILTINS_LOCATION
+	   && DECL_NAME (type_name))
+    id = DECL_NAME (type_name);
+  if (id != NULL_TREE &&
+      (!htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
+			NO_INSERT)
+       || htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (id),
+			  NO_INSERT)))
+    {
+      id = NULL_TREE;
+    }
+  if (id != NULL_TREE)
+    {
+      struct obstack *ob;
+
+      ob = &container->type_obstack;
+      obstack_1grow (ob, '_');
+      go_append_string (ob, id);
+      is_valid = htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
+				 NO_INSERT) != NULL;
+    }
+  else
+    is_valid = go_format_type (container, TREE_TYPE (decl), true, false, NULL);
   if (is_valid
       && htab_find_slot (container->type_hash,
 			 IDENTIFIER_POINTER (DECL_NAME (decl)),
@@ -1096,10 +1271,8 @@ go_output_var (struct godump_container *container, tree decl)
 
   /* Sometimes an extern variable is declared with an unknown struct
      type.  */
-  if (TYPE_NAME (TREE_TYPE (decl)) != NULL_TREE
-      && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
+  if (type_name != NULL_TREE && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
     {
-      tree type_name = TYPE_NAME (TREE_TYPE (decl));
       if (TREE_CODE (type_name) == IDENTIFIER_NODE)
 	container->pot_dummy_types.add (IDENTIFIER_POINTER (type_name));
       else if (TREE_CODE (type_name) == TYPE_DECL)
diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c b/gcc/testsuite/gcc.misc-tests/godump-1.c
new file mode 100644
index 0000000..98a2a78
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -0,0 +1,482 @@
+/* Test -fdump-go-specs option.  */
+
+/* { dg-options "-c -fdump-go-spec=godump-1.out" } */
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+/* integer based types */
+typedef char c_t;
+char c_v1;
+c_t c_v2;
+typedef short s_t;
+short s_v1;
+s_t s_v2;
+typedef int i_t;
+int i_v1;
+i_t i_v2;
+typedef long l_t;
+long l_v1;
+l_t l_v2;
+typedef long long ll_t;
+long long ll_v1;
+ll_t ll_v2;
+typedef unsigned char uc_t;
+unsigned char uc_v1;
+uc_t uc_v2;
+typedef unsigned short us_t;
+unsigned short us_v1;
+us_t us_v2;
+typedef unsigned int ui_t;
+unsigned int ui_v1;
+ui_t ui_v2;
+typedef unsigned long ul_t;
+unsigned long ul_v1;
+ul_t ul_v2;
+typedef unsigned long long ull_t;
+unsigned long long ull_v1;
+ull_t ull_v2;
+typedef signed char sc_t;
+signed char sc_v1;
+sc_t sc_v2;
+typedef signed short ss_t;
+signed short ss_v1;
+ss_t ss_v2;
+typedef signed int si_t;
+signed int si_v1;
+si_t si_v2;
+typedef signed long sl_t;
+signed long sl_v1;
+sl_t sl_v2;
+typedef signed long long sll_t;
+signed long long sll_v1;
+sll_t sll_v2;
+typedef int8_t i8_t;
+int8_t i8_v1;
+i8_t i8_v2;
+typedef int16_t i16_t;
+int16_t i16_v1;
+i16_t i16_v2;
+typedef int32_t i32_t;
+int32_t i32_v1;
+i32_t i32_v2;
+typedef int64_t i64_t;
+int64_t i64_v1;
+i64_t i64_v2;
+typedef uint8_t ui8_t;
+uint8_t ui8_v1;
+ui8_t ui8_v2;
+typedef uint16_t iu16_t;
+uint16_t iu16_v1;
+iu16_t iu16_v2;
+typedef uint32_t iu32_t;
+uint32_t iu32_v1;
+iu32_t iu32_v2;
+typedef uint64_t iu64_t;
+uint64_t iu64_v1;
+iu64_t iu64_v2;
+typedef const char cc_t;
+const char cc_v1;
+cc_t cc_v2;
+
+/* pointer and array types */
+typedef void *vp_t;
+void *vp_v1;
+vp_t vp_v2;
+typedef int **ipp_t;
+int **ipp_v1;
+ipp_t ipp_v2;
+typedef char ca_t[];
+char ca_v1[]; /* { dg-warning "array 'ca_v1' assumed to have one element" } */
+char ca_v1b[2];
+ca_t ca_v2; /* { dg-warning "array 'ca_v2' assumed to have one element" } */
+typedef short sa2_t[2];
+short sa2_v1[2];
+sa2_t sa2_v2;
+
+/* floating point types */
+typedef float f_t;
+float f_v1;
+f_t f_v2;
+typedef double d_t;
+double d_v1;
+d_t d_v2;
+typedef long double ld_t;
+long double ld_v1;
+ld_t ld_v2;
+
+/* nested typedefs */
+typedef int ni_t;
+typedef ni_t ni2_t;
+ni2_t ni2_v2;
+typedef ni2_t ni3_t;
+ni3_t ni3_v2;
+
+/* enums */
+enum { E11 };
+enum { EV11 } e1_v1;
+enum { E21, E22 };
+enum { EV21, EV22 } e2_v1;
+enum { EN1 = 3, EN2 = 77, EN3 = -1, EN4 };
+typedef enum { ET1, ET2 } et_t;
+enum { ETV1, ETV2 } et_v1;
+et_t et_v2;
+
+/* simple structs */
+typedef struct { } ts0e;
+struct { } s0e;
+typedef struct { int8_t e1; } ts1e;
+struct { int8_t e1; } s1e;
+typedef struct { int8_t e1; void *e2; } ts2el;
+struct { int8_t e1; void *e2; } s2el;
+typedef struct { void *e1; int8_t e2; } ts2eg;
+struct { void *e1; int8_t e2; } s2eg;
+typedef struct { int64_t l; int8_t c; int32_t i; int16_t s; } tsme;
+struct { int64_t l; int8_t c; int32_t i; int16_t s; } sme;
+typedef struct { int16_t sa[3]; int8_t ca[3]; } tsae;
+struct { int16_t sa[3]; int8_t ca[3]; } sae;
+typedef struct { float f; } tsf_equiv;
+struct { float f; } sf_equiv;
+typedef struct { float f; uint8_t : 0; } tsf_not_equiv;
+struct { float f; uint8_t : 0; } sf_not_equiv;
+typedef struct { double d; } tsd_equiv;
+struct { double d; } sd_equiv;
+typedef struct { double d; uint8_t : 0; } tsd_not_equiv;
+struct { double d; uint8_t : 0; } sd_not_equiv;
+typedef struct s_undef_t s_undef_t2;
+
+/* nested structs */
+typedef struct { struct { uint8_t ca[3]; } s; uint32_t i; } tsn;
+struct { struct { uint8_t ca[3]; } s; uint32_t i; } sn;
+typedef struct { struct { uint8_t a; uint16_t s; }; uint8_t b; } tsn_anon;
+struct { struct { uint8_t a; uint16_t s; }; uint8_t b; } sn_anon;
+
+/* structs with bitfields */
+typedef struct { uint8_t : 0; uint8_t c; } tsbf_anon_pad1;
+struct { uint8_t : 0; uint8_t c; } sbf_anon_pad1;
+typedef struct { uint8_t : 1; uint8_t c; } tsbf_anon_pad2;
+struct { uint8_t : 1; uint8_t c; } sbf_anon_pad2;
+typedef struct { uint8_t : 7; uint8_t c; } tsbf_anon_pad3;
+struct { uint8_t : 7; uint8_t c; } sbf_anon_pad3;
+typedef struct { uint8_t : 8; uint8_t c; } tsbf_anon_pad4;
+struct { uint8_t : 8; uint8_t c; } sbf_anon_pad4;
+typedef struct { uint64_t : 0; uint8_t c; } tsbf_anon_pad5;
+struct { uint64_t : 0; uint8_t c; } sbf_anon_pad5;
+typedef struct { uint64_t : 1; uint8_t c; } tsbf_anon_pad6;
+struct { uint64_t : 1; uint8_t c; } sbf_anon_pad6;
+typedef struct { uint64_t : 63; uint8_t c; } tsbf_anon_pad7;
+struct { uint64_t : 63; uint8_t c; } sbf_anon_pad7;
+typedef struct { uint64_t : 64; uint8_t c; } tsbf_anon_pad8;
+struct { uint64_t : 64; uint8_t c; } sbf_anon_pad8;
+typedef struct { uint8_t bf : 1; uint8_t c; } tsbf_pad8_1;
+struct { uint8_t bf : 1; uint8_t c; } sbf_pad8_1;
+typedef struct { uint8_t bf : 7; uint8_t c; } tsbf_pad8_2;
+struct { uint8_t bf : 7; uint8_t c; } sbf_pad8_2;
+typedef struct { uint8_t bf : 8; uint8_t c; } tsbf_pad8_3;
+struct { uint8_t bf : 8; uint8_t c; } sbf_pad8_3;
+typedef struct { uint16_t bf : 1; uint8_t c; } tsbf_pad16_1;
+struct { uint16_t bf : 1; uint8_t c; } sbf_pad16_1;
+typedef struct { uint16_t bf : 15; uint8_t c; } tsbf_pad16_2;
+struct { uint16_t bf : 15; uint8_t c; } sbf_pad16_2;
+typedef struct { uint16_t bf : 16; uint8_t c; } tsbf_pad16_3;
+struct { uint16_t bf : 16; uint8_t c; } sbf_pad16_3;
+typedef struct { uint32_t bf : 1; uint8_t c; } tsbf_pad32_1;
+struct { uint32_t bf : 1; uint8_t c; } sbf_pad32_1;
+typedef struct { uint32_t bf : 31; uint8_t c; } tsbf_pad32_2;
+struct { uint32_t bf : 31; uint8_t c; } sbf_pad32_2;
+typedef struct { uint32_t bf : 32; uint8_t c; } tsbf_pad32_3;
+struct { uint32_t bf : 32; uint8_t c; } sbf_pad32_3;
+typedef struct { uint64_t bf : 1; uint8_t c; } tsbf_pad64_1;
+struct { uint64_t bf : 1; uint8_t c; } sbf_pad64_1;
+typedef struct { uint64_t bf : 63; uint8_t c; } tsbf_pad64_2;
+struct { uint64_t bf : 63; uint8_t c; } sbf_pad64_2;
+typedef struct { uint64_t bf : 64; uint8_t c; } tsbf_pad64_3;
+struct { uint64_t bf : 64; uint8_t c; } sbf_pad64_3;
+typedef struct { uint8_t b1 : 1; } tsbf_1b;
+struct { uint8_t b1 : 1; } sbf_1b;
+typedef struct
+{
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+} tsbf_8b;
+struct
+{
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+} sbf_8b;
+typedef struct {
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+  uint8_t b9 : 1;
+} tsbf_9b;
+struct {
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+  uint8_t b9 : 1;
+} sbf_9b;
+typedef struct {
+  uint8_t b1 : 7; uint8_t b2 : 7; uint8_t b3 : 2;
+} tsbf_18b;
+struct {
+  uint8_t b1 : 7; uint8_t b2 : 7; uint8_t b3 : 2;
+} sbf_18b;
+struct
+{
+  uint16_t bf1 : 8;
+  uint8_t c;
+  uint16_t bf2 : 8;
+  uint32_t bf3 : 12;
+  uint16_t s;
+} sbf_gaps;
+typedef struct
+{
+  uint16_t bf1 : 8;
+  uint8_t c;
+  uint16_t bf2 : 8;
+  uint32_t bf3 : 12;
+  uint16_t s;
+} tsbf_gaps;
+
+/* unions */
+typedef union { } tue;
+union { } ue;
+typedef union { uint8_t c; uint64_t l; } tu1;
+union { uint8_t c; uint64_t l; } u1;
+typedef union { uint64_t l; uint8_t c; } tu2;
+union { uint64_t l; uint8_t c; } u2;
+typedef union { uint64_t l[3]; uint8_t c; } tu3;
+union { uint64_t l[3]; uint8_t c; } u3;
+typedef struct { union { uint8_t c; uint64_t l; }; } tsu_anon;
+struct { union { uint8_t c; uint64_t l; }; } su_anon;
+typedef union { uint64_t bf : 1; uint8_t ca[5]; } tu_size;
+union { uint64_t bf : 1; uint8_t ca[5]; } u_size;
+typedef union { uint64_t : 1; uint8_t ca[5]; } tu2_size;
+union { uint64_t : 1; uint8_t ca[5]; } u2_size;
+typedef union u_undef_t u_undef_t2;
+typedef union { uint64_t b : 1; uint8_t ca[5]; } tu3_size;
+union { uint64_t b : 1; uint8_t ca[5]; } u3_size;
+
+/* functions */
+extern uint32_t func1(uint8_t c);
+typedef int8_t (*func_t)(void *p);
+
+/* Necessary quoting in the regexp patters:
+
+     (?n) at beginning of pattern to make ^ and $ work.
+     "     ->  \"
+     *, +  ->  "*", "+"
+     [, ]  ->  "\[", "\]"
+     (, )  ->  "\[(\]", "\[)\]"
+     {, }  ->  "\{", "\}"
+*/
+
+/* { dg-final { scan-file godump-1.out "(?n)^type _c_t u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _s_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _l_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ll_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _uc_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _us_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ui_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ul_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ull_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sc_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ss_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _si_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sl_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sll_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i8_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i16_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i32_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i64_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ui8_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu16_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu32_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu64_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _cc_t u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _vp_t \\*byte$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ipp_t \\*\\*int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ca_t \\\[0\\\]uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sa2_t \\\[1\\+1\\\]int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _f_t float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _d_t float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// type _ld_t INVALID-float-128$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni2_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni3_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _et_t int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts0e struct \{ \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts1e struct \{ e1 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts2el struct \{ e1 int\[0-9\]*; e2 \\*byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts2eg struct \{ e1 \\*byte; e2 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsme struct \{ l int\[0-9\]*; c int\[0-9\]*; i int\[0-9\]*; s int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsae struct \{ sa \\\[2\\+1\\\]int\[0-9\]*; ca \\\[2\\+1\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsf_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsf_not_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsd_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsd_not_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsn struct \{ s struct \{ ca \\\[2\\+1\\\]uint\[0-9\]*; \}; i uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsn_anon struct \{ Godump_0 struct \{ a uint\[0-9\]*; s uint\[0-9\]*; \}; b uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad1 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad3 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad4 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad5 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad6 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad7 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad8 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_2 struct \{ Godump_0_pad \\\[2\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_2 struct \{ Godump_0_pad \\\[4\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_2 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_1b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_8b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_9b struct \{ Godump_0_pad \\\[2\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_18b struct \{ Godump_0_pad \\\[3\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_gaps struct \{ bf1 uint\[0-9\]*; c uint\[0-9\]*; bf2 uint\[0-9\]*; Godump_0_pad \\\[2\\\]byte; s uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tue struct \{ Godump_0 \\\[0\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu1 struct \{ c \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu2 struct \{ l \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu3 struct \{ l \\\[24\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsu_anon struct \{ Godump_0 struct \{ c \\\[8\\\]byte; Godump_1_align \\\[0\\\]uint64; \}; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu_size struct \{ bf \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu2_size struct \{ Godump_0 \\\[5\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu3_size struct \{ b \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _func_t func\[(\]\\*byte\[)\] int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _c_v1 u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _c_v2 _c_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s_v2 _s_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i_v2 _i_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _l_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _l_v2 _l_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ll_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ll_v2 _ll_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _uc_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _uc_v2 _uc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _us_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _us_v2 _us_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui_v2 _ui_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ul_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ul_v2 _ul_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ull_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ull_v2 _ull_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sc_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sc_v2 _sc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ss_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ss_v2 _ss_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _si_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _si_v2 _si_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sl_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sl_v2 _sl_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sll_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sll_v2 _sll_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i8_v1 _int8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i8_v2 _i8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i16_v1 _int16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i16_v2 _i16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i32_v1 _int32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i32_v2 _i32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i64_v1 _int64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i64_v2 _i64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui8_v1 _uint8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui8_v2 _ui8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu16_v1 _uint16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu16_v2 _iu16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu32_v1 _uint32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu32_v2 _iu32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu64_v1 _uint64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu64_v2 _iu64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cc_v1 u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cc_v2 _cc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _vp_v1 \\*byte$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _vp_v2 _vp_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ipp_v1 \\*\\*int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ipp_v2 _ipp_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v1 \\\[0\\+1\\\]uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v1b \\\[1\\+1\\\]uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v2 \\\[0\\+1\\\]uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sa2_v1 \\\[1\\+1\\\]int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sa2_v2 _sa2_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _f_v1 float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _f_v2 _f_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _d_v1 float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _d_v2 _d_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v1 INVALID-float-128$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v2 INVALID-float-128$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ni2_v2 _ni2_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ni3_v2 _ni3_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _e1_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _e2_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _et_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _et_v2 _et_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s0e struct \{ \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s1e struct \{ e1 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s2el struct \{ e1 int\[0-9\]*; e2 \\*byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s2eg struct \{ e1 \\*byte; e2 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sme struct \{ l int\[0-9\]*; c int\[0-9\]*; i int\[0-9\]*; s int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sae struct \{ sa \\\[2\\+1\\\]int\[0-9\]*; ca \\\[2\\+1\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sf_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sf_not_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sd_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sd_not_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sn struct \{ s struct \{ ca \\\[2\\+1\\\]uint\[0-9\]*; \}; i uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sn_anon struct \{ Godump_0 struct \{ a uint\[0-9\]*; s uint\[0-9\]*; \}; b uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad1 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad3 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad4 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad5 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad6 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad7 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad8 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_2 struct \{ Godump_0_pad \\\[2\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_2 struct \{ Godump_0_pad \\\[4\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_2 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_1b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_8b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_9b struct \{ Godump_0_pad \\\[2\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_18b struct \{ Godump_0_pad \\\[3\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_gaps struct \{ bf1 uint\[0-9\]*; c uint\[0-9\]*; bf2 uint\[0-9\]*; Godump_0_pad \\\[2\\\]byte; s uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ue struct \{ Godump_0 \\\[0\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u1 struct \{ c \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u2 struct \{ l \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u3 struct \{ l \\\[24\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _su_anon struct \{ Godump_0 struct \{ c \\\[8\\\]byte; Godump_1_align \\\[0\\\]uint64; \}; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u_size struct \{ bf \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u2_size struct \{ Godump_0 \\\[5\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u3_size struct \{ b \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^func _func1 \[(\]uint\[0-9\]*\[)\] uint\[0-9\]* __asm__\[(\]\"func1\"\[)\]$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E11 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E21 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E22 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN1 = 3$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN2 = 77$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN3 = -1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN4 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ET1 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ET2 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ETV1 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ETV2 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV11 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV21 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV22 = 1$" } } */
diff --git a/gcc/testsuite/gcc.misc-tests/godump.exp b/gcc/testsuite/gcc.misc-tests/godump.exp
new file mode 100644
index 0000000..96812c4
--- /dev/null
+++ b/gcc/testsuite/gcc.misc-tests/godump.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/godump-*.c]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-28 14:40     ` Dominik Vogt
@ 2014-10-28 17:37       ` Ian Taylor
  2014-10-29  9:05         ` Dominik Vogt
  0 siblings, 1 reply; 38+ messages in thread
From: Ian Taylor @ 2014-10-28 17:37 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 1620 bytes --]

On Tue, Oct 28, 2014 at 7:31 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
>
> The attached patch contains all the discussed changes.

I made a few formatting changes.  I patched the test to work on x86,
by making the char types accept either int8 or uint8, and making the
long double tests accept any floating point size.

Approved and applied as attached.

Thanks.

Ian


gcc/:
2014-10-28  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * godump.c (precision_to_units): New helper function.
        (go_append_artificial_name): Ditto.
        (go_append_decl_name): Ditto.
        (go_append_bitfield): Ditto.
        (go_get_uinttype_for_precision): Ditto.
        (go_append_padding): Ditto.
        (go_force_record_alignment): Ditto.
        (go_format_type): Represent unions with an array of uints of the size
        of the alignment in go.  This fixes the 'random' size of the union's
        representation using just the first field.
        (go_format_type): Add argument that indicates whether a record is
        nested (used for generation of artificial go names).
        (go_output_fndecl): Adapt to new go_format_type signature.
        (go_output_typedef): Ditto.
        (go_output_var): Ditto.
        (go_output_var): Prefer to output type as alias (typedef).
        (go_format_type): Bitfields in records are simulated as arrays of bytes
        in go.

        * godump.c (go_format_type): Fix handling of arrays with zero elements.


gcc/testsuite/:
2014-10-28  Dominik Vogt  <vogt@linux.vnet.ibm.com>

        * gcc.misc-tests/godump.exp: New.
        * gcc.misc-tests/godump-1.c: New.

[-- Attachment #2: foo.txt --]
[-- Type: text/plain, Size: 46877 bytes --]

Index: godump.c
===================================================================
--- godump.c	(revision 216766)
+++ godump.c	(working copy)
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3.
 #include "obstack.h"
 #include "debug.h"
 #include "wide-int-print.h"
+#include "stor-layout.h"
+#include "defaults.h"
 
 /* We dump this information from the debug hooks.  This gives us a
    stable and maintainable API to hook into.  In order to work
@@ -73,6 +75,15 @@ struct macro_hash_value
   char *value;
 };
 
+/* Returns the number of units necessary to represent an integer with the given
+   PRECISION (in bits).  */
+
+static inline unsigned int
+precision_to_units (unsigned int precision)
+{
+  return (precision + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
+}
+
 /* Calculate the hash value for an entry in the macro hash table.  */
 
 static hashval_t
@@ -552,19 +563,132 @@ go_append_string (struct obstack *ob, tr
   obstack_grow (ob, IDENTIFIER_POINTER (id), IDENTIFIER_LENGTH (id));
 }
 
+/* Given an integer PRECISION in bits, returns a constant string that is the
+   matching go int or uint type (depending on the IS_UNSIGNED flag).  Returns a
+   NULL pointer if there is no matching go type.  */
+
+static const char *
+go_get_uinttype_for_precision (unsigned int precision, bool is_unsigned)
+{
+  switch (precision)
+    {
+    case 8:
+      return is_unsigned ? "uint8" : "int8";
+    case 16:
+      return is_unsigned ? "uint16" : "int16";
+    case 32:
+      return is_unsigned ? "uint32" : "int32";
+    case 64:
+      return is_unsigned ? "uint64" : "int64";
+    default:
+      return NULL;
+    }
+}
+
+/* Append an artificial variable name with the suffix _INDEX to OB.  Returns
+   INDEX + 1.  */
+
+static unsigned int
+go_append_artificial_name (struct obstack *ob, unsigned int index)
+{
+  char buf[100];
+
+  /* FIXME: identifier may not be unique.  */
+  obstack_grow (ob, "Godump_", 7);
+  snprintf (buf, sizeof buf, "%u", index);
+  obstack_grow (ob, buf, strlen (buf));
+
+  return index + 1;
+}
+
+/* Append the variable name from DECL to OB.  If the name is in the
+   KEYWORD_HASH, prepend an '_'.  */
+
+static void
+go_append_decl_name (struct obstack *ob, tree decl, htab_t keyword_hash)
+{
+  const char *var_name;
+  void **slot;
+
+  /* Start variable name with an underscore if a keyword.  */
+  var_name = IDENTIFIER_POINTER (DECL_NAME (decl));
+  slot = htab_find_slot (keyword_hash, var_name, NO_INSERT);
+  if (slot != NULL)
+    obstack_1grow (ob, '_');
+  go_append_string (ob, DECL_NAME (decl));
+}
+
+/* Appends a byte array with the necessary number of elements and the name
+   "Godump_INDEX_pad" to pad from FROM_OFFSET to TO_OFFSET to OB assuming that
+   the next field is automatically aligned to ALIGN_UNITS.  Returns INDEX + 1,
+   or INDEX if no padding had to be appended.  The resulting offset where the
+   next field is allocated is returned through RET_OFFSET.  */
+
+static unsigned int
+go_append_padding (struct obstack *ob, unsigned int from_offset,
+		   unsigned int to_offset, unsigned int align_units,
+		   unsigned int index, unsigned int *ret_offset)
+{
+  if (from_offset % align_units > 0)
+    from_offset += align_units - (from_offset % align_units);
+  gcc_assert (to_offset >= from_offset);
+  if (to_offset > from_offset)
+    {
+      char buf[100];
+
+      index = go_append_artificial_name (ob, index);
+      snprintf (buf, sizeof buf, "_pad [%u]byte; ", to_offset - from_offset);
+      obstack_grow (ob, buf, strlen (buf));
+    }
+  *ret_offset = to_offset;
+
+  return index;
+}
+
+/* Appends an array of type TYPE_STRING with zero elements and the name
+   "Godump_INDEX_align" to OB.  If TYPE_STRING is a null pointer, ERROR_STRING
+   is appended instead of the type.  Returns INDEX + 1.  */
+
+static unsigned int
+go_force_record_alignment (struct obstack *ob, const char *type_string,
+			   unsigned int index, const char *error_string)
+{
+  index = go_append_artificial_name (ob, index);
+  obstack_grow (ob, "_align ", 7);
+  if (type_string == NULL)
+    obstack_grow (ob, error_string, strlen (error_string));
+  else
+    {
+      obstack_grow (ob, "[0]", 3);
+      obstack_grow (ob, type_string, strlen (type_string));
+    }
+  obstack_grow (ob, "; ", 2);
+
+  return index;
+}
+
 /* 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
-   type here; the "func" keyword will already have been added.  Return
-   true if the type can be represented in Go, false otherwise.  */
+   type here; the "func" keyword will already have been added.
+   Return true if the type can be represented in Go, false otherwise.
+   P_ART_I is used for indexing artificial elements in nested structures and
+   should always be a NULL pointer when called, except by certain recursive
+   calls from go_format_type() itself.  */
 
 static bool
 go_format_type (struct godump_container *container, tree type,
-		bool use_type_name, bool is_func_ok)
+		bool use_type_name, bool is_func_ok, unsigned int *p_art_i)
 {
   bool ret;
   struct obstack *ob;
+  unsigned int art_i_dummy;
 
+  if (p_art_i == NULL)
+    {
+      art_i_dummy = 0;
+      p_art_i = &art_i_dummy;
+    }
   ret = true;
   ob = &container->type_obstack;
 
@@ -618,27 +742,15 @@ go_format_type (struct godump_container
 	const char *s;
 	char buf[100];
 
-	switch (TYPE_PRECISION (type))
+	s = go_get_uinttype_for_precision (TYPE_PRECISION (type),
+					   TYPE_UNSIGNED (type));
+	if (s == NULL)
 	  {
-	  case 8:
-	    s = TYPE_UNSIGNED (type) ? "uint8" : "int8";
-	    break;
-	  case 16:
-	    s = TYPE_UNSIGNED (type) ? "uint16" : "int16";
-	    break;
-	  case 32:
-	    s = TYPE_UNSIGNED (type) ? "uint32" : "int32";
-	    break;
-	  case 64:
-	    s = TYPE_UNSIGNED (type) ? "uint64" : "int64";
-	    break;
-	  default:
 	    snprintf (buf, sizeof buf, "INVALID-int-%u%s",
 		      TYPE_PRECISION (type),
 		      TYPE_UNSIGNED (type) ? "u" : "");
 	    s = buf;
 	    ret = false;
-	    break;
 	  }
 	obstack_grow (ob, s, strlen (s));
       }
@@ -710,7 +822,7 @@ go_format_type (struct godump_container
       else
 	{
 	  if (!go_format_type (container, TREE_TYPE (type), use_type_name,
-			       true))
+			       true, NULL))
 	    ret = false;
 	}
       break;
@@ -732,64 +844,64 @@ go_format_type (struct godump_container
 		    tree_to_shwi (TYPE_MAX_VALUE (TYPE_DOMAIN (type))));
 	  obstack_grow (ob, buf, strlen (buf));
 	}
+      else
+	obstack_1grow (ob, '0');
       obstack_1grow (ob, ']');
-      if (!go_format_type (container, TREE_TYPE (type), use_type_name, false))
+      if (!go_format_type (container, TREE_TYPE (type), use_type_name, false,
+			   NULL))
 	ret = false;
       break;
 
-    case UNION_TYPE:
     case RECORD_TYPE:
       {
+	unsigned int prev_field_end;
+	unsigned int most_strict_known_alignment;
 	tree field;
-	int i;
 
+	/* FIXME: Why is this necessary?  Without it we can get a core
+	   dump on the s390x headers, or from a file containing simply
+	   "typedef struct S T;".  */
+	layout_type (type);
+
+	prev_field_end = 0;
+	most_strict_known_alignment = 1;
 	obstack_grow (ob, "struct { ", 9);
-	i = 0;
 	for (field = TYPE_FIELDS (type);
 	     field != NULL_TREE;
 	     field = TREE_CHAIN (field))
 	  {
-	    struct obstack hold_type_obstack;
 	    bool field_ok;
 
-	    if (TREE_CODE (type) == UNION_TYPE)
-	      {
-		hold_type_obstack = container->type_obstack;
-		obstack_init (&container->type_obstack);
-	      }
-
+	    if (TREE_CODE (field) != FIELD_DECL)
+	      continue;
 	    field_ok = true;
-
-	    if (DECL_NAME (field) == NULL)
-	      {
-		char buf[100];
-
-		obstack_grow (ob, "Godump_", 7);
-		snprintf (buf, sizeof buf, "%d", i);
-		obstack_grow (ob, buf, strlen (buf));
-		i++;
-	      }
-	    else
-              {
-		const char *var_name;
-		void **slot;
-
-		/* Start variable name with an underscore if a keyword.  */
-		var_name = IDENTIFIER_POINTER (DECL_NAME (field));
-		slot = htab_find_slot (container->keyword_hash, var_name,
-				       NO_INSERT);
-		if (slot != NULL)
-		  obstack_1grow (ob, '_');
-		go_append_string (ob, DECL_NAME (field));
-	      }
-	    obstack_1grow (ob, ' ');
 	    if (DECL_BIT_FIELD (field))
-	      {
-		obstack_grow (ob, "INVALID-bit-field", 17);
-		field_ok = false;
-	      }
+	      continue;
 	    else
               {
+		{
+		  unsigned int decl_align_unit;
+		  unsigned int decl_offset;
+
+		  decl_align_unit = DECL_ALIGN_UNIT (field);
+		  decl_offset =
+		    TREE_INT_CST_LOW (DECL_FIELD_OFFSET (field))
+		    + precision_to_units
+		    (TREE_INT_CST_LOW (DECL_FIELD_BIT_OFFSET (field)));
+		  if (decl_align_unit > most_strict_known_alignment)
+		    most_strict_known_alignment = decl_align_unit;
+		  *p_art_i = go_append_padding
+		    (ob, prev_field_end, decl_offset, decl_align_unit, *p_art_i,
+		     &prev_field_end);
+		  if (DECL_SIZE_UNIT (field))
+		    prev_field_end += TREE_INT_CST_LOW (DECL_SIZE_UNIT (field));
+		}
+		if (DECL_NAME (field) == NULL)
+		  *p_art_i = go_append_artificial_name (ob, *p_art_i);
+		else
+		  go_append_decl_name (ob, field, container->keyword_hash);
+		obstack_1grow (ob, ' ');
+
 		/* Do not expand type if a record or union type or a
 		   function pointer.  */
 		if (TYPE_NAME (TREE_TYPE (field)) != NULL_TREE
@@ -815,40 +927,76 @@ go_format_type (struct godump_container
 		else
 		  {
 		    if (!go_format_type (container, TREE_TYPE (field), true,
-					 false))
+					 false, p_art_i))
 		      field_ok = false;
 		  }
+		obstack_grow (ob, "; ", 2);
               }
-	    obstack_grow (ob, "; ", 2);
+	    if (!field_ok)
+	      ret = false;
+	  }
+	/* Alignment and padding as necessary.  */
+	{
+	  unsigned int type_align_unit;
 
-	    /* Only output the first successful field of a union, and
-	       hope for the best.  */
-	    if (TREE_CODE (type) == UNION_TYPE)
-	      {
-		if (!field_ok && TREE_CHAIN (field) == NULL_TREE)
-		  {
-		    field_ok = true;
-		    ret = false;
-		  }
-		if (field_ok)
-		  {
-		    unsigned int sz;
+	  type_align_unit = TYPE_ALIGN_UNIT (type);
+	  /* Padding.  */
+	  *p_art_i = go_append_padding
+	    (ob, prev_field_end, TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type)),
+	     type_align_unit, *p_art_i, &prev_field_end);
+	  if (most_strict_known_alignment < type_align_unit)
+	  {
+	    const char *s;
+	    char buf[100];
 
-		    sz = obstack_object_size (&container->type_obstack);
-		    obstack_grow (&hold_type_obstack,
-				  obstack_base (&container->type_obstack),
-				  sz);
-		  }
-		obstack_free (&container->type_obstack, NULL);
-		container->type_obstack = hold_type_obstack;
-		if (field_ok)
-		  break;
-	      }
-	    else
+	    /* Enforce proper record alignment.  */
+	    s = go_get_uinttype_for_precision
+	      (TYPE_ALIGN (type), TYPE_UNSIGNED (type));
+	    if (s == NULL)
 	      {
-		if (!field_ok)
-		  ret = false;
+		snprintf (buf, sizeof buf, "INVALID-int-%u%s",
+			  TYPE_ALIGN (type), TYPE_UNSIGNED (type) ? "u" : "");
+		s = buf;
+		ret = false;
 	      }
+	    *p_art_i = go_force_record_alignment (ob, s, *p_art_i, buf);
+	  }
+	}
+	obstack_1grow (ob, '}');
+      }
+      break;
+
+    case UNION_TYPE:
+      {
+	const char *s;
+	unsigned int sz_units;
+
+	layout_type (type);
+	sz_units = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (type));
+	s = go_get_uinttype_for_precision (TYPE_ALIGN (type), true);
+	obstack_grow (ob, "struct { ", 9);
+	if (s == NULL)
+	  {
+	    ret = false;
+	    s = "INVALID-union-alignment";
+	    obstack_grow (ob, s, strlen (s));
+	  }
+	else
+	  {
+	    char buf[100];
+	    tree field;
+
+	    field = TYPE_FIELDS (type);
+	    /* Use the same index as the byte field's artificial name for
+	       padding.  */
+	    if (field != NULL_TREE && DECL_NAME (field) != NULL)
+	      go_append_decl_name (ob, field, container->keyword_hash);
+	    else
+	      *p_art_i = go_append_artificial_name (ob, *p_art_i);
+	    snprintf (buf, sizeof buf, " [%u]byte; ", sz_units);
+	    obstack_grow (ob, buf, strlen (buf));
+	    if (TYPE_ALIGN_UNIT (type) > 1)
+	      *p_art_i = go_force_record_alignment (ob, s, *p_art_i, NULL);
 	  }
 	obstack_1grow (ob, '}');
       }
@@ -879,7 +1027,7 @@ go_format_type (struct godump_container
 	      break;
 	    if (seen_arg)
 	      obstack_grow (ob, ", ", 2);
-	    if (!go_format_type (container, arg_type, true, false))
+	    if (!go_format_type (container, arg_type, true, false, NULL))
 	      ret = false;
 	    seen_arg = true;
 	  }
@@ -895,7 +1043,7 @@ go_format_type (struct godump_container
 	if (!VOID_TYPE_P (result))
 	  {
 	    obstack_1grow (ob, ' ');
-	    if (!go_format_type (container, result, use_type_name, false))
+	    if (!go_format_type (container, result, use_type_name, false, NULL))
 	      ret = false;
 	  }
       }
@@ -929,7 +1077,7 @@ go_output_type (struct godump_container
 static void
 go_output_fndecl (struct godump_container *container, tree decl)
 {
-  if (!go_format_type (container, TREE_TYPE (decl), false, true))
+  if (!go_format_type (container, TREE_TYPE (decl), false, true, NULL))
     fprintf (go_dump_file, "// ");
   fprintf (go_dump_file, "func _%s ",
 	   IDENTIFIER_POINTER (DECL_NAME (decl)));
@@ -1004,7 +1152,7 @@ go_output_typedef (struct godump_contain
 	return;
       *slot = CONST_CAST (void *, (const void *) type);
 
-      if (!go_format_type (container, TREE_TYPE (decl), false, false))
+      if (!go_format_type (container, TREE_TYPE (decl), false, false, NULL))
 	{
 	  fprintf (go_dump_file, "// ");
 	  slot = htab_find_slot (container->invalid_hash, type, INSERT);
@@ -1040,7 +1188,7 @@ go_output_typedef (struct godump_contain
          return;
        *slot = CONST_CAST (void *, (const void *) type);
 
-       if (!go_format_type (container, TREE_TYPE (decl), false, false))
+       if (!go_format_type (container, TREE_TYPE (decl), false, false, NULL))
 	 {
 	   fprintf (go_dump_file, "// ");
 	   slot = htab_find_slot (container->invalid_hash, type, INSERT);
@@ -1069,6 +1217,8 @@ static void
 go_output_var (struct godump_container *container, tree decl)
 {
   bool is_valid;
+  tree type_name;
+  tree id;
 
   if (container->decls_seen.contains (decl)
       || container->decls_seen.contains (DECL_NAME (decl)))
@@ -1076,7 +1226,32 @@ go_output_var (struct godump_container *
   container->decls_seen.add (decl);
   container->decls_seen.add (DECL_NAME (decl));
 
-  is_valid = go_format_type (container, TREE_TYPE (decl), true, false);
+  type_name = TYPE_NAME (TREE_TYPE (decl));
+  id = NULL_TREE;
+  if (type_name != NULL_TREE && TREE_CODE (type_name) == IDENTIFIER_NODE)
+    id = type_name;
+  else if (type_name != NULL_TREE && TREE_CODE (type_name) == TYPE_DECL
+	   && DECL_SOURCE_LOCATION (type_name) != BUILTINS_LOCATION
+	   && DECL_NAME (type_name))
+    id = DECL_NAME (type_name);
+  if (id != NULL_TREE
+      && (!htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
+			   NO_INSERT)
+	  || htab_find_slot (container->invalid_hash, IDENTIFIER_POINTER (id),
+			     NO_INSERT)))
+    id = NULL_TREE;
+  if (id != NULL_TREE)
+    {
+      struct obstack *ob;
+
+      ob = &container->type_obstack;
+      obstack_1grow (ob, '_');
+      go_append_string (ob, id);
+      is_valid = htab_find_slot (container->type_hash, IDENTIFIER_POINTER (id),
+				 NO_INSERT) != NULL;
+    }
+  else
+    is_valid = go_format_type (container, TREE_TYPE (decl), true, false, NULL);
   if (is_valid
       && htab_find_slot (container->type_hash,
 			 IDENTIFIER_POINTER (DECL_NAME (decl)),
@@ -1096,10 +1271,8 @@ go_output_var (struct godump_container *
 
   /* Sometimes an extern variable is declared with an unknown struct
      type.  */
-  if (TYPE_NAME (TREE_TYPE (decl)) != NULL_TREE
-      && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
+  if (type_name != NULL_TREE && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
     {
-      tree type_name = TYPE_NAME (TREE_TYPE (decl));
       if (TREE_CODE (type_name) == IDENTIFIER_NODE)
 	container->pot_dummy_types.add (IDENTIFIER_POINTER (type_name));
       else if (TREE_CODE (type_name) == TYPE_DECL)
Index: testsuite/gcc.misc-tests/godump-1.c
===================================================================
--- testsuite/gcc.misc-tests/godump-1.c	(revision 0)
+++ testsuite/gcc.misc-tests/godump-1.c	(working copy)
@@ -0,0 +1,482 @@
+/* Test -fdump-go-specs option.  */
+
+/* { dg-options "-c -fdump-go-spec=godump-1.out" } */
+/* { dg-do compile } */
+
+#include <stdint.h>
+
+/* integer based types */
+typedef char c_t;
+char c_v1;
+c_t c_v2;
+typedef short s_t;
+short s_v1;
+s_t s_v2;
+typedef int i_t;
+int i_v1;
+i_t i_v2;
+typedef long l_t;
+long l_v1;
+l_t l_v2;
+typedef long long ll_t;
+long long ll_v1;
+ll_t ll_v2;
+typedef unsigned char uc_t;
+unsigned char uc_v1;
+uc_t uc_v2;
+typedef unsigned short us_t;
+unsigned short us_v1;
+us_t us_v2;
+typedef unsigned int ui_t;
+unsigned int ui_v1;
+ui_t ui_v2;
+typedef unsigned long ul_t;
+unsigned long ul_v1;
+ul_t ul_v2;
+typedef unsigned long long ull_t;
+unsigned long long ull_v1;
+ull_t ull_v2;
+typedef signed char sc_t;
+signed char sc_v1;
+sc_t sc_v2;
+typedef signed short ss_t;
+signed short ss_v1;
+ss_t ss_v2;
+typedef signed int si_t;
+signed int si_v1;
+si_t si_v2;
+typedef signed long sl_t;
+signed long sl_v1;
+sl_t sl_v2;
+typedef signed long long sll_t;
+signed long long sll_v1;
+sll_t sll_v2;
+typedef int8_t i8_t;
+int8_t i8_v1;
+i8_t i8_v2;
+typedef int16_t i16_t;
+int16_t i16_v1;
+i16_t i16_v2;
+typedef int32_t i32_t;
+int32_t i32_v1;
+i32_t i32_v2;
+typedef int64_t i64_t;
+int64_t i64_v1;
+i64_t i64_v2;
+typedef uint8_t ui8_t;
+uint8_t ui8_v1;
+ui8_t ui8_v2;
+typedef uint16_t iu16_t;
+uint16_t iu16_v1;
+iu16_t iu16_v2;
+typedef uint32_t iu32_t;
+uint32_t iu32_v1;
+iu32_t iu32_v2;
+typedef uint64_t iu64_t;
+uint64_t iu64_v1;
+iu64_t iu64_v2;
+typedef const char cc_t;
+const char cc_v1;
+cc_t cc_v2;
+
+/* pointer and array types */
+typedef void *vp_t;
+void *vp_v1;
+vp_t vp_v2;
+typedef int **ipp_t;
+int **ipp_v1;
+ipp_t ipp_v2;
+typedef char ca_t[];
+char ca_v1[]; /* { dg-warning "array 'ca_v1' assumed to have one element" } */
+char ca_v1b[2];
+ca_t ca_v2; /* { dg-warning "array 'ca_v2' assumed to have one element" } */
+typedef short sa2_t[2];
+short sa2_v1[2];
+sa2_t sa2_v2;
+
+/* floating point types */
+typedef float f_t;
+float f_v1;
+f_t f_v2;
+typedef double d_t;
+double d_v1;
+d_t d_v2;
+typedef long double ld_t;
+long double ld_v1;
+ld_t ld_v2;
+
+/* nested typedefs */
+typedef int ni_t;
+typedef ni_t ni2_t;
+ni2_t ni2_v2;
+typedef ni2_t ni3_t;
+ni3_t ni3_v2;
+
+/* enums */
+enum { E11 };
+enum { EV11 } e1_v1;
+enum { E21, E22 };
+enum { EV21, EV22 } e2_v1;
+enum { EN1 = 3, EN2 = 77, EN3 = -1, EN4 };
+typedef enum { ET1, ET2 } et_t;
+enum { ETV1, ETV2 } et_v1;
+et_t et_v2;
+
+/* simple structs */
+typedef struct { } ts0e;
+struct { } s0e;
+typedef struct { int8_t e1; } ts1e;
+struct { int8_t e1; } s1e;
+typedef struct { int8_t e1; void *e2; } ts2el;
+struct { int8_t e1; void *e2; } s2el;
+typedef struct { void *e1; int8_t e2; } ts2eg;
+struct { void *e1; int8_t e2; } s2eg;
+typedef struct { int64_t l; int8_t c; int32_t i; int16_t s; } tsme;
+struct { int64_t l; int8_t c; int32_t i; int16_t s; } sme;
+typedef struct { int16_t sa[3]; int8_t ca[3]; } tsae;
+struct { int16_t sa[3]; int8_t ca[3]; } sae;
+typedef struct { float f; } tsf_equiv;
+struct { float f; } sf_equiv;
+typedef struct { float f; uint8_t : 0; } tsf_not_equiv;
+struct { float f; uint8_t : 0; } sf_not_equiv;
+typedef struct { double d; } tsd_equiv;
+struct { double d; } sd_equiv;
+typedef struct { double d; uint8_t : 0; } tsd_not_equiv;
+struct { double d; uint8_t : 0; } sd_not_equiv;
+typedef struct s_undef_t s_undef_t2;
+
+/* nested structs */
+typedef struct { struct { uint8_t ca[3]; } s; uint32_t i; } tsn;
+struct { struct { uint8_t ca[3]; } s; uint32_t i; } sn;
+typedef struct { struct { uint8_t a; uint16_t s; }; uint8_t b; } tsn_anon;
+struct { struct { uint8_t a; uint16_t s; }; uint8_t b; } sn_anon;
+
+/* structs with bitfields */
+typedef struct { uint8_t : 0; uint8_t c; } tsbf_anon_pad1;
+struct { uint8_t : 0; uint8_t c; } sbf_anon_pad1;
+typedef struct { uint8_t : 1; uint8_t c; } tsbf_anon_pad2;
+struct { uint8_t : 1; uint8_t c; } sbf_anon_pad2;
+typedef struct { uint8_t : 7; uint8_t c; } tsbf_anon_pad3;
+struct { uint8_t : 7; uint8_t c; } sbf_anon_pad3;
+typedef struct { uint8_t : 8; uint8_t c; } tsbf_anon_pad4;
+struct { uint8_t : 8; uint8_t c; } sbf_anon_pad4;
+typedef struct { uint64_t : 0; uint8_t c; } tsbf_anon_pad5;
+struct { uint64_t : 0; uint8_t c; } sbf_anon_pad5;
+typedef struct { uint64_t : 1; uint8_t c; } tsbf_anon_pad6;
+struct { uint64_t : 1; uint8_t c; } sbf_anon_pad6;
+typedef struct { uint64_t : 63; uint8_t c; } tsbf_anon_pad7;
+struct { uint64_t : 63; uint8_t c; } sbf_anon_pad7;
+typedef struct { uint64_t : 64; uint8_t c; } tsbf_anon_pad8;
+struct { uint64_t : 64; uint8_t c; } sbf_anon_pad8;
+typedef struct { uint8_t bf : 1; uint8_t c; } tsbf_pad8_1;
+struct { uint8_t bf : 1; uint8_t c; } sbf_pad8_1;
+typedef struct { uint8_t bf : 7; uint8_t c; } tsbf_pad8_2;
+struct { uint8_t bf : 7; uint8_t c; } sbf_pad8_2;
+typedef struct { uint8_t bf : 8; uint8_t c; } tsbf_pad8_3;
+struct { uint8_t bf : 8; uint8_t c; } sbf_pad8_3;
+typedef struct { uint16_t bf : 1; uint8_t c; } tsbf_pad16_1;
+struct { uint16_t bf : 1; uint8_t c; } sbf_pad16_1;
+typedef struct { uint16_t bf : 15; uint8_t c; } tsbf_pad16_2;
+struct { uint16_t bf : 15; uint8_t c; } sbf_pad16_2;
+typedef struct { uint16_t bf : 16; uint8_t c; } tsbf_pad16_3;
+struct { uint16_t bf : 16; uint8_t c; } sbf_pad16_3;
+typedef struct { uint32_t bf : 1; uint8_t c; } tsbf_pad32_1;
+struct { uint32_t bf : 1; uint8_t c; } sbf_pad32_1;
+typedef struct { uint32_t bf : 31; uint8_t c; } tsbf_pad32_2;
+struct { uint32_t bf : 31; uint8_t c; } sbf_pad32_2;
+typedef struct { uint32_t bf : 32; uint8_t c; } tsbf_pad32_3;
+struct { uint32_t bf : 32; uint8_t c; } sbf_pad32_3;
+typedef struct { uint64_t bf : 1; uint8_t c; } tsbf_pad64_1;
+struct { uint64_t bf : 1; uint8_t c; } sbf_pad64_1;
+typedef struct { uint64_t bf : 63; uint8_t c; } tsbf_pad64_2;
+struct { uint64_t bf : 63; uint8_t c; } sbf_pad64_2;
+typedef struct { uint64_t bf : 64; uint8_t c; } tsbf_pad64_3;
+struct { uint64_t bf : 64; uint8_t c; } sbf_pad64_3;
+typedef struct { uint8_t b1 : 1; } tsbf_1b;
+struct { uint8_t b1 : 1; } sbf_1b;
+typedef struct
+{
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+} tsbf_8b;
+struct
+{
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+} sbf_8b;
+typedef struct {
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+  uint8_t b9 : 1;
+} tsbf_9b;
+struct {
+  uint8_t b1 : 1; uint8_t b2 : 1; uint8_t b3 : 1; uint8_t b4 : 1;
+  uint8_t b5 : 1; uint8_t b6 : 1; uint8_t b7 : 1; uint8_t b8 : 1;
+  uint8_t b9 : 1;
+} sbf_9b;
+typedef struct {
+  uint8_t b1 : 7; uint8_t b2 : 7; uint8_t b3 : 2;
+} tsbf_18b;
+struct {
+  uint8_t b1 : 7; uint8_t b2 : 7; uint8_t b3 : 2;
+} sbf_18b;
+struct
+{
+  uint16_t bf1 : 8;
+  uint8_t c;
+  uint16_t bf2 : 8;
+  uint32_t bf3 : 12;
+  uint16_t s;
+} sbf_gaps;
+typedef struct
+{
+  uint16_t bf1 : 8;
+  uint8_t c;
+  uint16_t bf2 : 8;
+  uint32_t bf3 : 12;
+  uint16_t s;
+} tsbf_gaps;
+
+/* unions */
+typedef union { } tue;
+union { } ue;
+typedef union { uint8_t c; uint64_t l; } tu1;
+union { uint8_t c; uint64_t l; } u1;
+typedef union { uint64_t l; uint8_t c; } tu2;
+union { uint64_t l; uint8_t c; } u2;
+typedef union { uint64_t l[3]; uint8_t c; } tu3;
+union { uint64_t l[3]; uint8_t c; } u3;
+typedef struct { union { uint8_t c; uint64_t l; }; } tsu_anon;
+struct { union { uint8_t c; uint64_t l; }; } su_anon;
+typedef union { uint64_t bf : 1; uint8_t ca[5]; } tu_size;
+union { uint64_t bf : 1; uint8_t ca[5]; } u_size;
+typedef union { uint64_t : 1; uint8_t ca[5]; } tu2_size;
+union { uint64_t : 1; uint8_t ca[5]; } u2_size;
+typedef union u_undef_t u_undef_t2;
+typedef union { uint64_t b : 1; uint8_t ca[5]; } tu3_size;
+union { uint64_t b : 1; uint8_t ca[5]; } u3_size;
+
+/* functions */
+extern uint32_t func1(uint8_t c);
+typedef int8_t (*func_t)(void *p);
+
+/* Necessary quoting in the regexp patters:
+
+     (?n) at beginning of pattern to make ^ and $ work.
+     "     ->  \"
+     *, +  ->  "*", "+"
+     [, ]  ->  "\[", "\]"
+     (, )  ->  "\[(\]", "\[)\]"
+     {, }  ->  "\{", "\}"
+*/
+
+/* { dg-final { scan-file godump-1.out "(?n)^type _c_t u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _s_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _l_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ll_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _uc_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _us_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ui_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ul_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ull_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sc_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ss_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _si_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sl_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sll_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i8_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i16_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i32_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _i64_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ui8_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu16_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu32_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _iu64_t uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _cc_t u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _vp_t \\*byte$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ipp_t \\*\\*int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ca_t \\\[0\\\]u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _sa2_t \\\[1\\+1\\\]int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _f_t float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _d_t float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// type _ld_t INVALID-float-\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni2_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ni3_t int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _et_t int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts0e struct \{ \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts1e struct \{ e1 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts2el struct \{ e1 int\[0-9\]*; e2 \\*byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _ts2eg struct \{ e1 \\*byte; e2 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsme struct \{ l int\[0-9\]*; c int\[0-9\]*; i int\[0-9\]*; s int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsae struct \{ sa \\\[2\\+1\\\]int\[0-9\]*; ca \\\[2\\+1\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsf_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsf_not_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsd_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsd_not_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsn struct \{ s struct \{ ca \\\[2\\+1\\\]uint\[0-9\]*; \}; i uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsn_anon struct \{ Godump_0 struct \{ a uint\[0-9\]*; s uint\[0-9\]*; \}; b uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad1 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad3 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad4 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad5 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad6 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad7 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_anon_pad8 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad8_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_2 struct \{ Godump_0_pad \\\[2\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad16_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_2 struct \{ Godump_0_pad \\\[4\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad32_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_2 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_pad64_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_1b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_8b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_9b struct \{ Godump_0_pad \\\[2\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_18b struct \{ Godump_0_pad \\\[3\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsbf_gaps struct \{ bf1 uint\[0-9\]*; c uint\[0-9\]*; bf2 uint\[0-9\]*; Godump_0_pad \\\[2\\\]byte; s uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tue struct \{ Godump_0 \\\[0\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu1 struct \{ c \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu2 struct \{ l \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu3 struct \{ l \\\[24\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tsu_anon struct \{ Godump_0 struct \{ c \\\[8\\\]byte; Godump_1_align \\\[0\\\]uint64; \}; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu_size struct \{ bf \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu2_size struct \{ Godump_0 \\\[5\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _tu3_size struct \{ b \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _func_t func\[(\]\\*byte\[)\] int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _c_v1 u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _c_v2 _c_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s_v2 _s_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i_v2 _i_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _l_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _l_v2 _l_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ll_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ll_v2 _ll_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _uc_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _uc_v2 _uc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _us_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _us_v2 _us_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui_v2 _ui_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ul_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ul_v2 _ul_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ull_v1 uint\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ull_v2 _ull_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sc_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sc_v2 _sc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ss_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ss_v2 _ss_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _si_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _si_v2 _si_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sl_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sl_v2 _sl_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sll_v1 int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sll_v2 _sll_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i8_v1 _int8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i8_v2 _i8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i16_v1 _int16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i16_v2 _i16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i32_v1 _int32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i32_v2 _i32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i64_v1 _int64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _i64_v2 _i64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui8_v1 _uint8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ui8_v2 _ui8_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu16_v1 _uint16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu16_v2 _iu16_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu32_v1 _uint32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu32_v2 _iu32_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu64_v1 _uint64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _iu64_v2 _iu64_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cc_v1 u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cc_v2 _cc_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _vp_v1 \\*byte$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _vp_v2 _vp_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ipp_v1 \\*\\*int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ipp_v2 _ipp_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v1 \\\[0\\+1\\\]u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v1b \\\[1\\+1\\\]u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ca_v2 \\\[0\\+1\\\]u?int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sa2_v1 \\\[1\\+1\\\]int\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sa2_v2 _sa2_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _f_v1 float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _f_v2 _f_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _d_v1 float\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _d_v2 _d_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v1 INVALID-float-\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v2 INVALID-float-\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ni2_v2 _ni2_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ni3_v2 _ni3_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _e1_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _e2_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _et_v1 int$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _et_v2 _et_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s0e struct \{ \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s1e struct \{ e1 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s2el struct \{ e1 int\[0-9\]*; e2 \\*byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _s2eg struct \{ e1 \\*byte; e2 int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sme struct \{ l int\[0-9\]*; c int\[0-9\]*; i int\[0-9\]*; s int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sae struct \{ sa \\\[2\\+1\\\]int\[0-9\]*; ca \\\[2\\+1\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sf_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sf_not_equiv struct \{ f float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sd_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sd_not_equiv struct \{ d float\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sn struct \{ s struct \{ ca \\\[2\\+1\\\]uint\[0-9\]*; \}; i uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sn_anon struct \{ Godump_0 struct \{ a uint\[0-9\]*; s uint\[0-9\]*; \}; b uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad1 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad3 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad4 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad5 struct \{ c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad6 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad7 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_anon_pad8 struct \{ Godump_0 uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_2 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad8_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_2 struct \{ Godump_0_pad \\\[2\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad16_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_2 struct \{ Godump_0_pad \\\[4\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad32_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_1 struct \{ Godump_0_pad \\\[1\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_2 struct \{ Godump_0_pad \\\[8\\\]byte; c uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_pad64_3 struct \{ bf uint\[0-9\]*; c uint\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_1b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_8b struct \{ Godump_0_pad \\\[1\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_9b struct \{ Godump_0_pad \\\[2\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_18b struct \{ Godump_0_pad \\\[3\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _sbf_gaps struct \{ bf1 uint\[0-9\]*; c uint\[0-9\]*; bf2 uint\[0-9\]*; Godump_0_pad \\\[2\\\]byte; s uint\[0-9\]*; Godump_1_align \\\[0\\\]int\[0-9\]*; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _ue struct \{ Godump_0 \\\[0\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u1 struct \{ c \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u2 struct \{ l \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u3 struct \{ l \\\[24\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _su_anon struct \{ Godump_0 struct \{ c \\\[8\\\]byte; Godump_1_align \\\[0\\\]uint64; \}; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u_size struct \{ bf \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u2_size struct \{ Godump_0 \\\[5\\\]byte; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _u3_size struct \{ b \\\[8\\\]byte; Godump_0_align \\\[0\\\]uint64; \}$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^func _func1 \[(\]uint\[0-9\]*\[)\] uint\[0-9\]* __asm__\[(\]\"func1\"\[)\]$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E11 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E21 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _E22 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN1 = 3$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN2 = 77$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN3 = -1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EN4 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ET1 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ET2 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ETV1 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _ETV2 = 1$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV11 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV21 = 0$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^const _EV22 = 1$" } } */
Index: testsuite/gcc.misc-tests/godump.exp
===================================================================
--- testsuite/gcc.misc-tests/godump.exp	(revision 0)
+++ testsuite/gcc.misc-tests/godump.exp	(working copy)
@@ -0,0 +1,36 @@
+# Copyright (C) 2014 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3.  If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+    set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/godump-*.c]] \
+	"" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-28 17:37       ` Ian Taylor
@ 2014-10-29  9:05         ` Dominik Vogt
  0 siblings, 0 replies; 38+ messages in thread
From: Dominik Vogt @ 2014-10-29  9:05 UTC (permalink / raw)
  To: gcc-patches, gofrontend-dev

On Tue, Oct 28, 2014 at 10:30:08AM -0700, Ian Taylor wrote:
> On Tue, Oct 28, 2014 at 7:31 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> > The attached patch contains all the discussed changes.
> I made a few formatting changes.  I patched the test to work on x86,
> by making the char types accept either int8 or uint8, and making the
> long double tests accept any floating point size.
> 
> Approved and applied as attached.

Great, thanks!  By the way, the changes I made to this patch do not
interfer with patch #8 (complex type support for -fdump-go-spec) in
any way - it should still apply without conflict.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 8/9] Gccgo port to s390[x] -- part I
  2014-10-17  0:03   ` [gofrontend-dev] " Ian Lance Taylor
@ 2014-10-29  9:13     ` Dominik Vogt
  2014-10-29 15:22       ` Ian Taylor
  0 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-10-29  9:13 UTC (permalink / raw)
  To: gcc-patches, gofrontend-dev

[-- Attachment #1: Type: text/plain, Size: 120 bytes --]

Patch updated to remove conflicts with changed tests in patch 7.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0008-godump-Support-_Complex-types-in-go_format_type.patch --]
[-- Type: text/x-diff, Size: 4520 bytes --]

From e81ca934b619cad8b3872f28edbf3d2d0afeeec9 Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Fri, 5 Sep 2014 07:31:01 +0100
Subject: [PATCH 8/9] Gccgo port to s390[x] -- part I

godump: Support _Complex types in go_format_type.

1) float/double _Complex are represented as complex64/complex128 in Go as
appropriate.

2) Add tests.

---
 gcc/godump.c                            | 34 +++++++++++++++++++++++++++++++++
 gcc/testsuite/gcc.misc-tests/godump-1.c | 30 +++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+)

diff --git a/gcc/godump.c b/gcc/godump.c
index 7a05664..fccd3eb 100644
--- a/gcc/godump.c
+++ b/gcc/godump.c
@@ -780,6 +780,40 @@ go_format_type (struct godump_container *container, tree type,
       }
       break;
 
+    case COMPLEX_TYPE:
+      {
+	const char *s;
+	char buf[100];
+	tree real_type;
+
+	real_type = TREE_TYPE (type);
+	if (TREE_CODE (real_type) == REAL_TYPE)
+	  {
+	    switch (TYPE_PRECISION (real_type))
+	      {
+	      case 32:
+		s = "complex64";
+		break;
+	      case 64:
+		s = "complex128";
+		break;
+	      default:
+		snprintf (buf, sizeof buf, "INVALID-complex-%u",
+			  2 * TYPE_PRECISION (real_type));
+		s = buf;
+		ret = false;
+		break;
+	      }
+	  }
+	else
+	  {
+	    s = "INVALID-complex-non-real";
+	    ret = false;
+	  }
+	obstack_grow (ob, s, strlen (s));
+      }
+      break;
+
     case BOOLEAN_TYPE:
       obstack_grow (ob, "bool", 4);
       break;
diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c b/gcc/testsuite/gcc.misc-tests/godump-1.c
index 876cf28..f339cc9 100644
--- a/gcc/testsuite/gcc.misc-tests/godump-1.c
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -104,6 +104,21 @@ d_t d_v2;
 typedef long double ld_t;
 long double ld_v1;
 ld_t ld_v2;
+typedef _Complex cx_t;
+_Complex cx_v1;
+cx_t cx_v2;
+typedef float _Complex fcx_t;
+float _Complex fcx_v1;
+fcx_t fcx_v2;
+typedef double _Complex dcx_t;
+double _Complex dcx_v1;
+dcx_t dcx_v2;
+typedef long double _Complex ldcx_t;
+long double _Complex ldcx_v1;
+ldcx_t ldcx_v2;
+typedef int _Complex icx_t;
+int _Complex icx_v1;
+icx_t icx_v2;
 
 /* nested typedefs */
 typedef int ni_t;
@@ -301,6 +316,11 @@ typedef int8_t (*func_t)(void *p);
 /* { dg-final { scan-file godump-1.out "(?n)^type _f_t float\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^type _d_t float\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^// type _ld_t INVALID-float-\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _cx_t complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _fcx_t complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^type _dcx_t complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// type _ldcx_t INVALID-complex-256$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// type _icx_t INVALID-complex-non-real$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^type _ni_t int\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^type _ni2_t int\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^type _ni3_t int\[0-9\]*$" } } */
@@ -414,6 +434,16 @@ typedef int8_t (*func_t)(void *p);
 /* { dg-final { scan-file godump-1.out "(?n)^var _d_v2 _d_t$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v1 INVALID-float-\[0-9\]*$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^// var _ld_v2 INVALID-float-\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cx_v1 complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _cx_v2 _cx_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _fcx_v1 complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _fcx_v2 _fcx_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _dcx_v1 complex\[0-9\]*$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^var _dcx_v2 _dcx_t$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ldcx_v1 INVALID-complex-256$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _ldcx_v2 INVALID-complex-256$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _icx_v1 INVALID-complex-non-real$" } } */
+/* { dg-final { scan-file godump-1.out "(?n)^// var _icx_v2 INVALID-complex-non-real$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^var _ni2_v2 _ni2_t$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^var _ni3_v2 _ni3_t$" } } */
 /* { dg-final { scan-file godump-1.out "(?n)^var _e1_v1 int$" } } */
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] [PATCH 8/9] Gccgo port to s390[x] -- part I
  2014-10-29  9:13     ` Dominik Vogt
@ 2014-10-29 15:22       ` Ian Taylor
  0 siblings, 0 replies; 38+ messages in thread
From: Ian Taylor @ 2014-10-29 15:22 UTC (permalink / raw)
  To: vogt, gcc-patches, gofrontend-dev

On Wed, Oct 29, 2014 at 12:01 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> Patch updated to remove conflicts with changed tests in patch 7.

Thanks.  Approved and committed.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-29 16:43   ` Andreas Schwab
@ 2014-10-29 16:43     ` Ian Taylor
  2014-10-29 17:05       ` Andreas Schwab
  0 siblings, 1 reply; 38+ messages in thread
From: Ian Taylor @ 2014-10-29 16:43 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: gcc-patches, gofrontend-dev

On Wed, Oct 29, 2014 at 9:38 AM, Andreas Schwab <schwab@suse.de> wrote:
> I'm getting these test failures on m68k-linux:

Can you send the file BUILDDIR/gcc/testsuite/gcc/godump-1.out?

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-09-09 13:02 ` [PATCH 7/9] " Dominik Vogt
  2014-10-16 23:46   ` [gofrontend-dev] " Ian Lance Taylor
@ 2014-10-29 16:43   ` Andreas Schwab
  2014-10-29 16:43     ` [gofrontend-dev] " Ian Taylor
  1 sibling, 1 reply; 38+ messages in thread
From: Andreas Schwab @ 2014-10-29 16:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: gofrontend-dev

I'm getting these test failures on m68k-linux:

FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_anon_pad1 struct { c uint[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_anon_pad5 struct { c uint[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_pad16_1 struct { Godump_0_pad \\[1\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_pad16_2 struct { Godump_0_pad \\[2\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_pad32_1 struct { Godump_0_pad \\[1\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_pad32_2 struct { Godump_0_pad \\[4\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_pad64_1 struct { Godump_0_pad \\[1\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_pad64_2 struct { Godump_0_pad \\[8\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_18b struct { Godump_0_pad \\[3\\]byte; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsbf_gaps struct { bf1 uint[0-9]*; c uint[0-9]*; bf2 uint[0-9]*; Godump_0_pad \\[2\\]byte; s uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tu1 struct { c \\[8\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tu2 struct { l \\[8\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tu3 struct { l \\[24\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tsu_anon struct { Godump_0 struct { c \\[8\\]byte; Godump_1_align \\[0\\]uint64; }; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tu_size struct { bf \\[8\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^type _tu3_size struct { b \\[8\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_anon_pad1 struct { c uint[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_anon_pad5 struct { c uint[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_pad16_1 struct { Godump_0_pad \\[1\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_pad16_2 struct { Godump_0_pad \\[2\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_pad32_1 struct { Godump_0_pad \\[1\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_pad32_2 struct { Godump_0_pad \\[4\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_pad64_1 struct { Godump_0_pad \\[1\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_pad64_2 struct { Godump_0_pad \\[8\\]byte; c uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_18b struct { Godump_0_pad \\[3\\]byte; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _sbf_gaps struct { bf1 uint[0-9]*; c uint[0-9]*; bf2 uint[0-9]*; Godump_0_pad \\[2\\]byte; s uint[0-9]*; Godump_1_align \\[0\\]int[0-9]*; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _u1 struct { c \\[8\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _u2 struct { l \\[8\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _u3 struct { l \\[24\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _su_anon struct { Godump_0 struct { c \\[8\\]byte; Godump_1_align \\[0\\]uint64; }; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _u_size struct { bf \\[8\\]byte; Godump_0_align \\[0\\]uint64; }$
FAIL: gcc.misc-tests/godump-1.c scan-file (?n)^var _u3_size struct { b \\[8\\]byte; Godump_0_align \\[0\\]uint64; }$

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-29 16:43     ` [gofrontend-dev] " Ian Taylor
@ 2014-10-29 17:05       ` Andreas Schwab
  2014-10-29 17:50         ` Ian Taylor
  0 siblings, 1 reply; 38+ messages in thread
From: Andreas Schwab @ 2014-10-29 17:05 UTC (permalink / raw)
  To: Ian Taylor; +Cc: gcc-patches, gofrontend-dev

// unknowndefine __SIZE_TYPE__ unsigned int
// unknowndefine __PTRDIFF_TYPE__ int
// unknowndefine __WCHAR_TYPE__ long int
// unknowndefine __WINT_TYPE__ unsigned int
// unknowndefine __INTMAX_TYPE__ long long int
// unknowndefine __UINTMAX_TYPE__ long long unsigned int
// unknowndefine __CHAR16_TYPE__ short unsigned int
// unknowndefine __CHAR32_TYPE__ unsigned int
// unknowndefine __SIG_ATOMIC_TYPE__ int
// unknowndefine __INT8_TYPE__ signed char
// unknowndefine __INT16_TYPE__ short int
// unknowndefine __INT32_TYPE__ int
// unknowndefine __INT64_TYPE__ long long int
// unknowndefine __UINT8_TYPE__ unsigned char
// unknowndefine __UINT16_TYPE__ short unsigned int
// unknowndefine __UINT32_TYPE__ unsigned int
// unknowndefine __UINT64_TYPE__ long long unsigned int
// unknowndefine __INT_LEAST8_TYPE__ signed char
// unknowndefine __INT_LEAST16_TYPE__ short int
// unknowndefine __INT_LEAST32_TYPE__ int
// unknowndefine __INT_LEAST64_TYPE__ long long int
// unknowndefine __UINT_LEAST8_TYPE__ unsigned char
// unknowndefine __UINT_LEAST16_TYPE__ short unsigned int
// unknowndefine __UINT_LEAST32_TYPE__ unsigned int
// unknowndefine __UINT_LEAST64_TYPE__ long long unsigned int
// unknowndefine __INT_FAST8_TYPE__ signed char
// unknowndefine __INT_FAST16_TYPE__ int
// unknowndefine __INT_FAST32_TYPE__ int
// unknowndefine __INT_FAST64_TYPE__ long long int
// unknowndefine __UINT_FAST8_TYPE__ unsigned char
// unknowndefine __UINT_FAST16_TYPE__ unsigned int
// unknowndefine __UINT_FAST32_TYPE__ unsigned int
// unknowndefine __UINT_FAST64_TYPE__ long long unsigned int
// unknowndefine __INTPTR_TYPE__ int
// unknowndefine __UINTPTR_TYPE__ unsigned int
// unknowndefine __DBL_MAX__ ((double)1.1)
// unknowndefine __DBL_MIN__ ((double)1.1)
// unknowndefine __DBL_EPSILON__ ((double)1.1)
// unknowndefine __DBL_DENORM_MIN__ ((double)1.1)
// unknowndefine __REGISTER_PREFIX__ %
// unknowndefine __LEAF , __leaf__
// unknowndefine __LEAF_ATTR __attribute__ ((__leaf__))
// unknowndefine __THROW __attribute__ ((__nothrow__ __LEAF))
// unknowndefine __THROWNL __attribute__ ((__nothrow__))
// unknowndefine __ptr_t void *
// unknowndefine __long_double_t long double
// unknowndefine __fortify_function __extern_always_inline __attribute_artificial__
// unknowndefine __flexarr []
// unknowndefine __attribute_malloc__ __attribute__ ((__malloc__))
// unknowndefine __attribute_pure__ __attribute__ ((__pure__))
// unknowndefine __attribute_const__ __attribute__ ((__const__))
// unknowndefine __attribute_used__ __attribute__ ((__used__))
// unknowndefine __attribute_noinline__ __attribute__ ((__noinline__))
// unknowndefine __attribute_deprecated__ __attribute__ ((__deprecated__))
// unknowndefine __attribute_warn_unused_result__ __attribute__ ((__warn_unused_result__))
// unknowndefine __always_inline __inline __attribute__ ((__always_inline__))
// unknowndefine __attribute_artificial__ __attribute__ ((__artificial__))
// unknowndefine __extern_inline extern __inline __attribute__ ((__gnu_inline__))
// unknowndefine __extern_always_inline extern __always_inline __attribute__ ((__gnu_inline__))
// unknowndefine __restrict_arr __restrict
// unknowndefine INT64_MIN (-__INT64_C(9223372036854775807)-1)
// unknowndefine INT64_MAX (__INT64_C(9223372036854775807))
// unknowndefine UINT64_MAX (__UINT64_C(18446744073709551615))
// unknowndefine INT_LEAST64_MIN (-__INT64_C(9223372036854775807)-1)
// unknowndefine INT_LEAST64_MAX (__INT64_C(9223372036854775807))
// unknowndefine UINT_LEAST64_MAX (__UINT64_C(18446744073709551615))
// unknowndefine INT_FAST64_MIN (-__INT64_C(9223372036854775807)-1)
// unknowndefine INT_FAST64_MAX (__INT64_C(9223372036854775807))
// unknowndefine UINT_FAST64_MAX (__UINT64_C(18446744073709551615))
// unknowndefine INTMAX_MIN (-__INT64_C(9223372036854775807)-1)
// unknowndefine INTMAX_MAX (__INT64_C(9223372036854775807))
// unknowndefine UINTMAX_MAX (__UINT64_C(18446744073709551615))
type _int8_t int8
type _int16_t int16
type _int32_t int32
type _int64_t int64
type _uint8_t uint8
type _uint16_t uint16
type _uint32_t uint32
type _uint64_t uint64
type _int_least8_t int8
type _int_least16_t int16
type _int_least32_t int32
type _int_least64_t int64
type _uint_least8_t uint8
type _uint_least16_t uint16
type _uint_least32_t uint32
type _uint_least64_t uint64
type _int_fast8_t int8
type _int_fast16_t int32
type _int_fast32_t int32
type _int_fast64_t int64
type _uint_fast8_t uint8
type _uint_fast16_t uint32
type _uint_fast32_t uint32
type _uint_fast64_t uint64
type _intptr_t int32
type _uintptr_t uint32
type _intmax_t int64
type _uintmax_t uint64
type _c_t int8
type _s_t int16
type _i_t int32
type _l_t int32
type _ll_t int64
type _uc_t uint8
type _us_t uint16
type _ui_t uint32
type _ul_t uint32
type _ull_t uint64
type _sc_t int8
type _ss_t int16
type _si_t int32
type _sl_t int32
type _sll_t int64
type _i8_t int8
type _i16_t int16
type _i32_t int32
type _i64_t int64
type _ui8_t uint8
type _iu16_t uint16
type _iu32_t uint32
type _iu64_t uint64
type _cc_t int8
type _vp_t *byte
type _ipp_t **int32
type _ca_t [0]int8
type _sa2_t [1+1]int16
type _f_t float32
type _d_t float64
// type _ld_t INVALID-float-80
type _ni_t int32
type _ni2_t int32
type _ni3_t int32
type _et_t int
type _ts0e struct { }
type _ts1e struct { e1 int8; }
const _sizeof_ts1e = 1
type _ts2el struct { e1 int8; e2 *byte; }
const _sizeof_ts2el = 6
type _ts2eg struct { e1 *byte; e2 int8; }
const _sizeof_ts2eg = 6
type _tsme struct { l int64; c int8; i int32; s int16; }
const _sizeof_tsme = 16
type _tsae struct { sa [2+1]int16; ca [2+1]int8; }
const _sizeof_tsae = 10
type _tsf_equiv struct { f float32; }
const _sizeof_tsf_equiv = 4
type _tsf_not_equiv struct { f float32; }
const _sizeof_tsf_not_equiv = 4
type _tsd_equiv struct { d float64; }
const _sizeof_tsd_equiv = 8
type _tsd_not_equiv struct { d float64; }
const _sizeof_tsd_not_equiv = 8
type _s_undef_t2 struct { }
type _tsn struct { s struct { ca [2+1]uint8; }; i uint32; }
const _sizeof_tsn = 8
type _tsn_anon struct { Godump_0 struct { a uint8; s uint16; }; b uint8; }
const _sizeof_tsn_anon = 6
type _tsbf_anon_pad1 struct { c uint8; Godump_0_align [0]int16; }
const _sizeof_tsbf_anon_pad1 = 2
type _tsbf_anon_pad2 struct { Godump_0_pad [1]byte; c uint8; }
const _sizeof_tsbf_anon_pad2 = 2
type _tsbf_anon_pad3 struct { Godump_0_pad [1]byte; c uint8; }
const _sizeof_tsbf_anon_pad3 = 2
type _tsbf_anon_pad4 struct { Godump_0 uint8; c uint8; }
const _sizeof_tsbf_anon_pad4 = 2
type _tsbf_anon_pad5 struct { c uint8; Godump_0_align [0]int16; }
const _sizeof_tsbf_anon_pad5 = 2
type _tsbf_anon_pad6 struct { Godump_0_pad [1]byte; c uint8; }
const _sizeof_tsbf_anon_pad6 = 2
type _tsbf_anon_pad7 struct { Godump_0_pad [8]byte; c uint8; }
const _sizeof_tsbf_anon_pad7 = 9
type _tsbf_anon_pad8 struct { Godump_0 uint64; c uint8; }
const _sizeof_tsbf_anon_pad8 = 10
type _tsbf_pad8_1 struct { Godump_0_pad [1]byte; c uint8; }
const _sizeof_tsbf_pad8_1 = 2
type _tsbf_pad8_2 struct { Godump_0_pad [1]byte; c uint8; }
const _sizeof_tsbf_pad8_2 = 2
type _tsbf_pad8_3 struct { bf uint8; c uint8; }
const _sizeof_tsbf_pad8_3 = 2
type _tsbf_pad16_1 struct { Godump_0_pad [1]byte; c uint8; }
const _sizeof_tsbf_pad16_1 = 2
type _tsbf_pad16_2 struct { Godump_0_pad [2]byte; c uint8; }
const _sizeof_tsbf_pad16_2 = 3
type _tsbf_pad16_3 struct { bf uint16; c uint8; }
const _sizeof_tsbf_pad16_3 = 4
type _tsbf_pad32_1 struct { Godump_0_pad [1]byte; c uint8; }
const _sizeof_tsbf_pad32_1 = 2
type _tsbf_pad32_2 struct { Godump_0_pad [4]byte; c uint8; }
const _sizeof_tsbf_pad32_2 = 5
type _tsbf_pad32_3 struct { bf uint32; c uint8; }
const _sizeof_tsbf_pad32_3 = 6
type _tsbf_pad64_1 struct { Godump_0_pad [1]byte; c uint8; }
const _sizeof_tsbf_pad64_1 = 2
type _tsbf_pad64_2 struct { Godump_0_pad [8]byte; c uint8; }
const _sizeof_tsbf_pad64_2 = 9
type _tsbf_pad64_3 struct { bf uint64; c uint8; }
const _sizeof_tsbf_pad64_3 = 10
type _tsbf_1b struct { Godump_0_pad [1]byte; }
const _sizeof_tsbf_1b = 1
type _tsbf_8b struct { Godump_0_pad [1]byte; }
const _sizeof_tsbf_8b = 1
type _tsbf_9b struct { Godump_0_pad [2]byte; }
const _sizeof_tsbf_9b = 2
type _tsbf_18b struct { Godump_0_pad [2]byte; }
const _sizeof_tsbf_18b = 2
type _tsbf_gaps struct { bf1 uint8; c uint8; bf2 uint8; Godump_0_pad [2]byte; s uint16; }
const _sizeof_tsbf_gaps = 8
type _tue struct { Godump_0 [0]byte; }
type _tu1 struct { c [8]byte; Godump_0_align [0]uint16; }
const _sizeof_tu1 = 8
type _tu2 struct { l [8]byte; Godump_0_align [0]uint16; }
const _sizeof_tu2 = 8
type _tu3 struct { l [24]byte; Godump_0_align [0]uint16; }
const _sizeof_tu3 = 24
type _tsu_anon struct { Godump_0 struct { c [8]byte; Godump_1_align [0]uint16; }; }
const _sizeof_tsu_anon = 8
type _tu_size struct { bf [5]byte; }
const _sizeof_tu_size = 5
type _tu2_size struct { Godump_0 [5]byte; }
const _sizeof_tu2_size = 5
type _u_undef_t2 struct { Godump_0 [0]byte; }
type _tu3_size struct { b [5]byte; }
const _sizeof_tu3_size = 5
type _func_t func(*byte) int8
var _c_v1 int8
var _c_v2 _c_t
var _s_v1 int16
var _s_v2 _s_t
var _i_v1 int32
var _i_v2 _i_t
var _l_v1 int32
var _l_v2 _l_t
var _ll_v1 int64
var _ll_v2 _ll_t
var _uc_v1 uint8
var _uc_v2 _uc_t
var _us_v1 uint16
var _us_v2 _us_t
var _ui_v1 uint32
var _ui_v2 _ui_t
var _ul_v1 uint32
var _ul_v2 _ul_t
var _ull_v1 uint64
var _ull_v2 _ull_t
var _sc_v1 int8
var _sc_v2 _sc_t
var _ss_v1 int16
var _ss_v2 _ss_t
var _si_v1 int32
var _si_v2 _si_t
var _sl_v1 int32
var _sl_v2 _sl_t
var _sll_v1 int64
var _sll_v2 _sll_t
var _i8_v1 _int8_t
var _i8_v2 _i8_t
var _i16_v1 _int16_t
var _i16_v2 _i16_t
var _i32_v1 _int32_t
var _i32_v2 _i32_t
var _i64_v1 _int64_t
var _i64_v2 _i64_t
var _ui8_v1 _uint8_t
var _ui8_v2 _ui8_t
var _iu16_v1 _uint16_t
var _iu16_v2 _iu16_t
var _iu32_v1 _uint32_t
var _iu32_v2 _iu32_t
var _iu64_v1 _uint64_t
var _iu64_v2 _iu64_t
var _cc_v1 int8
var _cc_v2 _cc_t
var _vp_v1 *byte
var _vp_v2 _vp_t
var _ipp_v1 **int32
var _ipp_v2 _ipp_t
var _ca_v1 [0+1]int8
var _ca_v1b [1+1]int8
var _ca_v2 [0+1]int8
var _sa2_v1 [1+1]int16
var _sa2_v2 _sa2_t
var _f_v1 float32
var _f_v2 _f_t
var _d_v1 float64
var _d_v2 _d_t
// var _ld_v1 INVALID-float-80
// var _ld_v2 INVALID-float-80
var _ni2_v2 _ni2_t
var _ni3_v2 _ni3_t
var _e1_v1 int
var _e2_v1 int
var _et_v1 int
var _et_v2 _et_t
var _s0e struct { }
var _s1e struct { e1 int8; }
var _s2el struct { e1 int8; e2 *byte; }
var _s2eg struct { e1 *byte; e2 int8; }
var _sme struct { l int64; c int8; i int32; s int16; }
var _sae struct { sa [2+1]int16; ca [2+1]int8; }
var _sf_equiv struct { f float32; }
var _sf_not_equiv struct { f float32; }
var _sd_equiv struct { d float64; }
var _sd_not_equiv struct { d float64; }
var _sn struct { s struct { ca [2+1]uint8; }; i uint32; }
var _sn_anon struct { Godump_0 struct { a uint8; s uint16; }; b uint8; }
var _sbf_anon_pad1 struct { c uint8; Godump_0_align [0]int16; }
var _sbf_anon_pad2 struct { Godump_0_pad [1]byte; c uint8; }
var _sbf_anon_pad3 struct { Godump_0_pad [1]byte; c uint8; }
var _sbf_anon_pad4 struct { Godump_0 uint8; c uint8; }
var _sbf_anon_pad5 struct { c uint8; Godump_0_align [0]int16; }
var _sbf_anon_pad6 struct { Godump_0_pad [1]byte; c uint8; }
var _sbf_anon_pad7 struct { Godump_0_pad [8]byte; c uint8; }
var _sbf_anon_pad8 struct { Godump_0 uint64; c uint8; }
var _sbf_pad8_1 struct { Godump_0_pad [1]byte; c uint8; }
var _sbf_pad8_2 struct { Godump_0_pad [1]byte; c uint8; }
var _sbf_pad8_3 struct { bf uint8; c uint8; }
var _sbf_pad16_1 struct { Godump_0_pad [1]byte; c uint8; }
var _sbf_pad16_2 struct { Godump_0_pad [2]byte; c uint8; }
var _sbf_pad16_3 struct { bf uint16; c uint8; }
var _sbf_pad32_1 struct { Godump_0_pad [1]byte; c uint8; }
var _sbf_pad32_2 struct { Godump_0_pad [4]byte; c uint8; }
var _sbf_pad32_3 struct { bf uint32; c uint8; }
var _sbf_pad64_1 struct { Godump_0_pad [1]byte; c uint8; }
var _sbf_pad64_2 struct { Godump_0_pad [8]byte; c uint8; }
var _sbf_pad64_3 struct { bf uint64; c uint8; }
var _sbf_1b struct { Godump_0_pad [1]byte; }
var _sbf_8b struct { Godump_0_pad [1]byte; }
var _sbf_9b struct { Godump_0_pad [2]byte; }
var _sbf_18b struct { Godump_0_pad [2]byte; }
var _sbf_gaps struct { bf1 uint8; c uint8; bf2 uint8; Godump_0_pad [2]byte; s uint16; }
var _ue struct { Godump_0 [0]byte; }
var _u1 struct { c [8]byte; Godump_0_align [0]uint16; }
var _u2 struct { l [8]byte; Godump_0_align [0]uint16; }
var _u3 struct { l [24]byte; Godump_0_align [0]uint16; }
var _su_anon struct { Godump_0 struct { c [8]byte; Godump_1_align [0]uint16; }; }
var _u_size struct { bf [5]byte; }
var _u2_size struct { Godump_0 [5]byte; }
var _u3_size struct { b [5]byte; }
func _func1 (uint8) uint32 __asm__("func1")
const ___USE_BSD = 1
const _EV22 = 1
const ___ORDER_PDP_ENDIAN__ = 3412
const _UINT_FAST8_MAX = (255)
const _INT_FAST8_MIN = (-128)
const ___FLT_MANT_DIG__ = 24
const ___DEC64_MANT_DIG__ = 16
const ___INT_LEAST64_MAX__ = 0x7fffffffffffffff
const ___DBL_MIN_EXP__ = (-1021)
const ___m68k__ = 1
const ___LONG_MAX__ = 0x7fffffff
const _EN3 = -1
const ___INT_FAST16_MAX__ = 0x7fffffff
const ___STDC_UTF_32__ = 1
const _ET1 = 0
const _unix = 1
const ___UINTPTR_MAX__ = 0xffffffff
const ___FLT_MIN__ = 1.1
const ___INT16_MAX__ = 0x7fff
const ___FLT_MIN_EXP__ = (-125)
const ___INT_LEAST8_MAX__ = 0x7f
const ___SIG_ATOMIC_MAX__ = 0x7fffffff
const ___mc68020 = 1
const ___GCC_ATOMIC_BOOL_LOCK_FREE = 2
const ___USE_ATFILE = 1
const _UINT_LEAST16_MAX = (65535)
const ___SIZEOF_PTRDIFF_T__ = 4
const ___ORDER_BIG_ENDIAN__ = 4321
const ___UINT_FAST64_MAX__ = 0xffffffffffffffff
const ___SIG_ATOMIC_MIN__ = (-___SIG_ATOMIC_MAX__ - 1)
const _INT_LEAST16_MIN = (-32767-1)
const _E11 = 0
const _ETV2 = 1
const __BITS_WCHAR_H = 1
const ___FLT_RADIX__ = 2
const ___GCC_IEC_559 = 2
const ___DEC32_SUBNORMAL_MIN__ = 0.000001E-95
const _INT_LEAST32_MIN = (-2147483647-1)
const ___mc68020__ = 1
const ___ATOMIC_ACQUIRE = 2
const ___FLT_MAX__ = 1.1
const ___PRAGMA_REDEFINE_EXTNAME = 1
const ___DECIMAL_DIG__ = 21
const ___USE_ISOC95 = 1
const ___UINTMAX_MAX__ = 0xffffffffffffffff
const ___GCC_ATOMIC_CHAR16_T_LOCK_FREE = 2
const ___STDC_VERSION__ = 201112
const ___UINT_LEAST16_MAX__ = 0xffff
const ___ATOMIC_RELAXED = 0
const ___FLT_DECIMAL_DIG__ = 9
const ___GCC_ATOMIC_CHAR32_T_LOCK_FREE = 2
const ___GCC_IEC_559_COMPLEX = 2
const ___DBL_HAS_DENORM__ = 1
const _INT8_MAX = (127)
const ___ELF__ = 1
const ___GCC_ATOMIC_TEST_AND_SET_TRUEVAL = 128
const ___SIZEOF_LONG_DOUBLE__ = 12
const ___SIZEOF_INT__ = 4
const ___DBL_DECIMAL_DIG__ = 17
const ___DEC32_MIN__ = 1E-95
const ___SIZEOF_WCHAR_T__ = 4
const ___STDC__ = 1
const _UINT8_MAX = (255)
const ___GNUC_MINOR__ = 0
const ___SIZEOF_WINT_T__ = 4
const _mc68020 = 1
const ___UINT_FAST16_MAX__ = 0xffffffff
const ___FLT_DENORM_MIN__ = 1.1
const ___linux = 1
const _INT_LEAST32_MAX = (2147483647)
const ___GCC_ATOMIC_LONG_LOCK_FREE = 2
const ___USE_POSIX2 = 1
const ___SIZEOF_SHORT__ = 2
const _PTRDIFF_MAX = (2147483647)
const _WCHAR_MAX = ___WCHAR_MAX
const ___DEC128_MIN__ = 1E-6143
const _UINT32_MAX = (4294967295)
const ___LDBL_HAS_INFINITY__ = 1
const ___INT_MAX__ = 0x7fffffff
const ___DEC32_MAX__ = 9.999999E96
const ___DBL_MAX_EXP__ = 1024
const _INT8_MIN = (-128)
const ___LDBL_MAX__ = 1.1
const ___DBL_MIN_10_EXP__ = (-307)
const ___LDBL_MAX_10_EXP__ = 4932
const ___GNUC_PATCHLEVEL__ = 0
const ___LDBL_HAS_QUIET_NAN__ = 1
const __POSIX_SOURCE = 1
const ___ORDER_LITTLE_ENDIAN__ = 1234
const ___UINT32_MAX__ = 0xffffffff
const ___DEC64_MIN_EXP__ = (-382)
const ___UINT_LEAST32_MAX__ = 0xffffffff
const ___LONG_LONG_MAX__ = 0x7fffffffffffffff
const ___DEC128_SUBNORMAL_MIN__ = 0.000000000000000000000000000000001E-6143
const ___FLT_MAX_EXP__ = 128
const ___ATOMIC_CONSUME = 1
const _INT_FAST32_MAX = (2147483647)
const ___USE_XOPEN2K = 1
const ___DBL_HAS_INFINITY__ = 1
const ___DEC128_MAX__ = 9.999999999999999999999999999999999E6144
const ___mc68000__ = 1
const ___UINT_LEAST8_MAX__ = 0xff
const ___DEC128_EPSILON__ = 1E-33
const __ATFILE_SOURCE = 1
const ___SIZEOF_SIZE_T__ = 4
const ___DBL_HAS_QUIET_NAN__ = 1
const ___INT_FAST32_MAX__ = 0x7fffffff
const ___ATOMIC_SEQ_CST = 5
const ___DEC128_MANT_DIG__ = 34
const _SIZE_MAX = (4294967295)
const ___SIZEOF_DOUBLE__ = 8
const ___INT32_MAX__ = 0x7fffffff
const ___LDBL_MANT_DIG__ = 64
const ___DEC128_MAX_EXP__ = 6145
const _ET2 = 1
const ___GLIBC__ = 2
const __STDINT_H = 1
const ___STDC_IEC_559__ = 1
const _UINT_FAST16_MAX = (4294967295)
const ___GCC_ATOMIC_INT_LOCK_FREE = 2
const ___FLT_HAS_INFINITY__ = 1
const ___WCHAR_MAX = ___WCHAR_MAX__
const ___FLT_MAX_10_EXP__ = 38
const ___USE_MISC = 1
const ___STDC_HOSTED__ = 1
const _UINT_FAST32_MAX = (4294967295)
const ___LDBL_MIN__ = 1.1
const _INT_LEAST8_MAX = (127)
const ___DEC32_MANT_DIG__ = 7
const ___GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 = 1
const ___GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 = 1
const ___FLOAT_WORD_ORDER__ = ___ORDER_BIG_ENDIAN__
const ___GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 = 1
const ___CHAR_BIT__ = 8
const ___GCC_ATOMIC_SHORT_LOCK_FREE = 2
const ___SHRT_MAX__ = 0x7fff
const ___HAVE_68881__ = 1
const _INT_LEAST8_MIN = (-128)
const ___STDC_ISO_10646__ = 201103
const ___LDBL_MAX_EXP__ = 16384
const _linux = 1
const ___WCHAR_MIN = ___WCHAR_MIN__
const _INTPTR_MIN = (-2147483647-1)
const ___FINITE_MATH_ONLY__ = 0
const ___USE_XOPEN2K8 = 1
const _SIG_ATOMIC_MIN = (-2147483647-1)
const _UINT16_MAX = (65535)
const ___DBL_MAX_10_EXP__ = 308
const ___STDC_UTF_16__ = 1
const ___SIZEOF_POINTER__ = 4
const ___GCC_ATOMIC_POINTER_LOCK_FREE = 2
const __STDC_PREDEF_H = 1
const ___INT_LEAST16_MAX__ = 0x7fff
const ___UINT_LEAST64_MAX__ = 0xffffffffffffffff
const ___FLT_EPSILON__ = 1.1
const ___DEC64_EPSILON__ = 1E-15
const ___GNU_LIBRARY__ = 6
const ___INTMAX_MAX__ = 0x7fffffffffffffff
const ___INTPTR_MAX__ = 0x7fffffff
const _UINTPTR_MAX = (4294967295)
const ___INT8_MAX__ = 0x7f
const ___SIZEOF_LONG_LONG__ = 8
const ___DBL_MANT_DIG__ = 53
const _WCHAR_MIN = ___WCHAR_MIN
const ___DEC64_MIN__ = 1E-383
const ___SIZEOF_LONG__ = 4
const ___gnu_linux__ = 1
const _EV21 = 0
const ___UINT64_MAX__ = 0xffffffffffffffff
const ___UINT_FAST32_MAX__ = 0xffffffff
const ___FLT_DIG__ = 6
const ___BYTE_ORDER__ = ___ORDER_BIG_ENDIAN__
const ___STDC_NO_THREADS__ = 1
const ___PTRDIFF_MAX__ = 0x7fffffff
const __BSD_SOURCE = 1
const ___UINT8_MAX__ = 0xff
const ___DEC32_MIN_EXP__ = (-94)
const ___VERSION__ = "5.0.0 20141029 (experimental)"
const ___linux__ = 1
const ___SCHAR_MAX__ = 0x7f
const ___GLIBC_MINOR__ = 18
const ___ATOMIC_ACQ_REL = 4
const ___DEC64_MAX__ = 9.999999999999999E384
const _INT_FAST16_MIN = (-2147483647-1)
const __SVID_SOURCE = 1
const ___WORDSIZE = 32
const ___WCHAR_MIN__ = (-___WCHAR_MAX__ - 1)
const ___DEC_EVAL_METHOD__ = 2
const ___GXX_ABI_VERSION = 999999
const ___unix = 1
const ___INT_FAST8_MAX__ = 0x7f
const ___GNUC_STDC_INLINE__ = 1
const _INT_FAST32_MIN = (-2147483647-1)
const _INT16_MAX = (32767)
const ___USE_POSIX199309 = 1
const _WINT_MAX = (4294967295)
const ___LDBL_MIN_10_EXP__ = (-4931)
const ___LDBL_EPSILON__ = 1.1
const __SYS_CDEFS_H = 1
const ___FLT_HAS_DENORM__ = 1
const _INT32_MAX = (2147483647)
const _INT16_MIN = (-32767-1)
const _WINT_MIN = (0)
const ___WCHAR_MAX__ = 0x7fffffff
const ___USE_POSIX_IMPLICITLY = 1
const _ETV1 = 0
const ___GCC_ATOMIC_WCHAR_T_LOCK_FREE = 2
const ___BIGGEST_ALIGNMENT__ = 2
const ___mc68000 = 1
const ___SIZE_MAX__ = 0xffffffff
const ___ATOMIC_RELEASE = 3
const ___INT64_MAX__ = 0x7fffffffffffffff
const ___USE_POSIX199506 = 1
const ___USE_ISOC11 = 1
const ___DEC64_SUBNORMAL_MIN__ = 0.000000000000001E-383
const ___DEC128_MIN_EXP__ = (-6142)
const ___WINT_MIN__ = 0
const ___FLT_HAS_QUIET_NAN__ = 1
const ___DEC32_EPSILON__ = 1E-6
const ___STDC_IEC_559_COMPLEX__ = 1
const ___USE_FORTIFY_LEVEL = 0
const _EV11 = 0
const _INTPTR_MAX = (2147483647)
const ___USE_POSIX = 1
const ___WINT_MAX__ = 0xffffffff
const _INT_FAST16_MAX = (2147483647)
const ___GCC_ATOMIC_CHAR_LOCK_FREE = 2
const ___LDBL_DENORM_MIN__ = 1.1
const ___DEC64_MAX_EXP__ = 385
const ___LDBL_DIG__ = 18
const ___DEC32_MAX_EXP__ = 97
const ___FLT_MIN_10_EXP__ = (-37)
const __POSIX_C_SOURCE = 200809
const ___GNUC__ = 5
const ___USE_ISOC99 = 1
const ___INT_LEAST32_MAX__ = 0x7fffffff
const _EN1 = 3
const _EN2 = 77
const ___SIZEOF_FLOAT__ = 4
const _EN4 = 0
const ___UINT_FAST8_MAX__ = 0xff
const _UINT_LEAST8_MAX = (255)
const ___LDBL_HAS_DENORM__ = 1
const ___LDBL_MIN_EXP__ = (-16382)
const _E21 = 0
const ___INT_FAST64_MAX__ = 0x7fffffffffffffff
const _E22 = 1
const ___NO_INLINE__ = 1
const __FEATURES_H = 1
const _UINT_LEAST32_MAX = (4294967295)
const ___unix__ = 1
const _mc68000 = 1
const _PTRDIFF_MIN = (-2147483647-1)
const ___USE_SVID = 1
const _INT_FAST8_MAX = (127)
const ___DBL_DIG__ = 15
const ___FLT_EVAL_METHOD__ = 2
const _SIG_ATOMIC_MAX = (2147483647)
const _INT32_MIN = (-2147483647-1)
const ___UINT16_MAX__ = 0xffff
const ___GCC_ATOMIC_LLONG_LOCK_FREE = 1
const _INT_LEAST16_MAX = (32767)

Andreas.

-- 
Andreas Schwab, SUSE Labs, schwab@suse.de
GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
"And now for something completely different."

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-29 17:05       ` Andreas Schwab
@ 2014-10-29 17:50         ` Ian Taylor
  2014-10-30  7:50           ` Dominik Vogt
  0 siblings, 1 reply; 38+ messages in thread
From: Ian Taylor @ 2014-10-29 17:50 UTC (permalink / raw)
  To: Andreas Schwab, vogt; +Cc: gcc-patches, gofrontend-dev

Thanks.  Part of the problem is that the m68k max alignment is 16
bits, but the godump test expects it to be at least 64 bits.  This is
BIGGEST_ALIGNMENT in config/m68k/m68k.h.  Another part of the problem
seems to be that structs are sometimes aligned to 16 bits although
there is no obvious reason for that.  I'm not sure where that is
coming from.

I'll let Dominik decide how he wants to handle this.  We could disable
the test on m68k or make it more accepting.  There may be problems on
other architectures as well.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-29 17:50         ` Ian Taylor
@ 2014-10-30  7:50           ` Dominik Vogt
  2014-10-30 15:05             ` Ian Taylor
  2014-10-30 21:57             ` Joseph S. Myers
  0 siblings, 2 replies; 38+ messages in thread
From: Dominik Vogt @ 2014-10-30  7:50 UTC (permalink / raw)
  To: gofrontend-dev, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1508 bytes --]

On Wed, Oct 29, 2014 at 10:16:40AM -0700, Ian Taylor wrote:
> Thanks.  Part of the problem is that the m68k max alignment is 16
> bits, but the godump test expects it to be at least 64 bits.  This is
> BIGGEST_ALIGNMENT in config/m68k/m68k.h.  Another part of the problem
> seems to be that structs are sometimes aligned to 16 bits although
> there is no obvious reason for that.  I'm not sure where that is
> coming from.

Hm, the test cases make assumptions about the Abi (structure
padding and alignment) that are true on x86, x64_64 and s390[x].
That may not be the case on other platforms and hence the tests
fail.  Another candidate for test failures is the effect of
bitfields (named or anonymous) on structure layout.

> We could disable the test on m68k or make it more accepting.

Since the point of some of the tests is to make sure that the Go
structure layout matches the C layout, making the tests accept
deviations seems to be rather pointless.  It's possible to add
target selectors to all the "scan-file" lines, but that is a lot
of work and will likely become unmaintainable very soon when more
platforms need to be added.  Personally I cannot provide fixed
tests for all the Abis either, so my suggestion is to "xfail" the
test on all targets except s390[x] and x86_64 and leave it to the
people who know the other platforms to decide whether the test
should work there or how the test could be modified to work.

See attached patch.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

[-- Attachment #2: 0001-Xfail-fdump-go-spec-tests-for-all-platforms-except-s.patch --]
[-- Type: text/x-diff, Size: 761 bytes --]

From fc92faa8532e3ea0ac3b4c8b18eb6b0a3ee862dc Mon Sep 17 00:00:00 2001
From: Dominik Vogt <vogt@linux.vnet.ibm.com>
Date: Thu, 30 Oct 2014 07:50:18 +0100
Subject: [PATCH] Xfail -fdump-go-spec tests for all platforms except s390[x]
 and x86_64.

---
 gcc/testsuite/gcc.misc-tests/godump-1.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/gcc/testsuite/gcc.misc-tests/godump-1.c b/gcc/testsuite/gcc.misc-tests/godump-1.c
index f339cc9..91b8637 100644
--- a/gcc/testsuite/gcc.misc-tests/godump-1.c
+++ b/gcc/testsuite/gcc.misc-tests/godump-1.c
@@ -2,6 +2,7 @@
 
 /* { dg-options "-c -fdump-go-spec=godump-1.out" } */
 /* { dg-do compile } */
+/* { dg-xfail-if "not supported for target" { ! "s390*-*-* x86_64-*-*" } } */
 
 #include <stdint.h>
 
-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-30  7:50           ` Dominik Vogt
@ 2014-10-30 15:05             ` Ian Taylor
  2014-10-31  9:30               ` Dominik Vogt
  2014-10-30 21:57             ` Joseph S. Myers
  1 sibling, 1 reply; 38+ messages in thread
From: Ian Taylor @ 2014-10-30 15:05 UTC (permalink / raw)
  To: vogt, gofrontend-dev, gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1934 bytes --]

On Thu, Oct 30, 2014 at 12:25 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> On Wed, Oct 29, 2014 at 10:16:40AM -0700, Ian Taylor wrote:
>> Thanks.  Part of the problem is that the m68k max alignment is 16
>> bits, but the godump test expects it to be at least 64 bits.  This is
>> BIGGEST_ALIGNMENT in config/m68k/m68k.h.  Another part of the problem
>> seems to be that structs are sometimes aligned to 16 bits although
>> there is no obvious reason for that.  I'm not sure where that is
>> coming from.
>
> Hm, the test cases make assumptions about the Abi (structure
> padding and alignment) that are true on x86, x64_64 and s390[x].
> That may not be the case on other platforms and hence the tests
> fail.  Another candidate for test failures is the effect of
> bitfields (named or anonymous) on structure layout.
>
>> We could disable the test on m68k or make it more accepting.
>
> Since the point of some of the tests is to make sure that the Go
> structure layout matches the C layout, making the tests accept
> deviations seems to be rather pointless.  It's possible to add
> target selectors to all the "scan-file" lines, but that is a lot
> of work and will likely become unmaintainable very soon when more
> platforms need to be added.  Personally I cannot provide fixed
> tests for all the Abis either, so my suggestion is to "xfail" the
> test on all targets except s390[x] and x86_64 and leave it to the
> people who know the other platforms to decide whether the test
> should work there or how the test could be modified to work.
>
> See attached patch.

I don't mind skipping the test on other platforms, but xfail is not
correct.  When an xfail test passes, we get an XPASS error from the
testsuite.  We need dg-skip-if.  I committed this patch.

Ian


2014-10-30  Dominik Vogt  <vogt@linux.vnet.ibm.com>

	* gcc.misc-tests/godump-1.c: Skip -fdump-go-spec tests for all
	platforms except s390[x] and x86_64.

[-- Attachment #2: foo.txt --]
[-- Type: text/plain, Size: 395 bytes --]

Index: gcc.misc-tests/godump-1.c
===================================================================
--- gcc.misc-tests/godump-1.c	(revision 216840)
+++ gcc.misc-tests/godump-1.c	(working copy)
@@ -2,6 +2,7 @@
 
 /* { dg-options "-c -fdump-go-spec=godump-1.out" } */
 /* { dg-do compile } */
+/* { dg-skip-if "not supported for target" { ! "s390*-*-* x86_64-*-*" } } */
 
 #include <stdint.h>
 

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-30  7:50           ` Dominik Vogt
  2014-10-30 15:05             ` Ian Taylor
@ 2014-10-30 21:57             ` Joseph S. Myers
  1 sibling, 0 replies; 38+ messages in thread
From: Joseph S. Myers @ 2014-10-30 21:57 UTC (permalink / raw)
  To: Dominik Vogt; +Cc: gofrontend-dev, gcc-patches

On Thu, 30 Oct 2014, Dominik Vogt wrote:

> platforms need to be added.  Personally I cannot provide fixed
> tests for all the Abis either, so my suggestion is to "xfail" the
> test on all targets except s390[x] and x86_64 and leave it to the

You should never do something in a test for x86_64 and not i?86, because 
they cover exactly the same set of targets (if only LP64 x86 / x86_64 is 
relevant, use { { i?86-*-* x86_64-*-* } && lp64 }).

-- 
Joseph S. Myers
joseph@codesourcery.com

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-30 15:05             ` Ian Taylor
@ 2014-10-31  9:30               ` Dominik Vogt
  2014-10-31 16:50                 ` Ian Taylor
  0 siblings, 1 reply; 38+ messages in thread
From: Dominik Vogt @ 2014-10-31  9:30 UTC (permalink / raw)
  To: gofrontend-dev, gcc-patches

On Thu, Oct 30, 2014 at 07:51:45AM -0700, Ian Taylor wrote:
> On Thu, Oct 30, 2014 at 12:25 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> > See attached patch.
> 
> I don't mind skipping the test on other platforms, but xfail is not
> correct.  When an xfail test passes, we get an XPASS error from the
> testsuite.  We need dg-skip-if.  I committed this patch.

That is exactly the reason why I chose dg-xfail-if:  To identify
the targets where the test works out of the box, because I think
there won't be many of them.

But anyway, we can leave it as it is for the moment and eventually
I'll get around cleaning that up.

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [gofrontend-dev] Re: [PATCH 7/9] Gccgo port to s390[x] -- part I
  2014-10-31  9:30               ` Dominik Vogt
@ 2014-10-31 16:50                 ` Ian Taylor
  0 siblings, 0 replies; 38+ messages in thread
From: Ian Taylor @ 2014-10-31 16:50 UTC (permalink / raw)
  To: Dominik Vogt, gofrontend-dev, gcc-patches

On Fri, Oct 31, 2014 at 2:11 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
> On Thu, Oct 30, 2014 at 07:51:45AM -0700, Ian Taylor wrote:
>> On Thu, Oct 30, 2014 at 12:25 AM, Dominik Vogt <vogt@linux.vnet.ibm.com> wrote:
>> > See attached patch.
>>
>> I don't mind skipping the test on other platforms, but xfail is not
>> correct.  When an xfail test passes, we get an XPASS error from the
>> testsuite.  We need dg-skip-if.  I committed this patch.
>
> That is exactly the reason why I chose dg-xfail-if:  To identify
> the targets where the test works out of the box, because I think
> there won't be many of them.

That would be fine if coupled with an immediate plan to test on all
systems.  What we don't want is an XPASS on some random system six
months from now that forces some poor GCC developer who knows nothing
at all about this code to figure out what is going on.


> But anyway, we can leave it as it is for the moment and eventually
> I'll get around cleaning that up.

OK.

Ian

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2014-10-31 16:42 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-09 12:44 [PATCH 0/9] Gccgo port to s390[x] -- part I Dominik Vogt
2014-09-09 12:48 ` [PATCH 1/9] " Dominik Vogt
2014-09-09 12:49 ` [PATCH 2/9] " Dominik Vogt
2014-10-09 18:56   ` [gofrontend-dev] " Ian Lance Taylor
2014-09-09 12:51 ` [PATCH 3/9] " Dominik Vogt
2014-10-03 18:28   ` [gofrontend-dev] " Ian Lance Taylor
2014-09-09 12:53 ` [PATCH 4/9] " Dominik Vogt
2014-10-04  1:19   ` [gofrontend-dev] " Ian Lance Taylor
2014-10-06  6:52     ` Dominik Vogt
2014-09-09 12:56 ` [PATCH 5/9] " Dominik Vogt
2014-10-04  1:26   ` [gofrontend-dev] " Ian Lance Taylor
2014-10-06  7:42     ` Dominik Vogt
2014-10-06 14:29       ` Ian Lance Taylor
2014-10-07 10:45         ` Dominik Vogt
2014-10-09 20:07           ` Ian Lance Taylor
2014-09-09 12:58 ` [PATCH 6/9] " Dominik Vogt
2014-10-16 22:59   ` [gofrontend-dev] " Ian Lance Taylor
2014-09-09 13:02 ` [PATCH 7/9] " Dominik Vogt
2014-10-16 23:46   ` [gofrontend-dev] " Ian Lance Taylor
2014-10-28 14:40     ` Dominik Vogt
2014-10-28 17:37       ` Ian Taylor
2014-10-29  9:05         ` Dominik Vogt
2014-10-29 16:43   ` Andreas Schwab
2014-10-29 16:43     ` [gofrontend-dev] " Ian Taylor
2014-10-29 17:05       ` Andreas Schwab
2014-10-29 17:50         ` Ian Taylor
2014-10-30  7:50           ` Dominik Vogt
2014-10-30 15:05             ` Ian Taylor
2014-10-31  9:30               ` Dominik Vogt
2014-10-31 16:50                 ` Ian Taylor
2014-10-30 21:57             ` Joseph S. Myers
2014-09-09 13:04 ` [PATCH 8/9] " Dominik Vogt
2014-10-17  0:03   ` [gofrontend-dev] " Ian Lance Taylor
2014-10-29  9:13     ` Dominik Vogt
2014-10-29 15:22       ` Ian Taylor
2014-09-09 13:06 ` [PATCH 9/9] " Dominik Vogt
2014-10-17  0:07   ` [gofrontend-dev] " Ian Lance Taylor
2014-10-17  0:45 ` [gofrontend-dev] [PATCH 0/9] " Ian Lance Taylor

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).