[57/59] ld: new CTF testsuite

Message ID 20200630233146.338613-58-nick.alcock@oracle.com
State New
Headers show
Series
  • Deduplicating CTF linker
Related show

Commit Message

H.J. Lu via Binutils June 30, 2020, 11:31 p.m.
From: Egeyar Bagcioglu <egeyar.bagcioglu@oracle.com>


Uses the new cc option to run_dump_test to compile most tests from C
code, ensuring that the types in the C code accurately describe what the
.d file is testing.

(Some tests, mostly those testing malformed CTF, run directly from .s,
or include both .s and .c.)

ld/
	* testsuite/ld-ctf/ctf.exp: New file.
	* testsuite/ld-ctf/A-2.c: New file.
	* testsuite/ld-ctf/A.c: New file.
	* testsuite/ld-ctf/B-2.c: New file.
	* testsuite/ld-ctf/B.c: New file.
	* testsuite/ld-ctf/C-2.c: New file.
	* testsuite/ld-ctf/C.c: New file.
	* testsuite/ld-ctf/array-char.c: New file.
	* testsuite/ld-ctf/array-int.c: New file.
	* testsuite/ld-ctf/array.d: New file.
	* testsuite/ld-ctf/child-float.c: New file.
	* testsuite/ld-ctf/child-int.c: New file.
	* testsuite/ld-ctf/conflicting-cycle-1.B-1.d: New file.
	* testsuite/ld-ctf/conflicting-cycle-1.B-2.d: New file.
	* testsuite/ld-ctf/conflicting-cycle-1.parent.d: New file.
	* testsuite/ld-ctf/conflicting-cycle-2.A-1.d: New file.
	* testsuite/ld-ctf/conflicting-cycle-2.A-2.d: New file.
	* testsuite/ld-ctf/conflicting-cycle-2.parent.d: New file.
	* testsuite/ld-ctf/conflicting-cycle-3.C-1.d: New file.
	* testsuite/ld-ctf/conflicting-cycle-3.C-2.d: New file.
	* testsuite/ld-ctf/conflicting-cycle-3.parent.d: New file.
	* testsuite/ld-ctf/conflicting-enums.d: New file.
	* testsuite/ld-ctf/conflicting-typedefs.d: New file.
	* testsuite/ld-ctf/cross-tu-1.c: New file.
	* testsuite/ld-ctf/cross-tu-2.c: New file.
	* testsuite/ld-ctf/cross-tu-conflicting-2.c: New file.
	* testsuite/ld-ctf/cross-tu-cyclic-1.c: New file.
	* testsuite/ld-ctf/cross-tu-cyclic-2.c: New file.
	* testsuite/ld-ctf/cross-tu-cyclic-3.c: New file.
	* testsuite/ld-ctf/cross-tu-cyclic-4.c: New file.
	* testsuite/ld-ctf/cross-tu-cyclic-conflicting.d: New file.
	* testsuite/ld-ctf/cross-tu-cyclic-nonconflicting.d: New file.
	* testsuite/ld-ctf/cross-tu-into-cycle.d: New file.
	* testsuite/ld-ctf/cross-tu-noncyclic.d: New file.
	* testsuite/ld-ctf/cycle-1.c: New file.
	* testsuite/ld-ctf/cycle-1.d: New file.
	* testsuite/ld-ctf/cycle-2.A.d: New file.
	* testsuite/ld-ctf/cycle-2.B.d: New file.
	* testsuite/ld-ctf/cycle-2.C.d: New file.
	* testsuite/ld-ctf/diag-ctf-version-0.d: New file.
	* testsuite/ld-ctf/diag-ctf-version-0.s: New file.
	* testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.d: New file.
	* testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.s: New file.
	* testsuite/ld-ctf/diag-ctf-version-f.d: New file.
	* testsuite/ld-ctf/diag-ctf-version-f.s: New file.
	* testsuite/ld-ctf/diag-cttname-invalid.d: New file.
	* testsuite/ld-ctf/diag-cttname-invalid.s: New file.
	* testsuite/ld-ctf/diag-cttname-null.d: New file.
	* testsuite/ld-ctf/diag-cttname-null.s: New file.
	* testsuite/ld-ctf/diag-cuname.d: New file.
	* testsuite/ld-ctf/diag-cuname.s: New file.
	* testsuite/ld-ctf/diag-decompression-failure.d: New file.
	* testsuite/ld-ctf/diag-decompression-failure.s: New file.
	* testsuite/ld-ctf/diag-parlabel.d: New file.
	* testsuite/ld-ctf/diag-parlabel.s: New file.
	* testsuite/ld-ctf/diag-parname.d: New file.
	* testsuite/ld-ctf/diag-parname.s: New file.
	* testsuite/ld-ctf/diag-unsupported-flag.d: New file.
	* testsuite/ld-ctf/diag-unsupported-flag.s: New file.
	* testsuite/ld-ctf/diag-wrong-magic-number-mixed.d: New file.
	* testsuite/ld-ctf/diag-wrong-magic-number.d: New file.
	* testsuite/ld-ctf/diag-wrong-magic-number.s: New file.
	* testsuite/ld-ctf/enum-2.c: New file.
	* testsuite/ld-ctf/enum.c: New file.
	* testsuite/ld-ctf/function.c: New file.
	* testsuite/ld-ctf/function.d: New file.
	* testsuite/ld-ctf/slice.c: New file.
	* testsuite/ld-ctf/slice.d: New file.
	* testsuite/ld-ctf/super-sub-cycles.c: New file.
	* testsuite/ld-ctf/super-sub-cycles.d: New file.
	* testsuite/ld-ctf/typedef-int.c: New file.
	* testsuite/ld-ctf/typedef-long.c: New file.
	* testsuite/ld-ctf/union-1.c: New file.
