diff mbox series

c++: EOF location [PR 96045]

Message ID 3d5880c1-7837-d8e7-6446-a4e6365ccdd0@acm.org
State New
Headers show
Series c++: EOF location [PR 96045] | expand

Commit Message

Nathan Sidwell Dec. 23, 2020, 10:25 p.m. UTC
Setting	the EOF	token location to be the start of a line just after
the ending newline is not most helpful.	 While that location is
probably the right place to report preprocessing and lexing issues,
when parsing, the location just after the last token is better.	 That
way we get to point at some actual text.  Setting the location from
the previous token has the advantage over just setting the location to
be the end of the final line, in that any ending comments do not get
considered, which I think is better.

         PR c++/96045
         gcc/cp/
         * parser.c (cp_lexer_new_main): Adjust EOF token location.
         gcc/testsuite/
         * g++.dg/diagnostic/pr96045-1.C: New.
         * g++.dg/diagnostic/pr96045-2.C: New.
         * g++.dg/diagnostic/pr96045-3.C: New.
         * c-c++-common/goacc/pr79428-1.c: Adjust EOF diagnostic location.
         * c-c++-common/gomp/pr79428-2.c: Likewise
         * c-c++-common/raw-string-6.c: Likewise
         * g++.dg/cpp0x/decltype63.C: Likewise
         * g++.dg/cpp0x/gen-attrs-64.C: Likewise
	* g++.dg/cpp0x/pr68726.C: Likewise
         * g++.dg/cpp0x/pr78341.C: Likewise
         * g++.dg/cpp1y/pr65202.C: Likewise
         * g++.dg/cpp1y/pr65340.C: Likewise
         * g++.dg/cpp1y/pr68578.C: Likewise
         * g++.dg/cpp1z/class-deduction44.C: Likewise
         * g++.dg/diagnostic/unclosed-extern-c.C: Likewise
         * g++.dg/diagnostic/unclosed-function.C: Likewise
         * g++.dg/diagnostic/unclosed-namespace.C: Likewise
         * g++.dg/diagnostic/unclosed-struct.C: Likewise
         * g++.dg/ext/pr84598.C: Likewise
         * g++.dg/other/switch4.C: Likewise
         * g++.dg/parse/attr4.C: Likewise
         * g++.dg/parse/cond4.C: Likewise
         * g++.dg/parse/crash10.C: Likewise
         * g++.dg/parse/crash18.C: Likewise
         * g++.dg/parse/crash27.C: Likewise
         * g++.dg/parse/crash34.C: Likewise
         * g++.dg/parse/crash35.C: Likewise
         * g++.dg/parse/crash52.C: Likewise
         * g++.dg/parse/crash59.C: Likewise
         * g++.dg/parse/crash61.C: Likewise
         * g++.dg/parse/crash67.C: Likewise
         * g++.dg/parse/error14.C: Likewise
         * g++.dg/parse/error56.C: Likewise
         * g++.dg/parse/invalid1.C: Likewise
         * g++.dg/parse/parameter-declaration-1.C: Likewise
         * g++.dg/parse/parser-pr28152-2.C: Likewise
         * g++.dg/parse/parser-pr28152.C: Likewise
         * g++.dg/parse/pr68722.C: Likewise
         * g++.dg/parse/pr96258.C: Likewise
         * g++.dg/pr46852.C: Likewise
         * g++.dg/pr46868.C: Likewise
         * g++.dg/template/crash115.C: Likewise
         * g++.dg/template/crash43.C: Likewise
         * g++.dg/template/crash90.C: Likewise
         * g++.dg/template/error-recovery1.C: Likewise
         * g++.dg/template/error57.C: Likewise
         * g++.old-deja/g++.other/crash31.C: Likewise
diff mbox series

Patch

diff --git c/gcc/cp/parser.c w/gcc/cp/parser.c
index 3883339aa64..dd8e8081847 100644
--- c/gcc/cp/parser.c
+++ w/gcc/cp/parser.c
@@ -666,6 +666,16 @@  cp_lexer_new_main (void)
                       + lexer->buffer->length ()
 		      - 1;
 
+  if (lexer->buffer->length () != 1)
+    {
+      /* Set the EOF token's location to be the just after the previous
+         token's range.  That way 'at-eof' diagnostics point at something
+	 meaninful.  */
+      auto range = get_range_from_loc (line_table, tok[-1].location);
+      tok[0].location
+	= linemap_position_for_loc_and_offset (line_table, range.m_finish, 1);
+    }
+
   if (filter)
     module_token_cdtor (parse_in, filter);
 
