c++: EOF location [PR 96045]
authorNathan Sidwell <nathan@acm.org>
Wed, 23 Dec 2020 22:17:17 +0000 (14:17 -0800)
committerNathan Sidwell <nathan@acm.org>
Wed, 23 Dec 2020 22:26:50 +0000 (14:26 -0800)
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

48 files changed:
gcc/cp/parser.c
gcc/testsuite/c-c++-common/goacc/pr79428-1.c
gcc/testsuite/c-c++-common/gomp/pr79428-2.c
gcc/testsuite/c-c++-common/raw-string-6.c
gcc/testsuite/g++.dg/cpp0x/decltype63.C
gcc/testsuite/g++.dg/cpp0x/gen-attrs-64.C
gcc/testsuite/g++.dg/cpp0x/pr68726.C
gcc/testsuite/g++.dg/cpp0x/pr78341.C
gcc/testsuite/g++.dg/cpp1y/pr65202.C
gcc/testsuite/g++.dg/cpp1y/pr65340.C
gcc/testsuite/g++.dg/cpp1y/pr68578.C
gcc/testsuite/g++.dg/cpp1z/class-deduction44.C
gcc/testsuite/g++.dg/diagnostic/pr96045-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/diagnostic/pr96045-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/diagnostic/pr96045-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/diagnostic/unclosed-extern-c.C
gcc/testsuite/g++.dg/diagnostic/unclosed-function.C
gcc/testsuite/g++.dg/diagnostic/unclosed-namespace.C
gcc/testsuite/g++.dg/diagnostic/unclosed-struct.C
gcc/testsuite/g++.dg/ext/pr84598.C
gcc/testsuite/g++.dg/other/switch4.C
gcc/testsuite/g++.dg/parse/attr4.C
gcc/testsuite/g++.dg/parse/cond4.C
gcc/testsuite/g++.dg/parse/crash10.C
gcc/testsuite/g++.dg/parse/crash18.C
gcc/testsuite/g++.dg/parse/crash27.C
gcc/testsuite/g++.dg/parse/crash34.C
gcc/testsuite/g++.dg/parse/crash35.C
gcc/testsuite/g++.dg/parse/crash52.C
gcc/testsuite/g++.dg/parse/crash59.C
gcc/testsuite/g++.dg/parse/crash61.C
gcc/testsuite/g++.dg/parse/crash67.C
gcc/testsuite/g++.dg/parse/error14.C
gcc/testsuite/g++.dg/parse/error56.C
gcc/testsuite/g++.dg/parse/invalid1.C
gcc/testsuite/g++.dg/parse/parameter-declaration-1.C
gcc/testsuite/g++.dg/parse/parser-pr28152-2.C
gcc/testsuite/g++.dg/parse/parser-pr28152.C
gcc/testsuite/g++.dg/parse/pr68722.C
gcc/testsuite/g++.dg/parse/pr96258.C
gcc/testsuite/g++.dg/pr46852.C
gcc/testsuite/g++.dg/pr46868.C
gcc/testsuite/g++.dg/template/crash115.C
gcc/testsuite/g++.dg/template/crash43.C
gcc/testsuite/g++.dg/template/crash90.C
gcc/testsuite/g++.dg/template/error-recovery1.C
gcc/testsuite/g++.dg/template/error57.C
gcc/testsuite/g++.old-deja/g++.other/crash31.C

index 3883339..dd8e808 100644 (file)
@@ -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);
 
index 68dea5b..a8047e9 100644 (file)
@@ -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 }
+
index 0914963..6d162a2 100644 (file)
@@ -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 }
index a2cb30e..819dd44 100644 (file)
@@ -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 }
index b588bc3..ab1a411 100644 (file)
@@ -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"  }
index 822b64e..c82beb9 100644 (file)
@@ -2,4 +2,3 @@
 // { dg-do compile { target c++11 } }
 
 namespace alignas() N  {} // { dg-error "expected"  }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