---
 ld/testsuite/ld-ctf/A-2.c                     |  6 ++
 ld/testsuite/ld-ctf/A.c                       |  5 ++
 ld/testsuite/ld-ctf/B-2.c                     |  5 ++
 ld/testsuite/ld-ctf/B.c                       |  4 ++
 ld/testsuite/ld-ctf/C-2.c                     |  5 ++
 ld/testsuite/ld-ctf/C.c                       |  5 ++
 ld/testsuite/ld-ctf/array-char.c              |  2 +
 ld/testsuite/ld-ctf/array-int.c               |  1 +
 ld/testsuite/ld-ctf/array.d                   | 34 ++++++++++
 ld/testsuite/ld-ctf/child-float.c             |  4 ++
 ld/testsuite/ld-ctf/child-int.c               |  4 ++
 ld/testsuite/ld-ctf/conflicting-cycle-1.B-1.d | 40 ++++++++++++
 ld/testsuite/ld-ctf/conflicting-cycle-1.B-2.d | 41 ++++++++++++
 .../ld-ctf/conflicting-cycle-1.parent.d       | 38 +++++++++++
 ld/testsuite/ld-ctf/conflicting-cycle-2.A-1.d | 40 ++++++++++++
 ld/testsuite/ld-ctf/conflicting-cycle-2.A-2.d | 41 ++++++++++++
 .../ld-ctf/conflicting-cycle-2.parent.d       | 40 ++++++++++++
 ld/testsuite/ld-ctf/conflicting-cycle-3.C-1.d | 39 +++++++++++
 ld/testsuite/ld-ctf/conflicting-cycle-3.C-2.d | 40 ++++++++++++
 .../ld-ctf/conflicting-cycle-3.parent.d       | 37 +++++++++++
 ld/testsuite/ld-ctf/conflicting-enums.d       | 35 ++++++++++
 ld/testsuite/ld-ctf/conflicting-typedefs.d    | 33 ++++++++++
 ld/testsuite/ld-ctf/cross-tu-1.c              | 12 ++++
 ld/testsuite/ld-ctf/cross-tu-2.c              |  8 +++
 ld/testsuite/ld-ctf/cross-tu-conflicting-2.c  |  8 +++
 ld/testsuite/ld-ctf/cross-tu-cyclic-1.c       | 14 ++++
 ld/testsuite/ld-ctf/cross-tu-cyclic-2.c       | 16 +++++
 ld/testsuite/ld-ctf/cross-tu-cyclic-3.c       |  3 +
 ld/testsuite/ld-ctf/cross-tu-cyclic-4.c       |  4 ++
 .../ld-ctf/cross-tu-cyclic-conflicting.d      | 57 +++++++++++++++++
 .../ld-ctf/cross-tu-cyclic-nonconflicting.d   | 50 +++++++++++++++
 ld/testsuite/ld-ctf/cross-tu-into-cycle.d     | 64 +++++++++++++++++++
 ld/testsuite/ld-ctf/cross-tu-noncyclic.d      | 46 +++++++++++++
 ld/testsuite/ld-ctf/ctf.exp                   | 26 ++++++++
 ld/testsuite/ld-ctf/cycle-1.c                 |  7 ++
 ld/testsuite/ld-ctf/cycle-1.d                 | 36 +++++++++++
 ld/testsuite/ld-ctf/cycle-2.A.d               | 40 ++++++++++++
 ld/testsuite/ld-ctf/cycle-2.B.d               | 40 ++++++++++++
 ld/testsuite/ld-ctf/cycle-2.C.d               | 40 ++++++++++++
 ld/testsuite/ld-ctf/diag-ctf-version-0.d      |  5 ++
 ld/testsuite/ld-ctf/diag-ctf-version-0.s      | 44 +++++++++++++
 .../diag-ctf-version-2-unsupported-feature.d  |  5 ++
 .../diag-ctf-version-2-unsupported-feature.s  | 44 +++++++++++++
 ld/testsuite/ld-ctf/diag-ctf-version-f.d      |  5 ++
 ld/testsuite/ld-ctf/diag-ctf-version-f.s      | 44 +++++++++++++
 ld/testsuite/ld-ctf/diag-cttname-invalid.d    |  5 ++
 ld/testsuite/ld-ctf/diag-cttname-invalid.s    | 44 +++++++++++++
 ld/testsuite/ld-ctf/diag-cttname-null.d       | 24 +++++++
 ld/testsuite/ld-ctf/diag-cttname-null.s       | 44 +++++++++++++
 ld/testsuite/ld-ctf/diag-cuname.d             | 39 +++++++++++
 ld/testsuite/ld-ctf/diag-cuname.s             | 44 +++++++++++++
 .../ld-ctf/diag-decompression-failure.d       |  5 ++
 .../ld-ctf/diag-decompression-failure.s       | 44 +++++++++++++
 ld/testsuite/ld-ctf/diag-parlabel.d           | 39 +++++++++++
 ld/testsuite/ld-ctf/diag-parlabel.s           | 44 +++++++++++++
 ld/testsuite/ld-ctf/diag-parname.d            |  5 ++
 ld/testsuite/ld-ctf/diag-parname.s            | 44 +++++++++++++
 ld/testsuite/ld-ctf/diag-unsupported-flag.d   |  5 ++
 ld/testsuite/ld-ctf/diag-unsupported-flag.s   | 44 +++++++++++++
 .../ld-ctf/diag-wrong-magic-number-mixed.d    | 39 +++++++++++
 ld/testsuite/ld-ctf/diag-wrong-magic-number.d |  5 ++
 ld/testsuite/ld-ctf/diag-wrong-magic-number.s | 44 +++++++++++++
 ld/testsuite/ld-ctf/enum-2.c                  |  3 +
 ld/testsuite/ld-ctf/enum.c                    |  3 +
 ld/testsuite/ld-ctf/function.c                |  3 +
 ld/testsuite/ld-ctf/function.d                | 23 +++++++
 ld/testsuite/ld-ctf/slice.c                   |  6 ++
 ld/testsuite/ld-ctf/slice.d                   | 30 +++++++++
 ld/testsuite/ld-ctf/super-sub-cycles.c        | 10 +++
 ld/testsuite/ld-ctf/super-sub-cycles.d        | 34 ++++++++++
 ld/testsuite/ld-ctf/typedef-int.c             |  3 +
 ld/testsuite/ld-ctf/typedef-long.c            |  3 +
 ld/testsuite/ld-ctf/union-1.c                 |  4 ++
 73 files changed, 1757 insertions(+)
 create mode 100644 ld/testsuite/ld-ctf/A-2.c
 create mode 100644 ld/testsuite/ld-ctf/A.c
 create mode 100644 ld/testsuite/ld-ctf/B-2.c
 create mode 100644 ld/testsuite/ld-ctf/B.c
 create mode 100644 ld/testsuite/ld-ctf/C-2.c
 create mode 100644 ld/testsuite/ld-ctf/C.c
 create mode 100644 ld/testsuite/ld-ctf/array-char.c
 create mode 100644 ld/testsuite/ld-ctf/array-int.c
 create mode 100644 ld/testsuite/ld-ctf/array.d
 create mode 100644 ld/testsuite/ld-ctf/child-float.c
 create mode 100644 ld/testsuite/ld-ctf/child-int.c
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-1.B-1.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-1.B-2.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-1.parent.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-2.A-1.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-2.A-2.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-2.parent.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-3.C-1.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-3.C-2.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-cycle-3.parent.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-enums.d
 create mode 100644 ld/testsuite/ld-ctf/conflicting-typedefs.d
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-1.c
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-2.c
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-conflicting-2.c
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-cyclic-1.c
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-cyclic-2.c
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-cyclic-3.c
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-cyclic-4.c
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-cyclic-conflicting.d
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-cyclic-nonconflicting.d
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-into-cycle.d
 create mode 100644 ld/testsuite/ld-ctf/cross-tu-noncyclic.d
 create mode 100644 ld/testsuite/ld-ctf/ctf.exp
 create mode 100644 ld/testsuite/ld-ctf/cycle-1.c
 create mode 100644 ld/testsuite/ld-ctf/cycle-1.d
 create mode 100644 ld/testsuite/ld-ctf/cycle-2.A.d
 create mode 100644 ld/testsuite/ld-ctf/cycle-2.B.d
 create mode 100644 ld/testsuite/ld-ctf/cycle-2.C.d
 create mode 100644 ld/testsuite/ld-ctf/diag-ctf-version-0.d
 create mode 100644 ld/testsuite/ld-ctf/diag-ctf-version-0.s
 create mode 100644 ld/testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.d
 create mode 100644 ld/testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.s
 create mode 100644 ld/testsuite/ld-ctf/diag-ctf-version-f.d
 create mode 100644 ld/testsuite/ld-ctf/diag-ctf-version-f.s
 create mode 100644 ld/testsuite/ld-ctf/diag-cttname-invalid.d
 create mode 100644 ld/testsuite/ld-ctf/diag-cttname-invalid.s
 create mode 100644 ld/testsuite/ld-ctf/diag-cttname-null.d
 create mode 100644 ld/testsuite/ld-ctf/diag-cttname-null.s
 create mode 100644 ld/testsuite/ld-ctf/diag-cuname.d
 create mode 100644 ld/testsuite/ld-ctf/diag-cuname.s
 create mode 100644 ld/testsuite/ld-ctf/diag-decompression-failure.d
 create mode 100644 ld/testsuite/ld-ctf/diag-decompression-failure.s
 create mode 100644 ld/testsuite/ld-ctf/diag-parlabel.d
 create mode 100644 ld/testsuite/ld-ctf/diag-parlabel.s
 create mode 100644 ld/testsuite/ld-ctf/diag-parname.d
 create mode 100644 ld/testsuite/ld-ctf/diag-parname.s
 create mode 100644 ld/testsuite/ld-ctf/diag-unsupported-flag.d
 create mode 100644 ld/testsuite/ld-ctf/diag-unsupported-flag.s
 create mode 100644 ld/testsuite/ld-ctf/diag-wrong-magic-number-mixed.d
 create mode 100644 ld/testsuite/ld-ctf/diag-wrong-magic-number.d
 create mode 100644 ld/testsuite/ld-ctf/diag-wrong-magic-number.s
 create mode 100644 ld/testsuite/ld-ctf/enum-2.c
 create mode 100644 ld/testsuite/ld-ctf/enum.c
 create mode 100644 ld/testsuite/ld-ctf/function.c
 create mode 100644 ld/testsuite/ld-ctf/function.d
 create mode 100644 ld/testsuite/ld-ctf/slice.c
 create mode 100644 ld/testsuite/ld-ctf/slice.d
 create mode 100644 ld/testsuite/ld-ctf/super-sub-cycles.c
 create mode 100644 ld/testsuite/ld-ctf/super-sub-cycles.d
 create mode 100644 ld/testsuite/ld-ctf/typedef-int.c
 create mode 100644 ld/testsuite/ld-ctf/typedef-long.c
 create mode 100644 ld/testsuite/ld-ctf/union-1.c