diff --git c/gcc/testsuite/c-c++-common/goacc/pr79428-1.c w/gcc/testsuite/c-c++-common/goacc/pr79428-1.c
index 68dea5b145e..a8047e98123 100644
--- c/gcc/testsuite/c-c++-common/goacc/pr79428-1.c
+++ w/gcc/testsuite/c-c++-common/goacc/pr79428-1.c
@@ -4,5 +4,5 @@  void
 foo ()
 {
 #pragma acc routine /* { dg-error ".#pragma acc routine. must be at file scope" } */
-// { dg-error "expected" "end" { target c } .-1 }
-// { dg-error "-:expected" "end" { target c++ } .+1 }
+// { dg-error "expected" "end" { target *-*-* } .-1 }
+
diff --git c/gcc/testsuite/c-c++-common/gomp/pr79428-2.c w/gcc/testsuite/c-c++-common/gomp/pr79428-2.c
index 0914963b8f9..6d162a2c13f 100644
--- c/gcc/testsuite/c-c++-common/gomp/pr79428-2.c
+++ w/gcc/testsuite/c-c++-common/gomp/pr79428-2.c
@@ -5,5 +5,4 @@  foo ()
 {
 #pragma omp sections
 #pragma omp section /* { dg-error "'#pragma omp section' may only be used in '#pragma omp sections' construct|not allowed" } */
-// { dg-error "expected" "end" { target c } .-1 }
-// { dg-error "-:expected" "end" { target c++ } .+1 }
+// { dg-error "expected" "end" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/c-c++-common/raw-string-6.c w/gcc/testsuite/c-c++-common/raw-string-6.c
index a2cb30e96c9..819dd44aff4 100644
--- c/gcc/testsuite/c-c++-common/raw-string-6.c
+++ w/gcc/testsuite/c-c++-common/raw-string-6.c
@@ -3,5 +3,4 @@ 
 // { dg-options "-std=c++0x" { target c++ } }
 
 const void *s0 = R"ouch()ouCh"; 	// { dg-error "unterminated raw string" "unterminated" }
-// { dg-error "at end of input" "end" { target c } .-1 }
-// { dg-error "-:at end of input" "end" { target c++ } .+1 }
+// { dg-error "at end of input" "end" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/cpp0x/decltype63.C w/gcc/testsuite/g++.dg/cpp0x/decltype63.C
index b588bc3e5ef..ab1a4111eee 100644
--- c/gcc/testsuite/g++.dg/cpp0x/decltype63.C
+++ w/gcc/testsuite/g++.dg/cpp0x/decltype63.C
@@ -4,5 +4,4 @@ 
 template<typename T>
 class C{
  T t;
-  decltype(t)::a:: // { dg-error "expected" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+  decltype(t)::a:: // { dg-error "expected"  }
diff --git c/gcc/testsuite/g++.dg/cpp0x/gen-attrs-64.C w/gcc/testsuite/g++.dg/cpp0x/gen-attrs-64.C
index 822b64ea460..c82beb98381 100644
--- c/gcc/testsuite/g++.dg/cpp0x/gen-attrs-64.C
+++ w/gcc/testsuite/g++.dg/cpp0x/gen-attrs-64.C
@@ -2,4 +2,3 @@ 
 // { dg-do compile { target c++11 } }
 
 namespace alignas() N  {} // { dg-error "expected"  }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/cpp0x/pr68726.C w/gcc/testsuite/g++.dg/cpp0x/pr68726.C
index 636a20c83be..8edd43996ff 100644
--- c/gcc/testsuite/g++.dg/cpp0x/pr68726.C
+++ w/gcc/testsuite/g++.dg/cpp0x/pr68726.C
@@ -5,4 +5,3 @@  template <typename> struct A {
   template <typename... _Args>
   using __has_construct typename __construct_helper<_Args...>::type;  // { dg-error "expected" }
 } struct : A<int> {   // { dg-error "expected" }
-  // { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/cpp0x/pr78341.C w/gcc/testsuite/g++.dg/cpp0x/pr78341.C
index 8573f9f0824..0a69210e5a1 100644
--- c/gcc/testsuite/g++.dg/cpp0x/pr78341.C
+++ w/gcc/testsuite/g++.dg/cpp0x/pr78341.C
@@ -2,4 +2,3 @@ 
 // { dg-do compile { target c++11 } }
 
 alignas (alignas double // { dg-error "expected" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/cpp1y/pr65202.C w/gcc/testsuite/g++.dg/cpp1y/pr65202.C
index a76f8da689c..1f7219b5b0a 100644
--- c/gcc/testsuite/g++.dg/cpp1y/pr65202.C
+++ w/gcc/testsuite/g++.dg/cpp1y/pr65202.C
@@ -24,5 +24,4 @@  int main()
 {
     foo<ns::bar> f;
     adl::swap(f, f) // { dg-error "expected ';'" }
-}
-// { dg-error "-:expected '.'" "expected end of namespace" { target *-*-* } .+1 }
+} // { dg-error "2:expected" }
diff --git c/gcc/testsuite/g++.dg/cpp1y/pr65340.C w/gcc/testsuite/g++.dg/cpp1y/pr65340.C
index d3e03f75df3..e0ce6810906 100644
--- c/gcc/testsuite/g++.dg/cpp1y/pr65340.C
+++ w/gcc/testsuite/g++.dg/cpp1y/pr65340.C
@@ -17,4 +17,4 @@  struct traverse {
 }
 auto &traverse = constant < functors :: traverse > ;
 operator()()->decltype(traverse(0, 0))// { dg-error "no match"  }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "39:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/cpp1y/pr68578.C w/gcc/testsuite/g++.dg/cpp1y/pr68578.C
index 9b3898176f1..f4be9daa8c6 100644
--- c/gcc/testsuite/g++.dg/cpp1y/pr68578.C
+++ w/gcc/testsuite/g++.dg/cpp1y/pr68578.C
@@ -1,4 +1,4 @@ 
 // { dg-do compile { target c++14 } }
 
 template <typename> struct bar foo; template <> struct foo<>:  // { dg-error "class template|redeclared" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "62:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/cpp1z/class-deduction44.C w/gcc/testsuite/g++.dg/cpp1z/class-deduction44.C
index 95caa992a21..419aaa20cbd 100644
--- c/gcc/testsuite/g++.dg/cpp1z/class-deduction44.C
+++ w/gcc/testsuite/g++.dg/cpp1z/class-deduction44.C
@@ -3,4 +3,3 @@ 
 
 template <typename> struct A;
 template <typename> struct B : A < B { , // { dg-error ""  }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/diagnostic/pr96045-1.C w/gcc/testsuite/g++.dg/diagnostic/pr96045-1.C
new file mode 100644
index 00000000000..b84a5d5c007
--- /dev/null
+++ w/gcc/testsuite/g++.dg/diagnostic/pr96045-1.C
@@ -0,0 +1,4 @@ 
+// PR 96045  EOF location
+
+template <class> class A {};
+struct A <int> // { dg-error "15:" }
diff --git c/gcc/testsuite/g++.dg/diagnostic/pr96045-2.C w/gcc/testsuite/g++.dg/diagnostic/pr96045-2.C
new file mode 100644
index 00000000000..1009ad0a4de
--- /dev/null
+++ w/gcc/testsuite/g++.dg/diagnostic/pr96045-2.C
@@ -0,0 +1,6 @@ 
+// PR 96045  EOF location
+
+template <class> class A {};
+struct A <int> // { dg-error "15:" }
+/* A comment */
+  
diff --git c/gcc/testsuite/g++.dg/diagnostic/pr96045-3.C w/gcc/testsuite/g++.dg/diagnostic/pr96045-3.C
new file mode 100644
index 00000000000..ad1f2a5f96d
--- /dev/null
+++ w/gcc/testsuite/g++.dg/diagnostic/pr96045-3.C
@@ -0,0 +1,6 @@ 
+// PR 96045  EOF location
+
+#define BORKED <int> // { dg-error "20:" }
+
+template <class> class A {};
+struct A BORKED // { dg-message "10: in expansion of" }
diff --git c/gcc/testsuite/g++.dg/diagnostic/unclosed-extern-c.C w/gcc/testsuite/g++.dg/diagnostic/unclosed-extern-c.C
index f905e4f3cc9..4dad8a21c16 100644
--- c/gcc/testsuite/g++.dg/diagnostic/unclosed-extern-c.C
+++ w/gcc/testsuite/g++.dg/diagnostic/unclosed-extern-c.C
@@ -10,4 +10,4 @@  void bar (void);
 
 void test (void);
 // { message "12: to match this '.'" "" { target *-*-* } open_extern_c }
-/* { dg-error "-:expected '.' at end of input" "" { target *-*-* } .+1 } */
+/* { dg-error "18:expected '.' at end of input" "" { target *-*-* } .-2 } */
diff --git c/gcc/testsuite/g++.dg/diagnostic/unclosed-function.C w/gcc/testsuite/g++.dg/diagnostic/unclosed-function.C
index 4d841d5c6f4..ff94bc7b262 100644
--- c/gcc/testsuite/g++.dg/diagnostic/unclosed-function.C
+++ w/gcc/testsuite/g++.dg/diagnostic/unclosed-function.C
@@ -1,4 +1,3 @@ 
 void test (void)
 { /* { dg-message "1: to match this '.'" } */
-  int filler;
-  /* { dg-error "-:expected '.' at end of input" "" { target *-*-* } .+1 } */
+  int filler; /* { dg-error "14:expected '.' at end of input"  } */
diff --git c/gcc/testsuite/g++.dg/diagnostic/unclosed-namespace.C w/gcc/testsuite/g++.dg/diagnostic/unclosed-namespace.C
index 0887bc1e813..fc3fc08595a 100644
--- c/gcc/testsuite/g++.dg/diagnostic/unclosed-namespace.C
+++ w/gcc/testsuite/g++.dg/diagnostic/unclosed-namespace.C
@@ -1,3 +1,2 @@ 
 namespace unclosed { /* { dg-message "20: to match this '.'" } */
-int filler;
-/* { dg-error "-:expected '.' at end of input" "" { target *-*-* } .+1 } */
+int filler; /* { dg-error "12:expected '.' at end of input" } */
diff --git c/gcc/testsuite/g++.dg/diagnostic/unclosed-struct.C w/gcc/testsuite/g++.dg/diagnostic/unclosed-struct.C
index e68e5996204..e3faaae715c 100644
--- c/gcc/testsuite/g++.dg/diagnostic/unclosed-struct.C
+++ w/gcc/testsuite/g++.dg/diagnostic/unclosed-struct.C
@@ -1,3 +1,2 @@ 
 struct unclosed { /* { dg-message "17: to match this '.'" } */
-  int dummy;
-  // { dg-error "-:expected" "" { target *-*-* } .+1 }
+  int dummy; // { dg-error "13:expected"  }
diff --git c/gcc/testsuite/g++.dg/ext/pr84598.C w/gcc/testsuite/g++.dg/ext/pr84598.C
index 8b78e0fddea..1dd09f9870d 100644
--- c/gcc/testsuite/g++.dg/ext/pr84598.C
+++ w/gcc/testsuite/g++.dg/ext/pr84598.C
@@ -1,4 +1,4 @@ 
 // { dg-options "-fpermissive -w" }
 
-template<int b> __attribute__ a([] { class c, __attribute__(vector_size(operator+()))) d; // { dg-error "" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+template<int b> __attribute__ a([] { class c, __attribute__(vector_size(operator+()))) d; // { dg-error "before" }
+// { dg-error "90:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/other/switch4.C w/gcc/testsuite/g++.dg/other/switch4.C
index 5d0047b89c8..070c55e4932 100644
--- c/gcc/testsuite/g++.dg/other/switch4.C
+++ w/gcc/testsuite/g++.dg/other/switch4.C
@@ -3,5 +3,4 @@ 
 class a b;  // { dg-error "aggregate" }
 void c() {
   switch ()  // { dg-error "expected" }
-  case b  // { dg-error "expected" }
-    // { dg-error "-:expected" "" { target *-*-* } .+1 }
+  case b  // { dg-error "9:expected" }
diff --git c/gcc/testsuite/g++.dg/parse/attr4.C w/gcc/testsuite/g++.dg/parse/attr4.C
index 36ebdbd0bae..f16bf4779b9 100644
--- c/gcc/testsuite/g++.dg/parse/attr4.C
+++ w/gcc/testsuite/g++.dg/parse/attr4.C
@@ -1,4 +1,3 @@ 
 // PR c++/93684 - ICE-on-invalid with broken attribute.
 
 [[a:: // { dg-error "expected" }
-  // { dg-error "-:expected" "" { target c++11 } .+1 }
diff --git c/gcc/testsuite/g++.dg/parse/cond4.C w/gcc/testsuite/g++.dg/parse/cond4.C
index 893caeaa571..6484f86072a 100644
--- c/gcc/testsuite/g++.dg/parse/cond4.C
+++ w/gcc/testsuite/g++.dg/parse/cond4.C
@@ -3,5 +3,4 @@ 
 
 void foo()                                                                                                                              
 {                                                                                                                                       
-  if (struct A{}// { dg-error "types may not be defined|expected" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+  if (struct A{}// { dg-error "" }
diff --git c/gcc/testsuite/g++.dg/parse/crash10.C w/gcc/testsuite/g++.dg/parse/crash10.C
index 7e2dec6bcb3..f713c3cc65b 100644
--- c/gcc/testsuite/g++.dg/parse/crash10.C
+++ w/gcc/testsuite/g++.dg/parse/crash10.C
@@ -9,4 +9,3 @@  class
 {
   typename::
 ; // { dg-error "expected" }
- // { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/parse/crash18.C w/gcc/testsuite/g++.dg/parse/crash18.C
index 596d3109ccc..25311332e57 100644
--- c/gcc/testsuite/g++.dg/parse/crash18.C
+++ w/gcc/testsuite/g++.dg/parse/crash18.C
@@ -4,4 +4,4 @@ 
 // PR 18095: ICE
 // Origin: Volker Reichelt <reichelt@gcc.gnu.org>
 
-struct A // { dg-error "-:expected" "" { target *-*-* } .+1 }
+struct A // { dg-error "9:expected" }
diff --git c/gcc/testsuite/g++.dg/parse/crash27.C w/gcc/testsuite/g++.dg/parse/crash27.C
index 08977b2a4a8..4090fc5eab6 100644
--- c/gcc/testsuite/g++.dg/parse/crash27.C
+++ w/gcc/testsuite/g++.dg/parse/crash27.C
@@ -2,4 +2,4 @@ 
 
 void Dispatcher()
 	 (__builtin_offsetof (ArgsType, largeMsgLen)) // { dg-error "initialize" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "54:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/crash34.C w/gcc/testsuite/g++.dg/parse/crash34.C
index 86f79cc4aef..60f44ae39a1 100644
--- c/gcc/testsuite/g++.dg/parse/crash34.C
+++ w/gcc/testsuite/g++.dg/parse/crash34.C
@@ -4,4 +4,4 @@ 
 void foo()
 {
   namespace N { /* { dg-error "is not allowed" } */
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "16:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/crash35.C w/gcc/testsuite/g++.dg/parse/crash35.C
index 05f0a631a31..24b69f15afc 100644
--- c/gcc/testsuite/g++.dg/parse/crash35.C
+++ w/gcc/testsuite/g++.dg/parse/crash35.C
@@ -4,4 +4,4 @@ 
 struct a {};
 
 class foo : public a, a		// { dg-error "duplicate base" }
-{ // { dg-error "-:at end of input" "" { target *-*-* } .+1 } 
+{ // { dg-error "2:at end of input" } 
diff --git c/gcc/testsuite/g++.dg/parse/crash52.C w/gcc/testsuite/g++.dg/parse/crash52.C
index 5dfb69c41d6..ab30a7a5d57 100644
--- c/gcc/testsuite/g++.dg/parse/crash52.C
+++ w/gcc/testsuite/g++.dg/parse/crash52.C
@@ -1,4 +1,4 @@ 
 // PR c++/39053
 
 void foo() = // { dg-error "initialized" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "13:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/crash59.C w/gcc/testsuite/g++.dg/parse/crash59.C
index 7526b08e105..52b6b24381e 100644
--- c/gcc/testsuite/g++.dg/parse/crash59.C
+++ w/gcc/testsuite/g++.dg/parse/crash59.C
@@ -1,4 +1,4 @@ 
 // PR c++/53003
 
 struct A{ void a{} return b  // { dg-error "16:function definition" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "28:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/crash61.C w/gcc/testsuite/g++.dg/parse/crash61.C
index 713fe9f15e1..b2004b85173 100644
--- c/gcc/testsuite/g++.dg/parse/crash61.C
+++ w/gcc/testsuite/g++.dg/parse/crash61.C
@@ -5,4 +5,3 @@ 
 struct pair { constexpr pair (const) : }; // { dg-error "" }
 template <0> make_pair () {}		  // { dg-error "" }
 pair prefix[] = { 0, make_pair }	  // { dg-error "" }
-// { dg-error "-:expected" "" { target c++11 } .+1 }
diff --git c/gcc/testsuite/g++.dg/parse/crash67.C w/gcc/testsuite/g++.dg/parse/crash67.C
index 2a5bb3f1d91..8f6305dff3c 100644
--- c/gcc/testsuite/g++.dg/parse/crash67.C
+++ w/gcc/testsuite/g++.dg/parse/crash67.C
@@ -4,4 +4,4 @@ 
 class x0;
 template <x1> x2() {  // { dg-error "declared|type" }
 x0 x3 = x3. // { dg-error "incomplete type" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "12:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/error14.C w/gcc/testsuite/g++.dg/parse/error14.C
index fd654180007..3d87d46a5d0 100644
--- c/gcc/testsuite/g++.dg/parse/error14.C
+++ w/gcc/testsuite/g++.dg/parse/error14.C
@@ -20,4 +20,4 @@  struct X
 		  //    }
 
 };   // { dg-error "1:expected primary-expression before '.' token" "primary"  }
-// { dg-error "-:expected" "at end of input" { target *-*-* } .+1 }
+// { dg-error "3:expected" "at end of input" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/error56.C w/gcc/testsuite/g++.dg/parse/error56.C
index 11d31973138..bd3d27e8fcd 100644
--- c/gcc/testsuite/g++.dg/parse/error56.C
+++ w/gcc/testsuite/g++.dg/parse/error56.C
@@ -4,4 +4,3 @@  template <0> int __copy_streambufs_eof; // { dg-error "" }
 class {
 // { dg-error "forbids" "" { target *-*-* } .+1 }
     friend __copy_streambufs_eof <> ( // { dg-error "" }
- // { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/parse/invalid1.C w/gcc/testsuite/g++.dg/parse/invalid1.C
index cb4ef1a6902..971898f2d54 100644
--- c/gcc/testsuite/g++.dg/parse/invalid1.C
+++ w/gcc/testsuite/g++.dg/parse/invalid1.C
@@ -3,4 +3,4 @@ 
 // { dg-options "-w" }
 
 int foo ( foo += *[ // { dg-error "expected" }
-// { dg-error "-:invalid|expected" "" { target *-*-* } .+1 }
+// { dg-error "20:invalid|expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/parameter-declaration-1.C w/gcc/testsuite/g++.dg/parse/parameter-declaration-1.C
index c6106d5206e..bd8f7f93b0d 100644
--- c/gcc/testsuite/g++.dg/parse/parameter-declaration-1.C
+++ w/gcc/testsuite/g++.dg/parse/parameter-declaration-1.C
@@ -3,5 +3,5 @@ 
 // { dg-do compile }
 
 struct {
-  a(void = 0; a(0), a(0) // { dg-error "" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+  a(void = 0; a(0), a(0) // { dg-error "invalid|cannot|before|forbid|member" }
+// { dg-error "25:end of input" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/parser-pr28152-2.C w/gcc/testsuite/g++.dg/parse/parser-pr28152-2.C
index 28048bd1a9a..8f6cce80778 100644
--- c/gcc/testsuite/g++.dg/parse/parser-pr28152-2.C
+++ w/gcc/testsuite/g++.dg/parse/parser-pr28152-2.C
@@ -8,4 +8,4 @@  main (void)
 
   z = __complex__ (1.90000007326203904e+19, 0.0);   // { dg-error "expected primary-expression before '__complex__'" "primary-expression" } 
   z = __complex__ (1.0e+0, 0.0) / z;    // { dg-error "expected primary-expression before '__complex__'" "primaty-expression" } 
-  // { dg-error "-:at end of input" "end" { target *-*-* } .+1 }
+  // { dg-error "37:at end of input" "end" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/parser-pr28152.C w/gcc/testsuite/g++.dg/parse/parser-pr28152.C
index 34617340fab..748c355bafc 100644
--- c/gcc/testsuite/g++.dg/parse/parser-pr28152.C
+++ w/gcc/testsuite/g++.dg/parse/parser-pr28152.C
@@ -8,4 +8,4 @@  main (void)
 
   z = _Complex (1.90000007326203904e+19, 0.0);   // { dg-error "expected primary-expression before '_Complex'" "primary-expression" } 
   z = _Complex (1.0e+0, 0.0) / z;    // { dg-error "expected primary-expression before '_Complex'" "primary-expression" } 
-  // { dg-error "-:at end of input" "end" { target *-*-* } .+1 }
+  // { dg-error "34:at end of input" "end" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/parse/pr68722.C w/gcc/testsuite/g++.dg/parse/pr68722.C
index 26f6d11cfe1..6d2f1008cf9 100644
--- c/gcc/testsuite/g++.dg/parse/pr68722.C
+++ w/gcc/testsuite/g++.dg/parse/pr68722.C
@@ -6,4 +6,3 @@  class A {
   A _M_ios_locale ios_base(ios_base &) template <_Traits> class basic_ios {  // { dg-error "" }
     basic_ios basic_ios = operator= // { dg-error "" }
 // { dg-prune-output "file ends in default argument" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/parse/pr96258.C w/gcc/testsuite/g++.dg/parse/pr96258.C
index 1b642e1fc38..4d14a80e255 100644
--- c/gcc/testsuite/g++.dg/parse/pr96258.C
+++ w/gcc/testsuite/g++.dg/parse/pr96258.C
@@ -1,5 +1,3 @@ 
 // { dg-additional-options -fopenmp }
 // { dg-require-effective-target fopenmp } 
-#pragma omp declare simd // { dg-error "not immediately followed by" }
-
-// { dg-error "-:expected unqualified-id" "" { target *-*-* } .+1 }
+#pragma omp declare simd // { dg-error "" }
diff --git c/gcc/testsuite/g++.dg/pr46852.C w/gcc/testsuite/g++.dg/pr46852.C
index 5cfeaf96e19..e3cb40247ba 100644
--- c/gcc/testsuite/g++.dg/pr46852.C
+++ w/gcc/testsuite/g++.dg/pr46852.C
@@ -5,4 +5,3 @@  template
 <
 class
 { // { dg-error "" }
-// { dg-error "-:" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/pr46868.C w/gcc/testsuite/g++.dg/pr46868.C
index 25b8c966f4d..544c7b219df 100644
--- c/gcc/testsuite/g++.dg/pr46868.C
+++ w/gcc/testsuite/g++.dg/pr46868.C
@@ -2,4 +2,3 @@ 
 // { dg-do compile }
 
 template < int > struct S { S < // { dg-error "" }
-  // { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/template/crash115.C w/gcc/testsuite/g++.dg/template/crash115.C
index c1a72352714..80f8683a136 100644
--- c/gcc/testsuite/g++.dg/template/crash115.C
+++ w/gcc/testsuite/g++.dg/template/crash115.C
@@ -1,4 +1,3 @@ 
 // PR c++/56534
 
 template < struct template rebind < > // { dg-error "expected|must follow" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/template/crash43.C w/gcc/testsuite/g++.dg/template/crash43.C
index 3647a17cad8..ae644ede97e 100644
--- c/gcc/testsuite/g++.dg/template/crash43.C
+++ w/gcc/testsuite/g++.dg/template/crash43.C
@@ -5,4 +5,3 @@  extern "C" {
   struct ___is_pod {
     enum {
       __value = (sizeof(__gnu_internal::__test_type<_Tp>(0)))}; // { dg-error "expected|declared"  }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/template/crash90.C w/gcc/testsuite/g++.dg/template/crash90.C
index e2a58e31819..125ab0a9d46 100644
--- c/gcc/testsuite/g++.dg/template/crash90.C
+++ w/gcc/testsuite/g++.dg/template/crash90.C
@@ -5,5 +5,4 @@  struct A ;
 template < typename >
 struct B ;
 template < typename T , A < B < T > {} // { dg-error "parse error|non-type|initializer" }
-
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "39:expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.dg/template/error-recovery1.C w/gcc/testsuite/g++.dg/template/error-recovery1.C
index 6f9ce6d6bc2..962571474fb 100644
--- c/gcc/testsuite/g++.dg/template/error-recovery1.C
+++ w/gcc/testsuite/g++.dg/template/error-recovery1.C
@@ -7,4 +7,3 @@  template < typename > struct T
   template < bool > struct T < S > // { dg-error "" }
   {
     void f () { // { dg-error "expected" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git c/gcc/testsuite/g++.dg/template/error57.C w/gcc/testsuite/g++.dg/template/error57.C
index 121fbb1d523..f67e0a6fa63 100644
--- c/gcc/testsuite/g++.dg/template/error57.C
+++ w/gcc/testsuite/g++.dg/template/error57.C
@@ -2,4 +2,4 @@ 
 
 template <int()> struct a;
 template <int(b)> a < b		// { dg-error "int" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "expected" "" { target *-*-* } .-1 }
diff --git c/gcc/testsuite/g++.old-deja/g++.other/crash31.C w/gcc/testsuite/g++.old-deja/g++.other/crash31.C
index 610dfe11270..d777691c66c 100644
--- c/gcc/testsuite/g++.old-deja/g++.other/crash31.C
+++ w/gcc/testsuite/g++.old-deja/g++.other/crash31.C
@@ -6,5 +6,4 @@  namespace bar
 struct foo
 {
   foo();
-};
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+}; // { dg-error "3:expected"  }
diff --git c/libcody/Makefile.in w/libcody/Makefile.in
index a0722f9a385..6e38d51516f 100644
--- c/libcody/Makefile.in
+++ w/libcody/Makefile.in
@@ -100,7 +100,7 @@  endif
 CXXOPTS += $(filter-out -DHAVE_CONFIG_H,@DEFS@) -include config.h
 
 # Linker options
-LDFLAGS := -L. @LDFLAGS@
+LDFLAGS := @LDFLAGS@
 LIBS := @LIBS@
 
 # Per-source & per-directory compile flags (warning: recursive)
diff --git c/libcody/tests/01-serialize/connect.cc w/libcody/tests/01-serialize/connect.cc
deleted file mode 100644
index 85277c844af..00000000000
--- c/libcody/tests/01-serialize/connect.cc
+++ /dev/null
@@ -1,30 +0,0 @@ 
-
-// Test client connection handshake
-// RUN: <<HELLO 1 TESTING
-// RUN: $subdir$stem | ezio -p OUT $test |& ezio -p ERR $test
-// RUN-END:
-
-// OUT-NEXT:^HELLO {:[0-9]+} TEST IDENT$
-// OUT-NEXT:$EOF
-
-// ERR-NEXT:Code:{:[0-9]+}$
-// ERR-NEXT:Version:1$
-// ERR-NEXT:$EOF
-
-
-// Cody
-#include "cody.hh"
-// C++
-#include <iostream>
-
-using namespace Cody;
-
-int main (int, char *[])
-{
-  Client client (0, 1);
-
-  auto token = client.Connect ("TEST", "IDENT");
-
-  std::cerr << "Code:" << token.GetCode () << '\n';
-  std::cerr << "Version:" << token.GetInteger () << '\n';
-}
diff --git c/libcody/tests/01-serialize/decoder.cc w/libcody/tests/01-serialize/decoder.cc
deleted file mode 100644
index a3495d145da..00000000000
--- c/libcody/tests/01-serialize/decoder.cc
+++ /dev/null
@@ -1,73 +0,0 @@ 
-// CODYlib		-*- mode:c++ -*-
-// Copyright (C) 2020 Nathan Sidwell, nathan@acm.org
-// License: Apache v2.0
-
-// RUN: <<bob 'frob dob''\nF\_b\20\61\\'
-// RUN: $subdir$stem |& ezio $test
-// CHECK-NEXT: ^line:0 word:0 'bob'
-// CHECK-NEXT: ^line:0 word:1 'frob dob$
-// CHECK-OPTION: matchSpace
-// CHECK-NEXT: ^F b a\'$
-// CHECK-NEXT: $EOF
-
-/* RUN: <<line-1 word:1 ;
-   RUN: <<'line 2' ;
-   RUN: <<
-*/
-// RUN: $subdir$stem |& ezio -p CHECK2 $test
-// CHECK2-NEXT: line:0 word:0 'line-1'
-// CHECK2-NEXT: line:0 word:1 'word:1'
-// CHECK2-NEXT: line:1 word:0 'line 2'
-// CHECK2-NEXT: error:No 
-// CHECK2-NEXT: $EOF
-
-// RUN: <<'
-// RUN: $subdir$stem |& ezio -p CHECK3 $test
-// CHECK3-NEXT: error:Invalid argument
-// CHECK3-NEXT: line:0 word:0 '''
-// CHECK3-NEXT: $EOF
-
-/* RUN: << ;
-   RUN: <<'\g'
-*/
-// RUN: $subdir$stem |& ezio -p CHECK4 $test
-// CHECK4-NEXT: error:No 
-// CHECK4-NEXT: error:Invalid argument
-// CHECK4-NEXT: line:1 word:0 ''\g''
-// CHECK4-NEXT: $EOF
-
-// RUN-END:
-
-// Cody
-#include "cody.hh"
-// C++
-#include <iostream>
-// C
-#include <cstring>
-
-using namespace Cody;
-
-int main (int, char *[])
-{
-  Detail::MessageBuffer reader;
-
-  reader.PrepareToRead ();
-  while (int e = reader.Read (0))
-    if (e != EAGAIN && e != EINTR)
-      break;
-
-  std::vector<std::string> words;
-  for (unsigned line = 0; !reader.IsAtEnd (); line++)
-    {
-      if (int e = reader.Lex (words))
-	std::cerr << "error:" << strerror (e) << '\n';
-      for (unsigned ix = 0; ix != words.size (); ix++)
-	{
-	  auto &word = words[ix];
-
-	  std::cerr << "line:" << line << " word:" << ix
-		    << " '" << word << "'\n";
-	}
-    }
-  return 0;
-}
diff --git c/libcody/tests/01-serialize/encoder.cc w/libcody/tests/01-serialize/encoder.cc
deleted file mode 100644
index c4cab6c630f..00000000000
--- c/libcody/tests/01-serialize/encoder.cc
+++ /dev/null
@@ -1,48 +0,0 @@ 
-// CODYlib		-*- mode:c++ -*-
-// Copyright (C) 2020 Nathan Sidwell, nathan@acm.org
-// License: Apache v2.0
-
-// Test message encoding, both string quoting and continuation lines
-
-// RUN: $subdir$stem |& ezio $test
-// RUN-END:
-// The ¯ is utf8-encoded as c2 af
-// CHECK-NEXT: ^bob 'frob dob''\n¯\\'$
-// CHECK-NEXT: ^2 ;$
-// CHECK-NEXT: ^3$
-// CHECK-NEXT: $EOF
-
-// Cody
-#include "cody.hh"
-
-using namespace Cody;
-
-int main (int, char *[])
-{
-  Detail::MessageBuffer writer;
-
-  writer.BeginLine ();
-  writer.AppendWord ("bob");
-  writer.AppendWord ("frob dob", true);
-  writer.Append ("\n\xc2\xaf\\", true);
-  writer.EndLine ();
-
-  writer.PrepareToWrite ();
-  while (int err = writer.Write (2))
-    if (err != EAGAIN && err != EINTR)
-      break;
-
-  writer.BeginLine ();
-  writer.Append ("2", true);
-  writer.EndLine ();
-  writer.BeginLine ();
-  writer.Append ("3", true);
-  writer.EndLine ();
-
-  writer.PrepareToWrite ();
-  while (int err = writer.Write (2))
-    if (err != EAGAIN && err != EINTR)
-      break;
-
-  return 0;
-}
diff --git c/libcody/tests/02-comms/client-1.cc w/libcody/tests/02-comms/client-1.cc
deleted file mode 100644
index edff0ab4732..00000000000
--- c/libcody/tests/02-comms/client-1.cc
+++ /dev/null
@@ -1,97 +0,0 @@ 
-
-// Test client message round tripping
-/*
-  RUN: <<HELLO 1 TESTING ;
-  RUN: <<PATHNAME REPO ;
-  RUN: <<PATHNAME biz/bar ;
-  RUN: <<PATHNAME blob ;
-  RUN: <<BOOL FALSE ;
-  RUN: << BOOL TRUE ;
-  RUN: << PATHNAME foo ;
-  RUN: <<OK
-*/
-// RUN: $subdir$stem | ezio -p OUT $test |& ezio -p ERR $test
-// RUN-END:
-
-/*
-  OUT-NEXT:^HELLO {:[0-9]+} TEST IDENT ;$
-  OUT-NEXT:^MODULE-REPO ;
-  OUT-NEXT:^MODULE-EXPORT bar ;
-  OUT-NEXT:^MODULE-IMPORT foo ;
-  OUT-NEXT:^INCLUDE-TRANSLATE baz.frob ;
-  OUT-NEXT:^INCLUDE-TRANSLATE ./corge ;
-  OUT-NEXT:^INCLUDE-TRANSLATE ./quux ;
-  OUT-NEXT:^MODULE-COMPILED bar
-*/
-// OUT-NEXT:$EOF
-
-// ERR-NEXT:Code:1$
-// ERR-NEXT:Integer:1$
-// ERR-NEXT:Code:5$
-// ERR-NEXT:String:REPO$
-// ERR-NEXT:Code:5$
-// ERR-NEXT:String:biz/bar$
-// ERR-NEXT:Code:5$
-// ERR-NEXT:String:blob$
-// ERR-NEXT:Code:4$
-// ERR-NEXT:Integer:0$
-// ERR-NEXT:Code:4$
-// ERR-NEXT:Integer:1$
-// ERR-NEXT:Code:5$
-// ERR-NEXT:String:foo
-// ERR-NEXT:Code:3$
-// ERR-NEXT:Integer:
-// ERR-NEXT:$EOF
-
-
-// Cody
-#include "cody.hh"
-// C++
-#include <iostream>
-
-using namespace Cody;
-
-int main (int, char *[])
-{
-  Client client (0, 1);
-
-  client.Cork ();
-  if (client.Connect ("TEST", "IDENT").GetCode () != Client::PC_CORKED)
-    std::cerr << "Not corked!\n";
-  if (client.ModuleRepo ().GetCode () != Client::PC_CORKED)
-    std::cerr << "Not corked!\n";
-  if (client.ModuleExport ("bar").GetCode () != Client::PC_CORKED)
-    std::cerr << "Not corked!\n";
-  if (client.ModuleImport ("foo").GetCode () != Client::PC_CORKED)
-    std::cerr << "Not corked!\n";
-  if (client.IncludeTranslate ("baz.frob").GetCode () != Client::PC_CORKED)
-    std::cerr << "Not corked!\n";
-  if (client.IncludeTranslate ("./corge").GetCode () != Client::PC_CORKED)
-    std::cerr << "Not corked!\n";
-  if (client.IncludeTranslate ("./quux").GetCode () != Client::PC_CORKED)
-    std::cerr << "Not corked!\n";
-  if (client.ModuleCompiled ("bar").GetCode () != Client::PC_CORKED)
-    std::cerr << "Not corked!\n";
-
-  auto result = client.Uncork ();
-  for (auto iter = result.begin (); iter != result.end (); ++iter)
-    {
-      std::cerr << "Code:" << iter->GetCode () << '\n';
-      switch (iter->GetCategory ())
-	{
-	case Packet::INTEGER:
-	  std::cerr << "Integer:" << iter->GetInteger () << '\n';
-	  break;
-	case Packet::STRING:
-	  std::cerr << "String:" << iter->GetString () << '\n';
-	  break;
-	case Packet::VECTOR:
-	  {
-	    auto const &v = iter->GetVector ();
-	    for (unsigned ix = 0; ix != v.size (); ix++)
-	      std::cerr << "Vector[" << ix << "]:" << v[ix] << '\n';
-	  }
-	  break;
-	}
-    }
-}
diff --git c/libcody/tests/02-comms/pivot-1.cc w/libcody/tests/02-comms/pivot-1.cc
deleted file mode 100644
index b98c833ab27..00000000000
--- c/libcody/tests/02-comms/pivot-1.cc
+++ /dev/null
@@ -1,76 +0,0 @@ 
-
-// Test resolver pivot
-
-// RUN:<<HELLO 1 TEST IDENT ;
-// RUN:<<MODULE-REPO ;
-// RUN:<<HELLO 1 TEST IDENT
-// RUN: $subdir$stem | ezio -p OUT1 $test |& ezio -p ERR1 $test
-// OUT1-NEXT:HELLO 1 default ;
-// OUT1-NEXT:PATHNAME cmi.cache ;
-// OUT1-NEXT:ERROR 'already connected
-// OUT1-NEXT:$EOF
-// ERR1-NEXT:resolver is handler
-// ERR1-NEXT:$EOF
-
-// RUN:<<MODULE-REPO ;
-// RUN:<<HELLO 1 TEST IDENT ;
-// RUN:<<MODULE-REPO
-// RUN: $subdir$stem | ezio -p OUT2 $test |& ezio -p ERR2 $test
-// OUT2-NEXT:ERROR 'not connected
-// OUT2-NEXT:HELLO 1 default ;
-// OUT2-NEXT:PATHNAME cmi.cache
-// OUT2-NEXT:$EOF
-// ERR2-NEXT:resolver is handler
-// ERR2-NEXT:$EOF
-
-// RUN-END:
-#include "cody.hh"
-#include <iostream>
-
-using namespace Cody;
-
-class Handler : public Resolver
-{
-  virtual Handler *ConnectRequest (Server *s, unsigned ,
-				   std::string &, std::string &)
-  {
-    ErrorResponse (s, "unexpected connect call");
-    return nullptr;
-  }
-};
-
-Handler handler;
-
-class Initial : public Resolver
-{
-  virtual Handler *ConnectRequest (Server *s, unsigned v,
-				   std::string &agent, std::string &ident)
-  {
-    Resolver::ConnectRequest (s, v, agent, ident);
-    return &handler;
-  }
-};
-
-Initial initial;
-
-int main (int, char *[])
-{
-  Server server (&initial, 0, 1);
-
-  while (int e = server.Read ())
-    if (e != EAGAIN && e != EINTR)
-      break;
-
-  server.ProcessRequests ();
-  if (server.GetResolver () == &handler)
-    std::cerr << "resolver is handler\n";
-  else if (server.GetResolver () == &initial)
-    std::cerr << "resolver is initial\n";
-  else
-    std::cerr << "resolver is surprising\n";
-
-  server.PrepareToWrite ();
-  while (int e = server.Write ())
-    if (e != EAGAIN && e != EINTR)
-      break;
-}
diff --git c/libcody/tests/02-comms/server-1.cc w/libcody/tests/02-comms/server-1.cc
deleted file mode 100644
index 0a8694e94df..00000000000
--- c/libcody/tests/02-comms/server-1.cc
+++ /dev/null
@@ -1,68 +0,0 @@ 
-
-// Test server message round tripping
-/*
-  RUN:<<HELLO 1 TEST IDENT ;
-  RUN:<<MODULE-REPO ;
-  RUN:<<MODULE-EXPORT bar ;
-  RUN:<<MODULE-IMPORT foo ;
-  RUN:<<NOT A COMMAND ;
-  RUN:<<INCLUDE-TRANSLATE baz.frob ;
-  RUN:<<INCLUDE-TRANSLATE ./quux ;
-  RUN:<<MODULE-COMPILED bar ;
-  RUN:<<MODULE-IMPORT ''
-*/
-// RUN: $subdir$stem | ezio -p OUT1 $test |& ezio -p ERR1 $test
-
-// These all fail because there's nothing in the server interpretting stuff
-/*
-  OUT1-NEXT: ^HELLO 1 default	;
-  OUT1-NEXT: ^PATHNAME cmi.cache	;
-  OUT1-NEXT: ^PATHNAME bar.cmi	;
-  OUT1-NEXT: ^PATHNAME foo.cmi	;
-  OUT1-NEXT: ^ERROR 'unrecognized \'NOT
-  OUT1-NEXT: ^BOOL FALSE	;
-  OUT1-NEXT: ^BOOL FALSE	;
-  OUT1-NEXT: ^OK
-  OUT1-NEXT: ^ERROR 'malformed
-*/
-// OUT1-NEXT:$EOF
-// ERR1-NEXT:$EOF
-
-/*
-  RUN:<<HELLO 1 TEST IDENT
-  RUN:<<MODULE-REPO
-*/
-// RUN: $subdir$stem | ezio -p OUT2 $test |& ezio -p ERR2 $test
-/*
-  OUT2-NEXT: ^HELLO 1 default
-*/
-// OUT2-NEXT:$EOF
-// ERR2-NEXT:$EOF
-
-// RUN-END:
-
-// Cody
-#include "cody.hh"
-// C++
-#include <iostream>
-
-using namespace Cody;
-
-int main (int, char *[])
-{
-  Resolver r;
-  Server server (&r, 0, 1);
-
-  while (int e = server.Read ())
-    if (e != EAGAIN && e != EINTR)
-      break;
-
-  server.ProcessRequests ();
-  if (server.GetResolver () != &r)
-    std::cerr << "resolver changed\n";
-  server.PrepareToWrite ();
-
-  while (int e = server.Write ())
-    if (e != EAGAIN && e != EINTR)
-      break;
-}
diff --git c/libcody/tests/Makesub.in w/libcody/tests/Makesub.in
deleted file mode 100644
index 329e94609ee..00000000000
--- c/libcody/tests/Makesub.in
+++ /dev/null
@@ -1,36 +0,0 @@ 
-# CODYlib		-*- mode:Makefile -*-
-# Copyright (C) 2019-2020 Nathan Sidwell, nathan@acm.org
-# License: Apache v2.0
-
-ALOY := @ALOY@
-TESTS := $(patsubst $(srcdir)/%.cc,%,\
-	$(wildcard $(srcdir)/tests/*/*.cc))
-TESTDIRS = $(shell cd $(srcdir)/${<D} ; echo *(/))
-testdir := $(and $(filter-out /%,$(srcdir)),../)$(srcdir)/tests
-
-check:: tests/cody.defs $(TESTS)
-	+cd ${<D} && srcbuilddir=$(srcdir)/tests JOUST=${<F} \
-	  $(ALOY) -t kratos -o cody -g $(testdir)/jouster $(TESTDIRS)
-ifeq ($(firstword $(aloy)),:)
-	@echo WARNING: tests were not run as Joust test harness was not found
-endif
-
-tests/cody.defs: tests/Makesub
-	echo '# Automatically generated by Make' >$@
-	echo 'testdir=$(testdir)' >>$@
-	echo 'timelimit=60' >>$@
-	echo 'memlimit=1' >>$@
-	echo 'cpulimit=60' >>$@
-	echo 'filelimit=1' >>$@
-	echo 'SHELL=$(SHELL)' >>$@
-
-$(TESTS): %: %.o libcody.a
-	$(CXX) $(LDFLAGS) $< -lcody $(LIBS) -o $@
-
-clean::
-	rm -f $(TESTS)
-	rm -f $(TESTS:=.o) $(TESTS:=.d)
-
-ifeq ($(filter clean%,$(MAKECMDGOALS)),)
--include $(TESTS:=.d)
-endif
diff --git c/libcody/tests/jouster w/libcody/tests/jouster
deleted file mode 100755
index c7a913c8a19..00000000000
--- c/libcody/tests/jouster
+++ /dev/null
@@ -1,11 +0,0 @@ 
-#! /bin/zsh
-# CODYlib		-*- mode:Makefile -*-
-# Copyright (C) 2019-2020 Nathan Sidwell, nathan@acm.org
-# License Apache v2.0
-
-pushd ${0%/*}
-setopt nullglob
-for subdir in $@ ; do
-    echo $subdir/*(.^*)
-done
-popd