index 636a20c..8edd439 100644 (file)
@@ -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 }
index 8573f9f..0a69210 100644 (file)
@@ -2,4 +2,3 @@
 // { dg-do compile { target c++11 } }
 
 alignas (alignas double // { dg-error "expected" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
index a76f8da..1f7219b 100644 (file)
@@ -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" }
index d3e03f7..e0ce681 100644 (file)
@@ -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 }
index 9b38981..f4be9da 100644 (file)
@@ -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 }
index 95caa99..419aaa2 100644 (file)
@@ -3,4 +3,3 @@
 
 template <typename> struct A;
 template <typename> struct B : A < B { , // { dg-error ""  }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr96045-1.C b/gcc/testsuite/g++.dg/diagnostic/pr96045-1.C
new file mode 100644 (file)
index 0000000..b84a5d5
--- /dev/null
@@ -0,0 +1,4 @@
+// PR 96045  EOF location
+
+template <class> class A {};
+struct A <int> // { dg-error "15:" }
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr96045-2.C b/gcc/testsuite/g++.dg/diagnostic/pr96045-2.C
new file mode 100644 (file)
index 0000000..1009ad0
--- /dev/null
@@ -0,0 +1,6 @@
+// PR 96045  EOF location
+
+template <class> class A {};
+struct A <int> // { dg-error "15:" }
+/* A comment */
+  
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr96045-3.C b/gcc/testsuite/g++.dg/diagnostic/pr96045-3.C
new file mode 100644 (file)
index 0000000..ad1f2a5
--- /dev/null
@@ -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" }
index f905e4f..4dad8a2 100644 (file)
@@ -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 } */
index 4d841d5..ff94bc7 100644 (file)
@@ -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"  } */
index 0887bc1..fc3fc08 100644 (file)
@@ -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" } */
index e68e599..e3faaae 100644 (file)
@@ -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"  }
index 8b78e0f..1dd09f9 100644 (file)
@@ -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 }
index 5d0047b..070c55e 100644 (file)
@@ -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" }
index 36ebdbd..f16bf47 100644 (file)
@@ -1,4 +1,3 @@
 // PR c++/93684 - ICE-on-invalid with broken attribute.
 
 [[a:: // { dg-error "expected" }
-  // { dg-error "-:expected" "" { target c++11 } .+1 }
index 893caea..6484f86 100644 (file)
@@ -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 "" }
index 7e2dec6..f713c3c 100644 (file)
@@ -9,4 +9,3 @@ class
 {
   typename::
 ; // { dg-error "expected" }
- // { dg-error "-:expected" "" { target *-*-* } .+1 }
index 596d310..2531133 100644 (file)
@@ -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" }
index 08977b2..4090fc5 100644 (file)
@@ -2,4 +2,4 @@
 
 void Dispatcher()
         (__builtin_offsetof (ArgsType, largeMsgLen)) // { dg-error "initialize" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "54:expected" "" { target *-*-* } .-1 }
index 86f79cc..60f44ae 100644 (file)
@@ -4,4 +4,4 @@
 void foo()
 {
   namespace N { /* { dg-error "is not allowed" } */
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "16:expected" "" { target *-*-* } .-1 }
index 05f0a63..24b69f1 100644 (file)
@@ -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" } 
index 5dfb69c..ab30a7a 100644 (file)
@@ -1,4 +1,4 @@
 // PR c++/39053
 
 void foo() = // { dg-error "initialized" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+// { dg-error "13:expected" "" { target *-*-* } .-1 }
index 7526b08..52b6b24 100644 (file)
@@ -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 }
index 713fe9f..b2004b8 100644 (file)
@@ -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 }
index 2a5bb3f..8f6305d 100644 (file)
@@ -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 }
index fd65418..3d87d46 100644 (file)
@@ -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 }
index 11d3197..bd3d27e 100644 (file)
@@ -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 }
index cb4ef1a..971898f 100644 (file)
@@ -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 }
index c6106d5..bd8f7f9 100644 (file)
@@ -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 }
index 28048bd..8f6cce8 100644 (file)
@@ -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 }
index 3461734..748c355 100644 (file)
@@ -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 }
index 26f6d11..6d2f100 100644 (file)
@@ -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 }
index 1b642e1..4d14a80 100644 (file)
@@ -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 "" }
index 5cfeaf9..e3cb402 100644 (file)
@@ -5,4 +5,3 @@ template
 <
 class
 { // { dg-error "" }
-// { dg-error "-:" "" { target *-*-* } .+1 }
index 25b8c96..544c7b2 100644 (file)
@@ -2,4 +2,3 @@
 // { dg-do compile }
 
 template < int > struct S { S < // { dg-error "" }
-  // { dg-error "-:expected" "" { target *-*-* } .+1 }
index c1a7235..80f8683 100644 (file)
@@ -1,4 +1,3 @@
 // PR c++/56534
 
 template < struct template rebind < > // { dg-error "expected|must follow" }
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
index 3647a17..ae644ed 100644 (file)
@@ -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 }
index e2a58e3..125ab0a 100644 (file)
@@ -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 }
index 6f9ce6d..9625714 100644 (file)
@@ -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 }
index 121fbb1..f67e0a6 100644 (file)
@@ -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 }
index 610dfe1..d777691 100644 (file)
@@ -6,5 +6,4 @@ namespace bar
 struct foo
 {
   foo();
-};
-// { dg-error "-:expected" "" { target *-*-* } .+1 }
+}; // { dg-error "3:expected"  }