-- 
2.27.0.247.g3dff7de930

Patch

diff --git a/ld/testsuite/ld-ctf/A-2.c b/ld/testsuite/ld-ctf/A-2.c
new file mode 100644
index 00000000000..1484983fe8a
--- /dev/null
+++ b/ld/testsuite/ld-ctf/A-2.c
@@ -0,0 +1,6 @@ 
+struct A {
+  struct B *b;
+  int wombat;
+};
+
+static struct A a __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/A.c b/ld/testsuite/ld-ctf/A.c
new file mode 100644
index 00000000000..f99691a5d3a
--- /dev/null
+++ b/ld/testsuite/ld-ctf/A.c
@@ -0,0 +1,5 @@ 
+struct A {
+  struct B *b;
+};
+
+static struct A a __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/B-2.c b/ld/testsuite/ld-ctf/B-2.c
new file mode 100644
index 00000000000..be01fec1a29
--- /dev/null
+++ b/ld/testsuite/ld-ctf/B-2.c
@@ -0,0 +1,5 @@ 
+struct B {
+  struct C *c;
+  int wombat;
+};
+static struct B b __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/B.c b/ld/testsuite/ld-ctf/B.c
new file mode 100644
index 00000000000..8a7f4c2d3c2
--- /dev/null
+++ b/ld/testsuite/ld-ctf/B.c
@@ -0,0 +1,4 @@ 
+struct B {
+  struct C *c;
+};
+static struct B b __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/C-2.c b/ld/testsuite/ld-ctf/C-2.c
new file mode 100644
index 00000000000..12363b59609
--- /dev/null
+++ b/ld/testsuite/ld-ctf/C-2.c
@@ -0,0 +1,5 @@ 
+struct C {
+  struct A *a;
+  int wombat;
+};
+static struct C c __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/C.c b/ld/testsuite/ld-ctf/C.c
new file mode 100644
index 00000000000..02635e3804c
--- /dev/null
+++ b/ld/testsuite/ld-ctf/C.c
@@ -0,0 +1,5 @@ 
+struct C {
+  struct A *a;
+};
+static struct C c __attribute__((used));
+
diff --git a/ld/testsuite/ld-ctf/array-char.c b/ld/testsuite/ld-ctf/array-char.c
new file mode 100644
index 00000000000..0d1c71e02c7
--- /dev/null
+++ b/ld/testsuite/ld-ctf/array-char.c
@@ -0,0 +1,2 @@ 
+char * digits_names[10] = {"zero", "one", "two", "three", "four",
+			   "five", "six", "seven", "eight", "nine"};
diff --git a/ld/testsuite/ld-ctf/array-int.c b/ld/testsuite/ld-ctf/array-int.c
new file mode 100644
index 00000000000..ec6bed2e038
--- /dev/null
+++ b/ld/testsuite/ld-ctf/array-int.c
@@ -0,0 +1 @@ 
+int digits[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, };
diff --git a/ld/testsuite/ld-ctf/array.d b/ld/testsuite/ld-ctf/array.d
new file mode 100644
index 00000000000..f45d68cfda7
--- /dev/null
+++ b/ld/testsuite/ld-ctf/array.d
@@ -0,0 +1,34 @@ 
+#as:
+#source: array-char.c
+#source: array-int.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Arrays
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0xf \(0x10 bytes\)
+    Type section:	0x10 -- 0x6b \(0x5c bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    digits.*\[10] .*
+    digits.*\[10] .*
+
+  Types:
+#...
+     [0-9a-f]*: .*\[10\] .*
+#...
+     [0-9a-f]*: .*\[10\] .*
+#...
diff --git a/ld/testsuite/ld-ctf/child-float.c b/ld/testsuite/ld-ctf/child-float.c
new file mode 100644
index 00000000000..7366dc4c9db
--- /dev/null
+++ b/ld/testsuite/ld-ctf/child-float.c
@@ -0,0 +1,4 @@ 
+struct child_float {
+  float d;
+};
+static struct child_float *a_child_float __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/child-int.c b/ld/testsuite/ld-ctf/child-int.c
new file mode 100644
index 00000000000..3454ce9159c
--- /dev/null
+++ b/ld/testsuite/ld-ctf/child-int.c
@@ -0,0 +1,4 @@ 
+struct child_int {
+  int i;
+};
+static struct child_int *a_child_int __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-1.B-1.d b/ld/testsuite/ld-ctf/conflicting-cycle-1.B-1.d
new file mode 100644
index 00000000000..146986bc3d2
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-1.B-1.d
@@ -0,0 +1,40 @@ 
+#as:
+#source: cycle-1.c
+#source: A.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Conflicting cycle 1.B-1
+
+.*: +file format .*
+
+#...
+CTF archive member: .*/B.c:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Parent name: .ctf
+    Compilation unit name: .*/B.c
+    Variable section:	0x0 -- 0x7 \(0x8 bytes\)
+    Type section:	0x8 -- 0x1f \(0x18 bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    b ->  80000001: struct B \(size 0x[0-9]*\)
+
+  Types:
+     8[0-9a-f]*: struct B .*
+        \[0x0\] \(ID 0x8[0-9a-f]*\) \(kind 6\) struct B \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct C \* c \(.*
+
+  Strings:
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-1.B-2.d b/ld/testsuite/ld-ctf/conflicting-cycle-1.B-2.d
new file mode 100644
index 00000000000..48c11a79635
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-1.B-2.d
@@ -0,0 +1,41 @@ 
+#as:
+#source: cycle-1.c
+#source: A.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Conflicting cycle 1.B-2
+
+.*: +file format .*
+
+#...
+CTF archive member: .*/B-2.c:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Parent name: .ctf
+    Compilation unit name: .*/B-2.c
+    Variable section:	0x0 -- 0x7 \(0x8 bytes\)
+    Type section:	0x8 -- 0x2b \(0x24 bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    b ->  80000001: struct B \(.*
+
+  Types:
+     8[0-9a-f]*: struct B \(.*
+        \[0x0\] \(ID 0x8[0-9a-f]*\) \(kind 6\) struct B \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct C \* c \(.*
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 1\) int wombat:32 \(aligned at 0x[0-9a-f]*, format 0x1, offset:bits 0x0:0x[0-9a-f]*\)
+
+  Strings:
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-1.parent.d b/ld/testsuite/ld-ctf/conflicting-cycle-1.parent.d
new file mode 100644
index 00000000000..7e0c824da5c
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-1.parent.d
@@ -0,0 +1,38 @@ 
+#as:
+#source: cycle-1.c
+#source: A.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Conflicting cycle 1.parent
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0x17 \(0x18 bytes\)
+    Type section:	0x18 -- 0xc3 \(0xac bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+#...
+  Function objects:
+
+  Variables:
+#...
+  Types:
+#...
+     [0-9a-f]*: struct B \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 9\) struct B \(.*
+#...
+CTF archive member: .*:
+#...
+CTF archive member: .*:
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-2.A-1.d b/ld/testsuite/ld-ctf/conflicting-cycle-2.A-1.d
new file mode 100644
index 00000000000..8929a1f2516
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-2.A-1.d
@@ -0,0 +1,40 @@ 
+#as:
+#source: cycle-1.c
+#source: A.c
+#source: A-2.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#source: C-2.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Conflicting cycle 2.A-1
+
+.*: +file format .*
+
+#...
+CTF archive member: .*/A.c:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Parent name: .*
+    Compilation unit name: .*/A.c
+#...
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    a ->  80000001: struct A \(size 0x[0-9a-f]*\)
+
+  Types:
+     8[0-9a-f]*: struct A \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x8[0-9a-f]*\) \(kind 6\) struct A \(aligned at 0x[0-9a-f]*\)
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(aligned at 0x[0-9a-f]*\)
+
+  Strings:
+    0: 
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-2.A-2.d b/ld/testsuite/ld-ctf/conflicting-cycle-2.A-2.d
new file mode 100644
index 00000000000..f65382c7f8e
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-2.A-2.d
@@ -0,0 +1,41 @@ 
+#as:
+#source: cycle-1.c
+#source: A.c
+#source: A-2.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#source: C-2.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Conflicting cycle 2.A-2
+
+.*: +file format .*
+
+#...
+CTF archive member: .*/A-2.c:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Parent name: .*
+    Compilation unit name: .*/A-2.c
+#...
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    a ->  80000001: struct A \(size 0x[0-9a-f]*\)
+
+  Types:
+     8[0-9a-f]*: struct A \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x8[0-9a-f]*\) \(kind 6\) struct A \(aligned at 0x[0-9a-f]*\)
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(aligned at 0x[0-9a-f]*\)
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 1\) int wombat:32 \(aligned at 0x[0-9a-f]*, format 0x1, offset:bits 0x0:0x[0-9a-f]*\)
+
+  Strings:
+    0: 
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-2.parent.d b/ld/testsuite/ld-ctf/conflicting-cycle-2.parent.d
new file mode 100644
index 00000000000..8fd84886fd3
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-2.parent.d
@@ -0,0 +1,40 @@ 
+#as:
+#source: cycle-1.c
+#source: A.c
+#source: A-2.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#source: C-2.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Conflicting cycle 2.parent
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0x7 \(0x8 bytes\)
+    Type section:	0x8 -- 0x9b \(0x94 bytes\)
+    String section:	0x9c -- 0xac \(0x11 bytes\)
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    cycle_1 ->  [0-9a-f]*: struct cycle_1 \* \(size 0x[0-9a-f]*\) -> [0-9a-f]*: struct cycle_1 \(size 0x[0-9a-f]*\)
+
+  Types:
+#...
+     [0-9a-f]*: struct cycle_1 \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct cycle_1 \(aligned at 0x[0-9a-f]*\)
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* a \(aligned at 0x[0-9a-f]*\)
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(aligned at 0x[0-9a-f]*\)
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct cycle_1 \* next \(aligned at 0x[0-9a-f]*\)
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-3.C-1.d b/ld/testsuite/ld-ctf/conflicting-cycle-3.C-1.d
new file mode 100644
index 00000000000..fc426de4dcb
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-3.C-1.d
@@ -0,0 +1,39 @@ 
+#as:
+#source: A.c
+#source: A-2.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#source: C-2.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Conflicting cycle 3.C-1
+
+.*: +file format .*
+
+#...
+CTF archive member: .*/C.c:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Parent name: .*
+    Compilation unit name: .*/C.c
+#...
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    c ->  80000001: struct C \(size 0x[0-9a-f]*\)
+
+  Types:
+     8[0-9a-f]*: struct C \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x8[0-9a-f]*\) \(kind 6\) struct C \(aligned at 0x[0-9a-f]*\)
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* a \(aligned at 0x[0-9a-f]*\)
+
+  Strings:
+    0: 
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-3.C-2.d b/ld/testsuite/ld-ctf/conflicting-cycle-3.C-2.d
new file mode 100644
index 00000000000..d5e59e30c4c
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-3.C-2.d
@@ -0,0 +1,40 @@ 
+#as:
+#source: A.c
+#source: A-2.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#source: C-2.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Conflicting cycle 3.C-2
+
+.*: +file format .*
+
+#...
+CTF archive member: .*/C-2.c:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Parent name: .*
+    Compilation unit name: .*/C-2.c
+#...
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    c ->  80000001: struct C \(size 0x[0-9a-f]*\)
+
+  Types:
+     8[0-9a-f]*: struct C \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x8[0-9a-f]*\) \(kind 6\) struct C \(aligned at 0x[0-9a-f]*\)
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* a \(aligned at 0x[0-9a-f]*\)
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 1\) int wombat:[0-9]* \(aligned at 0x[0-9a-f]*, format 0x1, offset:bits 0x0:0x[0-9a-f]*\)
+
+  Strings:
+    0: 
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-cycle-3.parent.d b/ld/testsuite/ld-ctf/conflicting-cycle-3.parent.d
new file mode 100644
index 00000000000..1660821e078
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-cycle-3.parent.d
@@ -0,0 +1,37 @@ 
+#as:
+#source: A.c
+#source: A-2.c
+#source: B.c
+#source: B-2.c
+#source: C.c
+#source: C-2.c
+#objdump: --ctf=.ctf
+#ld: -shared
+#name: Conflicting cycle 3
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Type section:	0x0 -- 0x57 \(0x58 bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+
+  Types:
+#...
+     [0-9a-f]*: int \[0x0:0x[0-9a-f]*\] \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) int:[0-9]* \(aligned at 0x[0-9a-f]*, format 0x1, offset:bits 0x0:0x[0-9a-f]*\)
+#...
+  Strings:
+    0: 
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-enums.d b/ld/testsuite/ld-ctf/conflicting-enums.d
new file mode 100644
index 00000000000..8b16b4cb9e1
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-enums.d
@@ -0,0 +1,35 @@ 
+#as:
+#source: enum.c
+#source: enum-2.c
+#objdump: --ctf=.ctf
+#ld: -shared
+#name: Conflicting Enums
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+#...
+  Types:
+
+  Strings:
+#...
+CTF archive member: .*enum.*\.c:
+#...
+  Types:
+     8[0-9a-f]*: enum day_of_the_week \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x8[0-9a-f]*\) \(kind 8\) enum day_of_the_week \(aligned at 0x[0-9a-f]*\)
+
+  Strings:
+#...
+CTF archive member: .*enum.*\.c:
+#...
+  Types:
+     8[0-9a-f]*: enum day_of_the_week \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x8[0-9a-f]*\) \(kind 8\) enum day_of_the_week \(aligned at 0x[0-9a-f]*\)
+
+  Strings:
+#...
diff --git a/ld/testsuite/ld-ctf/conflicting-typedefs.d b/ld/testsuite/ld-ctf/conflicting-typedefs.d
new file mode 100644
index 00000000000..09d6c3cf54e
--- /dev/null
+++ b/ld/testsuite/ld-ctf/conflicting-typedefs.d
@@ -0,0 +1,33 @@ 
+#as:
+#source: typedef-int.c
+#source: typedef-long.c
+#objdump: --ctf=.ctf
+#ld: -shared
+#name: Conflicting Typedefs
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+#...
+  Types:
+     1: .*int .*
+        .*
+     [0-9]:.*int .*
+        .*
+     [0-9]: word .*
+        \[0x0\] \(ID 0x[0-9]\) \(kind 10\) word \(aligned at 0x[48]\)
+
+  Strings:
+#...
+CTF archive member: .*typedef.*\.c:
+#...
+  Types:
+     80000001: word .*
+        \[0x0\] \(ID 0x80000001\) \(kind 10\) word \(aligned at 0x[48]\)
+
+  Strings:
+#...
diff --git a/ld/testsuite/ld-ctf/cross-tu-1.c b/ld/testsuite/ld-ctf/cross-tu-1.c
new file mode 100644
index 00000000000..907d071d64e
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-1.c
@@ -0,0 +1,12 @@ 
+struct B
+{
+  int foo;
+};
+
+struct A
+{
+  long a;
+  struct B *foo;
+};
+
+static struct A *foo __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/cross-tu-2.c b/ld/testsuite/ld-ctf/cross-tu-2.c
new file mode 100644
index 00000000000..033d96d3352
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-2.c
@@ -0,0 +1,8 @@ 
+struct B;
+struct A
+{
+  long a;
+  struct B *foo;
+};
+
+static struct A *foo __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/cross-tu-conflicting-2.c b/ld/testsuite/ld-ctf/cross-tu-conflicting-2.c
new file mode 100644
index 00000000000..cfe65a5682a
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-conflicting-2.c
@@ -0,0 +1,8 @@ 
+struct B;
+struct A
+{
+  int a;
+  struct B *foo;
+};
+
+static struct A *foo __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/cross-tu-cyclic-1.c b/ld/testsuite/ld-ctf/cross-tu-cyclic-1.c
new file mode 100644
index 00000000000..658e2c6f58d
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-cyclic-1.c
@@ -0,0 +1,14 @@ 
+struct A;
+struct B
+{
+  int foo;
+  struct A *bar;
+};
+
+struct A
+{
+  long a;
+  struct B *foo;
+};
+
+static struct A *foo __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/cross-tu-cyclic-2.c b/ld/testsuite/ld-ctf/cross-tu-cyclic-2.c
new file mode 100644
index 00000000000..aa2d177cf9c
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-cyclic-2.c
@@ -0,0 +1,16 @@ 
+struct B;
+struct A
+{
+  long a;
+  struct B *foo;
+  struct C *bar;
+};
+
+struct C
+{
+  struct B *foo;
+  int b;
+};
+
+static struct C *foo __attribute__((used));
+static struct A *bar __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/cross-tu-cyclic-3.c b/ld/testsuite/ld-ctf/cross-tu-cyclic-3.c
new file mode 100644
index 00000000000..19947e85104
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-cyclic-3.c
@@ -0,0 +1,3 @@ 
+struct A { struct B *foo; };
+static struct A *a __attribute__((__used__));
+static struct A *conflicty __attribute__((__used__));
diff --git a/ld/testsuite/ld-ctf/cross-tu-cyclic-4.c b/ld/testsuite/ld-ctf/cross-tu-cyclic-4.c
new file mode 100644
index 00000000000..6e0c957e8fe
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-cyclic-4.c
@@ -0,0 +1,4 @@ 
+struct A { struct B *foo; };
+struct B { struct B *next; };
+static struct A *a __attribute__((__used__));
+static struct B *conflicty __attribute__((__used__));
diff --git a/ld/testsuite/ld-ctf/cross-tu-cyclic-conflicting.d b/ld/testsuite/ld-ctf/cross-tu-cyclic-conflicting.d
new file mode 100644
index 00000000000..aa36533ea37
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-cyclic-conflicting.d
@@ -0,0 +1,57 @@ 
+# Check that types with the same names in distinct TUs show up as
+# conflicting.
+#as:
+#source: cross-tu-cyclic-1.c
+#source: cross-tu-cyclic-2.c
+#objdump: --ctf=.ctf
+#ld: -shared
+#name: cross-TU-cyclic-conflicting
+
+.*:     file format .*
+
+Contents of CTF section \.ctf:
+
+#...
+  Types:
+#...
+     [0-9a-f]*: long int \[0x0:0x[0-9a-f]*\] \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) long int:[0-9]* \(aligned at 0x[0-9a-f]*, format 0x1, offset:bits 0x0:0x[0-9a-f]*\)
+#...
+     [0-9a-f]*: struct B .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct B .*
+#...
+     [0-9a-f]*: int \[0x0:0x[0-9a-f]*\] \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) int:[0-9]* \(aligned at 0x[0-9a-f]*, format 0x1, offset:bits 0x0:0x[0-9a-f]*\)
+#...
+     [0-9a-f]*: struct A .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 9\) struct A .*
+#...
+     [0-9a-f]*: struct C .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct C .*
+#...
+
+  Strings:
+#...
+
+CTF archive member: .*/ld/testsuite/ld-ctf/cross-tu-cyclic-1\.c:
+#...
+  Types:
+     80.*[0-9a-f]*: struct A .*
+        \[0x0\] \(ID 0x80.*\) \(kind 6\) struct A .*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) long int a:.*
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* foo .*
+
+  Strings:
+#...
+
+CTF archive member: .*/ld/testsuite/ld-ctf/cross-tu-cyclic-2\.c:
+#...
+  Types:
+     80.*[0-9a-f]*: struct A .*
+        \[0x0\] \(ID 0x80.*\) \(kind 6\) struct A .*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) long int a:.*
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* foo .*
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct C \* bar .*
+
+  Strings:
+#...
diff --git a/ld/testsuite/ld-ctf/cross-tu-cyclic-nonconflicting.d b/ld/testsuite/ld-ctf/cross-tu-cyclic-nonconflicting.d
new file mode 100644
index 00000000000..39f5c187e54
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-cyclic-nonconflicting.d
@@ -0,0 +1,50 @@ 
+# Check that cross-TU chasing to a type in a cycle works.
+# In particular, there should be only one copy of 'struct A *'.
+# (Not entirely reliable: only fails if the two are emitted adjacently.
+# Needs a proper objdump-CTF parser.)
+#as:
+#source: cross-tu-2.c
+#source: cross-tu-cyclic-1.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: cross-TU-cyclic-nonconflicting
+
+.*:     file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+#...
+
+  Labels:
+
+  Data objects:
+#...
+  Function objects:
+
+  Variables:
+#...
+
+  Types:
+#...
+     [0-9a-f]*: struct A \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]\) \(kind 6\) struct A \(aligned at 0x[0-9a-f]*\)
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) long int a:[0-9]* \(aligned at 0x[0-9a-f]*, format 0x1, offset:bits 0x0:0x[0-9a-f]*\)
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* foo \(aligned at 0x[0-9a-f]*\)
+     [0-9a-f]*: long int .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) long int:[0-9].*
+     [0-9a-f]*: struct B \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct B \(aligned at 0x[0-9a-f]*\)
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) int foo:[0-9]* \(aligned at 0x[0-9a-f]*, format 0x1, offset:bits 0x0:0x[0-9a-f]*\)
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* bar \(aligned at 0x[0-9a-f]*\)
+     [0-9a-f]*: struct B \* \(size 0x[0-9a-f]*\) -> [0-9a-f]*: struct B \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* \(aligned at 0x[0-9a-f]*\)
+     [0-9a-f]*: struct A \* \(size 0x[0-9a-f]*\) -> [0-9a-f]*: struct A \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* \(aligned at 0x[0-9a-f]*\)
+     [0-9a-f]*: int .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) int:.*
+
+  Strings:
+#...
diff --git a/ld/testsuite/ld-ctf/cross-tu-into-cycle.d b/ld/testsuite/ld-ctf/cross-tu-into-cycle.d
new file mode 100644
index 00000000000..6bfdc40a800
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-into-cycle.d
@@ -0,0 +1,64 @@ 
+# Check that a type outside a cycle pointing into a cycle
+# in another TU does not cause the whole cycle to show up
+# as conflicted.  (Here, we do that by forcing conflicts
+# in the variable section alone, so that we can assert that
+# the type section of any conflicted dicts is empty.)
+# Minimized from libbfd itself.
+#as:
+#source: cross-tu-cyclic-3.c
+#source: cross-tu-cyclic-4.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: cross-TU-into-cycle
+
+.*:     file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+#...
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    a ->  .*
+    conflicty ->  .*
+
+  Types:
+     [0-9a-f]*: struct A .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct A .*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* foo .*
+     [0-9a-f]*: struct B .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct B .*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* next .*
+     [0-9a-f]*: struct B \* .*
+        \[0x0\] .*
+     [0-9a-f]*: struct A \* .*
+        \[0x0\] .*
+
+  Strings:
+#...
+
+CTF archive member: .*/ld/testsuite/ld-ctf/cross-tu-cyclic-[34].c:
+
+  Header:
+#...
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+    conflicty ->  .*
+
+  Types:
+
+  Strings:
+#...
diff --git a/ld/testsuite/ld-ctf/cross-tu-noncyclic.d b/ld/testsuite/ld-ctf/cross-tu-noncyclic.d
new file mode 100644
index 00000000000..b90504abb59
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cross-tu-noncyclic.d
@@ -0,0 +1,46 @@ 
+# Check that noncyclic cross-TU matching-up works.
+# We can guarantee the order of emitted structures, too.
+#as:
+#source: cross-tu-1.c
+#source: cross-tu-2.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: cross-TU-noncyclic
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0x7 \(0x8 bytes\)
+    Type section:	0x8 -- 0x7b \(0x74 bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+#...
+  Function objects:
+
+  Variables:
+#...
+
+  Types:
+#...
+     [0-9a-f]*: struct A .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct A .*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) long int a:[0-9]* .*
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* foo .*
+#...
+     [0-9a-f]*: struct B .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct B .*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) int foo:[0-9]* .*
+#...
+     [0-9a-f]*: struct B \* \(size 0x[0-9a-f]*\) -\> [0-9a-f]*: struct B .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* .*
+#...
+     [0-9a-f]*: struct A \* \(size 0x[0-9a-f]*\) -> [0-9a-f]*: struct A .*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* .*
+#...
diff --git a/ld/testsuite/ld-ctf/ctf.exp b/ld/testsuite/ld-ctf/ctf.exp
new file mode 100644
index 00000000000..9a248f90ec4
--- /dev/null
+++ b/ld/testsuite/ld-ctf/ctf.exp
@@ -0,0 +1,26 @@ 
+# Copyright (C) 2020 Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+set ctf_test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
+
+foreach ctf_test $ctf_test_list {
+    verbose [file rootname $ctf_test]
+    run_dump_test [file rootname $ctf_test] { { cc "-gt -fPIC" } }
+}
diff --git a/ld/testsuite/ld-ctf/cycle-1.c b/ld/testsuite/ld-ctf/cycle-1.c
new file mode 100644
index 00000000000..371d411a0d7
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cycle-1.c
@@ -0,0 +1,7 @@ 
+struct cycle_1 {
+  struct A *a;
+  struct B *b;
+  struct cycle_1 *next;
+};
+
+static struct cycle_1 *cycle_1 __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/cycle-1.d b/ld/testsuite/ld-ctf/cycle-1.d
new file mode 100644
index 00000000000..145221fa99e
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cycle-1.d
@@ -0,0 +1,36 @@ 
+#as:
+#source: cycle-1.c
+#source: A.c
+#source: B.c
+#source: C.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Cycle 1
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0x1f \(0x20 bytes\)
+    Type section:	0x20 -- 0xc7 \(0xa8 bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+#...
+  Types:
+#...
+     [0-9a-f]*: struct cycle_1 \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct cycle_1 \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* a \(.*
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(.*
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct cycle_1 \* next \(.*
+#...
diff --git a/ld/testsuite/ld-ctf/cycle-2.A.d b/ld/testsuite/ld-ctf/cycle-2.A.d
new file mode 100644
index 00000000000..d224f41683d
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cycle-2.A.d
@@ -0,0 +1,40 @@ 
+#as:
+#source: A.c
+#source: B.c
+#source: C.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Cycle 2.A
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0x17 \(0x18 bytes\)
+    Type section:	0x18 -- 0x83 \(0x6c bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+#...
+    a ->  [0-9a-f]*: struct A \(.*
+#...
+  Types:
+#...
+     [0-9a-f]*: struct A \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct A \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(.*
+#...
+  Strings:
+    0: 
+#...
+    [0-9a-f]*: A
+#...
diff --git a/ld/testsuite/ld-ctf/cycle-2.B.d b/ld/testsuite/ld-ctf/cycle-2.B.d
new file mode 100644
index 00000000000..598b8ca37d2
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cycle-2.B.d
@@ -0,0 +1,40 @@ 
+#as:
+#source: A.c
+#source: B.c
+#source: C.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Cycle 2.B
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0x17 \(0x18 bytes\)
+    Type section:	0x18 -- 0x83 \(0x6c bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+#...
+    b ->  [0-9a-f]*: struct B \(.*
+#...
+  Types:
+#...
+     [0-9a-f]*: struct B \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct B \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct C \* c \(.*
+#...
+  Strings:
+    0: 
+#...
+    [0-9a-f]*: B
+#...
diff --git a/ld/testsuite/ld-ctf/cycle-2.C.d b/ld/testsuite/ld-ctf/cycle-2.C.d
new file mode 100644
index 00000000000..44cdeb56b94
--- /dev/null
+++ b/ld/testsuite/ld-ctf/cycle-2.C.d
@@ -0,0 +1,40 @@ 
+#as:
+#source: A.c
+#source: B.c
+#source: C.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Cycle 2.C
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0x17 \(0x18 bytes\)
+    Type section:	0x18 -- 0x83 \(0x6c bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+#...
+    c ->  [0-9a-f]*: struct C \(.*
+#...
+  Types:
+#...
+     [0-9a-f]*: struct C \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct C \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* a \(.*
+#...
+  Strings:
+    0: 
+#...
+    [0-9a-f]*: C
+#...
diff --git a/ld/testsuite/ld-ctf/diag-ctf-version-0.d b/ld/testsuite/ld-ctf/diag-ctf-version-0.d
new file mode 100644
index 00000000000..4e7402ccd71
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-ctf-version-0.d
@@ -0,0 +1,5 @@ 
+#as:
+#source: diag-ctf-version-0.s
+#ld: -shared
+#name: Diagnostics - CTF version 0
+#warning: CTF section .* not loaded; its types will be discarded: .*
diff --git a/ld/testsuite/ld-ctf/diag-ctf-version-0.s b/ld/testsuite/ld-ctf/diag-ctf-version-0.s
new file mode 100644
index 00000000000..5b1c33de1e3
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-ctf-version-0.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x0
+	.byte	0
+	.long	0
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.d b/ld/testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.d
new file mode 100644
index 00000000000..e494810e8ca
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.d
@@ -0,0 +1,5 @@ 
+#as:
+#source: diag-ctf-version-2-unsupported-feature.s
+#ld: -shared
+#name: Diagnostics - CTF version 2 with unsupported feature
+#warning: CTF section .* not loaded; its types will be discarded: .*
diff --git a/ld/testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.s b/ld/testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.s
new file mode 100644
index 00000000000..95e8d5187c1
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-ctf-version-2-unsupported-feature.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x2
+	.byte	0
+	.long	0
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-ctf-version-f.d b/ld/testsuite/ld-ctf/diag-ctf-version-f.d
new file mode 100644
index 00000000000..860aae92a32
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-ctf-version-f.d
@@ -0,0 +1,5 @@ 
+#as:
+#source: diag-ctf-version-f.s
+#ld: -shared
+#name: Diagnostics - Unsupported CTF version
+#warning: CTF section .* not loaded; its types will be discarded: .CTF dict version is too new for libctf.
diff --git a/ld/testsuite/ld-ctf/diag-ctf-version-f.s b/ld/testsuite/ld-ctf/diag-ctf-version-f.s
new file mode 100644
index 00000000000..63b94ca9f6a
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-ctf-version-f.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0xf
+	.byte	0
+	.long	0
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-cttname-invalid.d b/ld/testsuite/ld-ctf/diag-cttname-invalid.d
new file mode 100644
index 00000000000..de4aedc8842
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-cttname-invalid.d
@@ -0,0 +1,5 @@ 
+#as:
+#source: diag-cttname-invalid.s
+#ld: -shared
+#name: Diagnostics - Invalid type name.
+#warning: CTF section in .*not loaded; its types will be discarded: .String name offset is corrupt.
diff --git a/ld/testsuite/ld-ctf/diag-cttname-invalid.s b/ld/testsuite/ld-ctf/diag-cttname-invalid.s
new file mode 100644
index 00000000000..dbfdd21fe27
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-cttname-invalid.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x4
+	.byte	0
+	.long	0
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0xff00
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-cttname-null.d b/ld/testsuite/ld-ctf/diag-cttname-null.d
new file mode 100644
index 00000000000..17df7d6a7bf
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-cttname-null.d
@@ -0,0 +1,24 @@ 
+#as:
+#source: diag-cttname-null.s
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Diagnostics - Null type name
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+#...
+  Variables:
+#...
+    a ->  [0-9a-f]*: struct  \(.*
+#...
+  Types:
+#...
+     [0-9a-f]*: struct  \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct  \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(.*
+#...
diff --git a/ld/testsuite/ld-ctf/diag-cttname-null.s b/ld/testsuite/ld-ctf/diag-cttname-null.s
new file mode 100644
index 00000000000..ad6ce60f964
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-cttname-null.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x4
+	.byte	0
+	.long	0
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-cuname.d b/ld/testsuite/ld-ctf/diag-cuname.d
new file mode 100644
index 00000000000..e243008e0c5
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-cuname.d
@@ -0,0 +1,39 @@ 
+#as:
+#source: diag-cuname.s
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Diagnostics - Invalid CU name offset
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Compilation unit name: \(\?\)
+    Variable section:	.*
+    Type section:	.*
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+#...
+    a ->  [0-9a-f]*: struct A \(.*
+#...
+  Types:
+#...
+     [0-9a-f]*: struct A \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct A \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(.*
+#...
+  Strings:
+    0: 
+#...
+    [0-9a-f]*: \(\?\)
+#...
diff --git a/ld/testsuite/ld-ctf/diag-cuname.s b/ld/testsuite/ld-ctf/diag-cuname.s
new file mode 100644
index 00000000000..dcdbd62aa73
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-cuname.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x4
+	.byte	0
+	.long	0
+	.long	0
+	.long	0xffffffff
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-decompression-failure.d b/ld/testsuite/ld-ctf/diag-decompression-failure.d
new file mode 100644
index 00000000000..c4567e10919
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-decompression-failure.d
@@ -0,0 +1,5 @@ 
+#as:
+#source: diag-decompression-failure.s
+#ld: -shared
+#name: Diagnostics - Decompression failure
+#warning: CTF section.* not loaded; its types will be discarded: .Failed to decompress CTF data.
diff --git a/ld/testsuite/ld-ctf/diag-decompression-failure.s b/ld/testsuite/ld-ctf/diag-decompression-failure.s
new file mode 100644
index 00000000000..40a2fcf66ce
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-decompression-failure.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x4
+	.byte	0x1
+	.long	0
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-parlabel.d b/ld/testsuite/ld-ctf/diag-parlabel.d
new file mode 100644
index 00000000000..7e328176cfd
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-parlabel.d
@@ -0,0 +1,39 @@ 
+#as:
+#source: diag-parlabel.s
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Diagnostics - Non-zero parlabel in parent
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Compilation unit name: .*A.c
+    Variable section:	0x0 -- 0x7 \(0x8 bytes\)
+    Type section:	0x8 -- 0x37 \(0x30 bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+#...
+    a ->  [0-9a-f]*: struct A \(.*
+#...
+  Types:
+#...
+     [0-9a-f]*: struct A \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct A \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(.*
+#...
+  Strings:
+    0: 
+#...
+    [0-9a-f]*: A
+#...
diff --git a/ld/testsuite/ld-ctf/diag-parlabel.s b/ld/testsuite/ld-ctf/diag-parlabel.s
new file mode 100644
index 00000000000..e0ce57ca535
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-parlabel.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x4
+	.byte	0
+	.long	0x2
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-parname.d b/ld/testsuite/ld-ctf/diag-parname.d
new file mode 100644
index 00000000000..d2ce9aac81f
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-parname.d
@@ -0,0 +1,5 @@ 
+#as:
+#source: diag-parname.s
+#ld: -shared --ctf-variables
+#name: Diagnostics - No parent dictionary
+#warning: CTF linking failed; output will have no CTF section: .The parent CTF dictionary is unavailable.
diff --git a/ld/testsuite/ld-ctf/diag-parname.s b/ld/testsuite/ld-ctf/diag-parname.s
new file mode 100644
index 00000000000..da30e4a7c85
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-parname.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x4
+	.byte	0
+	.long	0
+	.long	0xffffffff
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-unsupported-flag.d b/ld/testsuite/ld-ctf/diag-unsupported-flag.d
new file mode 100644
index 00000000000..879781772aa
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-unsupported-flag.d
@@ -0,0 +1,5 @@ 
+#as:
+#source: diag-unsupported-flag.s
+#ld: -shared
+#name: Diagnostics - Unsupported flag
+#warning: CTF section.* not loaded; its types will be discarded: .CTF header contains flags unknown to libctf.
diff --git a/ld/testsuite/ld-ctf/diag-unsupported-flag.s b/ld/testsuite/ld-ctf/diag-unsupported-flag.s
new file mode 100644
index 00000000000..9e773e91df3
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-unsupported-flag.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff2
+	.byte	0x4
+	.byte	0x80
+	.long	0
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/diag-wrong-magic-number-mixed.d b/ld/testsuite/ld-ctf/diag-wrong-magic-number-mixed.d
new file mode 100644
index 00000000000..5415c131940
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-wrong-magic-number-mixed.d
@@ -0,0 +1,39 @@ 
+#as:
+#source: diag-wrong-magic-number.s
+#source: B.c
+#ld: -shared --ctf-variables
+#name: Diagnostics - Wrong magic number mixed with valid CTF sections
+#warning: CTF section in .* not loaded; its types will be discarded: .Buffer does not contain CTF data.
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Variable section:	0x0 -- 0x17 \(0x18 bytes\)
+    Type section:	0x18 -- 0x83 \(0x6c bytes\)
+    String section:	.*
+
+  Labels:
+
+  Data objects:
+
+  Function objects:
+
+  Variables:
+#...
+    b ->  [0-9a-f]*: struct B \(.*
+#...
+  Types:
+#...
+     [0-9a-f]*: struct B \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct B \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct C \* c \(.*
+#...
+  Strings:
+    0: 
+#...
+    [0-9a-f]*: B
+#...
diff --git a/ld/testsuite/ld-ctf/diag-wrong-magic-number.d b/ld/testsuite/ld-ctf/diag-wrong-magic-number.d
new file mode 100644
index 00000000000..847bbf87240
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-wrong-magic-number.d
@@ -0,0 +1,5 @@ 
+#as:
+#source: diag-wrong-magic-number.s
+#ld: -shared
+#name: Diagnostics - Wrong magic number
+#warning: CTF section in .* not loaded; its types will be discarded: .Buffer does not contain CTF data.
diff --git a/ld/testsuite/ld-ctf/diag-wrong-magic-number.s b/ld/testsuite/ld-ctf/diag-wrong-magic-number.s
new file mode 100644
index 00000000000..a80c8644b19
--- /dev/null
+++ b/ld/testsuite/ld-ctf/diag-wrong-magic-number.s
@@ -0,0 +1,44 @@ 
+	.file	"A.c"
+	.section	.ctf,"",@progbits
+.Lctf0:
+	.2byte	0xdff3
+	.byte	0x4
+	.byte	0
+	.long	0
+	.long	0
+	.long	0x9
+	.long	0
+	.long	0
+	.long	0x4
+	.long	0x4
+	.long	0x8
+	.long	0x8
+	.long	0x10
+	.long	0x40
+	.long	0x42
+	.long	0x1
+	.long	0x7
+	.long	0x7
+	.long	0x1
+	.long	0x1
+	.long	0x1a000001
+	.long	0x8
+	.long	0x5
+	.long	0
+	.long	0x3
+	.long	0x3
+	.long	0x26000000
+	.long	0x6
+	.long	0
+	.long	0xe000000
+	.long	0x2
+	.ascii "\0"
+	.ascii "A\0"
+	.ascii "B\0"
+	.ascii "b\0"
+	.ascii "a\0"
+	.ascii "/usr/src/binutils-gdb/ld/testsuite/ld-ctf/A.c\0"
+	.text
+	.comm	a,8,8
+	.ident	"GCC: (GNU) 8.3.1 20191121 (Red Hat 8.3.1-5.0.1)"
+	.section	.note.GNU-stack,"",@progbits
diff --git a/ld/testsuite/ld-ctf/enum-2.c b/ld/testsuite/ld-ctf/enum-2.c
new file mode 100644
index 00000000000..f7c095394e3
--- /dev/null
+++ b/ld/testsuite/ld-ctf/enum-2.c
@@ -0,0 +1,3 @@ 
+enum day_of_the_week {Sunday = 0, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
+
+static enum day_of_the_week day __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/enum.c b/ld/testsuite/ld-ctf/enum.c
new file mode 100644
index 00000000000..11851a1fc0f
--- /dev/null
+++ b/ld/testsuite/ld-ctf/enum.c
@@ -0,0 +1,3 @@ 
+enum day_of_the_week {Monday = 0, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday};
+
+static enum day_of_the_week day __attribute__((used));
diff --git a/ld/testsuite/ld-ctf/function.c b/ld/testsuite/ld-ctf/function.c
new file mode 100644
index 00000000000..806742fc9b5
--- /dev/null
+++ b/ld/testsuite/ld-ctf/function.c
@@ -0,0 +1,3 @@ 
+int foo (char ch, int i, float f, void * p, void (*bar_ptr)(int)) {
+  return 0;
+}
diff --git a/ld/testsuite/ld-ctf/function.d b/ld/testsuite/ld-ctf/function.d
new file mode 100644
index 00000000000..0ed8eece1bb
--- /dev/null
+++ b/ld/testsuite/ld-ctf/function.d
@@ -0,0 +1,23 @@ 
+#as:
+#source: function.c
+#objdump: --ctf=.ctf
+#ld: -shared
+#name: Function
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Compilation unit name: .*function.c
+#...
+    Type section:	0x0 -- 0x8f \(0x90 bytes\)
+    String section:	.*
+#...
+  Types:
+#...
+     [0-9a-f]*: int \(\*\) \(char, int, float, void \*, void \(\*\)\(\*\) \(int\)\) \(size 0x0\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 5\) int \(\*\) \(char, int[0-9]*, float, void \*, void \(\*\)\(\*\) \(int\)\) \(aligned at 0x[0-9a-f]*\)
+#...
diff --git a/ld/testsuite/ld-ctf/slice.c b/ld/testsuite/ld-ctf/slice.c
new file mode 100644
index 00000000000..7937bcf796e
--- /dev/null
+++ b/ld/testsuite/ld-ctf/slice.c
@@ -0,0 +1,6 @@ 
+struct slices {
+  int one : 1;
+  int two : 2;
+  int six : 6;
+  int ten :10;
+} slices; 
diff --git a/ld/testsuite/ld-ctf/slice.d b/ld/testsuite/ld-ctf/slice.d
new file mode 100644
index 00000000000..b594553568c
--- /dev/null
+++ b/ld/testsuite/ld-ctf/slice.d
@@ -0,0 +1,30 @@ 
+#as:
+#source: slice.c
+#objdump: --ctf=.ctf
+#ld: -shared --ctf-variables
+#name: Slice
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Compilation unit name: .*slice.c
+    Variable section:	0x0 -- 0x7 \(0x8 bytes\)
+    Type section:	0x8 -- 0xa3 \(0x9c bytes\)
+    String section:	.*
+#...
+  Variables:
+    slices ->  [0-9a-f]*: struct slices \(size 0x4\)
+
+  Types:
+#...
+     [0-9a-f]*: struct slices \(size 0x[0-9a-f]*\)
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct slices \(aligned at 0x1\)
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 1\) int  one:1 \(aligned at 0x1, format 0x1, offset:bits 0x0:0x1\)
+            \[0x1\] \(ID 0x[0-9a-f]*\) \(kind 1\) int  two:2 \(aligned at 0x1, format 0x1, offset:bits 0x1:0x2\)
+            \[0x3\] \(ID 0x[0-9a-f]*\) \(kind 1\) int  six:6 \(aligned at 0x1, format 0x1, offset:bits 0x3:0x6\)
+            \[0x9\] \(ID 0x[0-9a-f]*\) \(kind 1\) int  ten:10 \(aligned at 0x2, format 0x1, offset:bits 0x9:0xa\)
+#...
diff --git a/ld/testsuite/ld-ctf/super-sub-cycles.c b/ld/testsuite/ld-ctf/super-sub-cycles.c
new file mode 100644
index 00000000000..e63411b6227
--- /dev/null
+++ b/ld/testsuite/ld-ctf/super-sub-cycles.c
@@ -0,0 +1,10 @@ 
+struct A;
+struct B;
+struct D { struct B *b; };
+struct Y;
+struct Z { struct Y *y; struct D *d; };
+struct Y { struct Z z; };
+struct X { struct Y y; };
+struct C { struct A *a; struct D d; };
+struct B { struct C c; struct D d; };
+struct A { struct B b; struct X x; } a;
diff --git a/ld/testsuite/ld-ctf/super-sub-cycles.d b/ld/testsuite/ld-ctf/super-sub-cycles.d
new file mode 100644
index 00000000000..8a46f16f496
--- /dev/null
+++ b/ld/testsuite/ld-ctf/super-sub-cycles.d
@@ -0,0 +1,34 @@ 
+#as:
+#source: super-sub-cycles.c
+#objdump: --ctf=.ctf
+#ld: -shared
+#name: Super- and sub-cycles
+
+.*: +file format .*
+
+Contents of CTF section .ctf:
+
+  Header:
+    Magic number: dff2
+    Version: 4 \(CTF_VERSION_3\)
+    Compilation unit name: .*super-sub-cycles.c
+#...
+    Type section:	.*\(0x108 bytes\)
+#...
+  Types:
+#...
+     [0-9a-f]*: struct A \(.*
+        \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct A \(.*
+            \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct B b \(.*
+                \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct C c \(.*
+                    \[0x0\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct A \* a \(.*
+                    \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct D d \(.*
+                        \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(.*
+                \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct D d \(.*
+                    \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct B \* b \(.*
+            \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct X x \(.*
+                \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct Y y \(.*
+                    \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 6\) struct Z z \(.*
+                        \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct Y \* y \(.*
+                        \[0x[0-9a-f]*\] \(ID 0x[0-9a-f]*\) \(kind 3\) struct D \* d \(.*
+#...
diff --git a/ld/testsuite/ld-ctf/typedef-int.c b/ld/testsuite/ld-ctf/typedef-int.c
new file mode 100644
index 00000000000..15889108e40
--- /dev/null
+++ b/ld/testsuite/ld-ctf/typedef-int.c
@@ -0,0 +1,3 @@ 
+typedef int word;
+
+static word w;
diff --git a/ld/testsuite/ld-ctf/typedef-long.c b/ld/testsuite/ld-ctf/typedef-long.c
new file mode 100644
index 00000000000..f2e070cc5a4
--- /dev/null
+++ b/ld/testsuite/ld-ctf/typedef-long.c
@@ -0,0 +1,3 @@ 
+typedef long word;
+
+static word w;
diff --git a/ld/testsuite/ld-ctf/union-1.c b/ld/testsuite/ld-ctf/union-1.c
new file mode 100644
index 00000000000..24d2f2efbb5
--- /dev/null
+++ b/ld/testsuite/ld-ctf/union-1.c
@@ -0,0 +1,4 @@ 
+union int_or_float {
+  struct child_int * a_child_int;
+  struct child_float * a_child_float;
+} an_int_or_float;