From 8eae307d6148940f2fcb0796cf5389916d99e1b0 Mon Sep 17 00:00:00 2001
From: "James K. Lowden" <jklowden@symas.com>
Date: Fri, 10 Jan 2025 17:08:27 -0500
Subject: [PATCH] begin updating UAT with new diagnostics

---
 gcc/cobol/Make-lang.in                        |   2 +-
 gcc/cobol/UAT/testsuite.src/fixed_format.at   |   5 +-
 gcc/cobol/UAT/testsuite.src/run_functions.at  | 259 +++++++++++-------
 .../UAT/testsuite.src/run_fundamental.at      |   4 +-
 gcc/cobol/UAT/testsuite.src/run_misc.at       |  17 +-
 gcc/cobol/cbldiag.h                           |   9 +
 gcc/cobol/cdf-copy.cc                         |  21 +-
 gcc/cobol/cdf.y                               |   8 +-
 gcc/cobol/lexio.cc                            |   2 +-
 gcc/cobol/parse.y                             |  53 ++--
 gcc/cobol/scan.l                              |  39 +--
 gcc/cobol/scan_ante.h                         |  13 +
 gcc/cobol/util.cc                             |  45 ++-
 13 files changed, 297 insertions(+), 180 deletions(-)

diff --git a/gcc/cobol/Make-lang.in b/gcc/cobol/Make-lang.in
index 1a34a4bcc231..50ae0cfdab13 100644
--- a/gcc/cobol/Make-lang.in
+++ b/gcc/cobol/Make-lang.in
@@ -188,7 +188,7 @@ cobol/scan.c: cobol/scan.l
 	$(LEX) -o$@ $(LFLAGS) $< >$@~ 2>&1
 	awk  '! /$(FLEX_WARNING)/ {print > "/dev/stderr"; nerr++}	\
 	     END {print "$(LEX):", NR, "messages" > "/dev/stderr";	\
-		  exit nerr}' $@~					\
+		  exit nerr}' $@~
 	@rm $@~
 
 cobol/cdf.o: cobol/cdf.c			\
diff --git a/gcc/cobol/UAT/testsuite.src/fixed_format.at b/gcc/cobol/UAT/testsuite.src/fixed_format.at
index dfe1a4afa7c4..2e9c789377ce 100644
--- a/gcc/cobol/UAT/testsuite.src/fixed_format.at
+++ b/gcc/cobol/UAT/testsuite.src/fixed_format.at
@@ -29,7 +29,10 @@ AT_DATA([prog.cob], [
            EXIT PROGRAM.
 ])
 
-AT_CHECK([$COMPILE_FIXED prog.cob], [1], [], [prog.cob:4: syntax error at 'Asterisk'
+AT_CHECK([$COMPILE_FIXED prog.cob], [1], [],
+[prog.cob:4:8: error: syntax error, unexpected NAME, expecting end of file
+    4 |      * Asterisk in wrong column
+      |        ^
 cobol1: error: failed compiling prog.cob
 ])
 AT_CLEANUP
diff --git a/gcc/cobol/UAT/testsuite.src/run_functions.at b/gcc/cobol/UAT/testsuite.src/run_functions.at
index 112878f09ee7..91937b1d8efd 100644
--- a/gcc/cobol/UAT/testsuite.src/run_functions.at
+++ b/gcc/cobol/UAT/testsuite.src/run_functions.at
@@ -5266,28 +5266,51 @@ AT_DATA([prog.cob], [
 ])
 
 AT_CHECK([$COMPILE prog.cob], [1], [], 
-[prog.cob:12: error: format must be literal at 'invalid-date-format'
-prog.cob:12: syntax error at 'invalid-date-format'
-prog.cob:16: syntax error at 'END-IF'
-prog.cob:18: error: format must be literal at 'invalid-date-format'
-prog.cob:18: syntax error at 'invalid-date-format'
-prog.cob:22: syntax error at 'END-IF'
-prog.cob:25: error: format must be literal at 'invalid-datetime-format'
-prog.cob:25: syntax error at 'invalid-datetime-format'
-prog.cob:25: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:29: syntax error at 'END-IF'
-prog.cob:31: error: format must be literal at 'invalid-time-format'
-prog.cob:31: syntax error at 'invalid-time-format'
-prog.cob:35: syntax error at 'END-IF'
-prog.cob:38: error: format must be literal at 'invalid-date-format'
-prog.cob:38: syntax error at 'invalid-date-format'
-prog.cob:42: syntax error at 'END-IF'
-prog.cob:45: error: format must be literal at 'invalid-time-format'
-prog.cob:45: syntax error at 'invalid-time-format'
-prog.cob:49: syntax error at 'END-IF'
-prog.cob:52: error: format must be literal at 'invalid-datetime-format'
-prog.cob:52: syntax error at 'invalid-datetime-format'
-prog.cob:56: syntax error at 'END-IF'
+[prog.cob:12:29: error: syntax error, unexpected NAME, expecting DATETIME_FMT
+   12 |                            (invalid-date-format) <> SPACES
+      |                             ^
+prog.cob:16:12: error: syntax error, unexpected END_IF
+   16 |            END-IF
+      |            ^
+prog.cob:18:40: error: syntax error, unexpected NAME, expecting DATE_FMT
+   18 |            IF FUNCTION FORMATTED-DATE (invalid-date-format, 1) <> SPACES
+      |                                        ^
+prog.cob:22:12: error: syntax error, unexpected END_IF
+   22 |            END-IF
+      |            ^
+prog.cob:25:29: error: syntax error, unexpected NAME, expecting DATETIME_FMT
+   25 |                            (invalid-datetime-format, 1, 1) <> SPACES
+      |                             ^
+prog.cob:25:1: error: FORMATTED_DATETIME: invalid parameter value
+   25 |                            (invalid-datetime-format, 1, 1) <> SPACES
+      | ^
+prog.cob:29:12: error: syntax error, unexpected END_IF
+   29 |            END-IF
+      |            ^
+prog.cob:31:40: error: syntax error, unexpected NAME, expecting TIME_FMT
+   31 |            IF FUNCTION FORMATTED-TIME (invalid-time-format, 1) <> SPACES
+      |                                        ^
+prog.cob:35:12: error: syntax error, unexpected END_IF
+   35 |            END-IF
+      |            ^
+prog.cob:38:29: error: syntax error, unexpected NAME, expecting DATE_FMT or DATETIME_FMT
+   38 |                            (invalid-date-format, 1) <> ZERO
+      |                             ^
+prog.cob:42:12: error: syntax error, unexpected END_IF
+   42 |            END-IF
+      |            ^
+prog.cob:45:29: error: syntax error, unexpected NAME, expecting TIME_FMT or DATETIME_FMT
+   45 |                            (invalid-time-format, 1) <> ZERO
+      |                             ^
+prog.cob:49:12: error: syntax error, unexpected END_IF
+   49 |            END-IF
+      |            ^
+prog.cob:52:29: error: syntax error, unexpected NAME, expecting DATE_FMT or TIME_FMT or DATETIME_FMT
+   52 |                            (invalid-datetime-format, 1) <> ZERO
+      |                             ^
+prog.cob:56:12: error: syntax error, unexpected END_IF
+   56 |            END-IF
+      |            ^
 cobol1: error: failed compiling prog.cob
 ])
 
@@ -5308,8 +5331,12 @@ AT_DATA([prog.cob], [
            STOP RUN.
 ])
 AT_CHECK([$COMPILE prog.cob], [1], [],
-[prog.cob:8: error: symbol 'PI' not found at 'TO'
-prog.cob:9: error: symbol 'E' not found at 'TO'
+[prog.cob:8:17: error: symbol 'PI' not found
+    8 |            MOVE PI TO Z.
+      |                 ^
+prog.cob:9:17: error: symbol 'E' not found
+    9 |            MOVE E TO Z.
+      |                 ^
 cobol1: error: failed compiling prog.cob
 ])
 AT_CLEANUP
@@ -5371,7 +5398,9 @@ AT_DATA([prog.cob], [
        END PROGRAM prog.
 ])
 AT_CHECK([$COMPILE -c prog.cob], [1], [],
-[prog.cob:4: error: FUNCTION SUBSTITUTE is an intrinsic function
+[prog.cob:3:21: error: FUNCTION SUBSTITUTE is an intrinsic function
+    3 |        FUNCTION-ID. SUBSTITUTE.
+      |                     ^
 cobol1: error: failed compiling prog.cob
 ])
 AT_CLEANUP
@@ -5424,78 +5453,114 @@ AT_DATA([prog.cob], [
         END PROGRAM datetime.
 ])
 AT_CHECK([$COMPILE prog.cob], [1], [],
-[prog.cob:7: syntax error at ''
-prog.cob:7: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:8: syntax error at ''
-prog.cob:8: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:9: syntax error at ''
-prog.cob:9: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:10: syntax error at ''
-prog.cob:10: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:11: syntax error at ''
-prog.cob:11: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:12: syntax error at ''
-prog.cob:12: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:13: syntax error at ''
-prog.cob:13: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:14: syntax error at ''
-prog.cob:14: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:15: syntax error at ''
-prog.cob:15: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:16: syntax error at ''
-prog.cob:16: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:17: syntax error at ''
-prog.cob:17: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:18: syntax error at ''
-prog.cob:18: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:19: syntax error at ''
-prog.cob:19: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:20: syntax error at ''
-prog.cob:20: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:21: syntax error at ''
-prog.cob:21: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:22: syntax error at ''
-prog.cob:22: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:23: syntax error at ''
-prog.cob:23: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:24: syntax error at ''
-prog.cob:24: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:25: syntax error at ''
-prog.cob:25: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:26: syntax error at ''
-prog.cob:26: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:27: syntax error at ''
-prog.cob:27: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:28: syntax error at ''
-prog.cob:28: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:29: syntax error at ''
-prog.cob:29: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:30: syntax error at ''
-prog.cob:30: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:31: syntax error at ''
-prog.cob:31: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:32: syntax error at ''
-prog.cob:32: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:33: syntax error at ''
-prog.cob:33: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:34: syntax error at ''
-prog.cob:34: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:35: syntax error at ''
-prog.cob:35: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:36: syntax error at ''
-prog.cob:36: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:37: syntax error at ''
-prog.cob:37: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:38: syntax error at ''
-prog.cob:38: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:39: syntax error at ''
-prog.cob:39: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:40: syntax error at ''
-prog.cob:40: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:41: syntax error at ''
-prog.cob:41: error: FORMATTED_DATETIME: invalid parameter value at ')'
-prog.cob:42: syntax error at ''
-prog.cob:42: error: FORMATTED_DATETIME: invalid parameter value at ')'
+[prog.cob:7:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+    7 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:8:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+    8 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss+hhmm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:9:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+    9 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss.ssss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:10:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   10 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss.ssss+hhmm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:11:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   11 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmss.ssssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:12:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   12 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-DDDThhmmssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:13:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   13 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:14:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   14 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss+hhmm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:15:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   15 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss.ssss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:16:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   16 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss.ssss+hhmm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:17:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   17 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmss.ssssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:18:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   18 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-MM-DDThhmmssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:19:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   19 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:20:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   20 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss+hhmm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:21:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   21 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss.ssss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:22:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   22 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss.ssss+hhmm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:23:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   23 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmss.ssssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:24:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   24 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYY-Www-DThhmmssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:25:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   25 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:26:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   26 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss+hh:mm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:27:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   27 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss.ssss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:28:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   28 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss.ssss+hh:mm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:29:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   29 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ss.ssssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:30:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   30 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYDDDThh:mm:ssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:31:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   31 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:32:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   32 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss+hh:mm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:33:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   33 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss.ssss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:34:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   34 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss.ssss+hh:mm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:35:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   35 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ss.ssssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:36:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   36 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYMMDDThh:mm:ssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:37:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   37 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:38:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   38 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss+hh:mm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:39:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   39 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss.ssss" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:40:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   40 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss.ssss+hh:mm" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:41:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   41 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ss.ssssZ" 128623 45296.987654321 -300).
+      |                                             ^
+prog.cob:42:45: error: syntax error, unexpected LITERAL, expecting DATETIME_FMT
+   42 |         DISPLAY FUNCTION FORMATTED-DATETIME("YYYYWwwDThh:mm:ssZ" 128623 45296.987654321 -300).
+      |                                             ^
 cobol1: error: failed compiling prog.cob
 ])
 AT_CLEANUP
diff --git a/gcc/cobol/UAT/testsuite.src/run_fundamental.at b/gcc/cobol/UAT/testsuite.src/run_fundamental.at
index 481d77ef6bff..62a6f79638e4 100644
--- a/gcc/cobol/UAT/testsuite.src/run_fundamental.at
+++ b/gcc/cobol/UAT/testsuite.src/run_fundamental.at
@@ -3952,7 +3952,9 @@ AT_DATA([prog.cob], [
        STOP RUN.
 ])
 AT_CHECK([$COMPILE prog.cob], [0], [],
-[prog.cob:20: warning: GROUP-2 and GROUP-1 have no corresponding fields
+[prog.cob:20:17: warning: GROUP-2 and GROUP-1 have no corresponding fields
+   20 |        SUBTRACT CORRESPONDING GROUP-2 FROM GROUP-1.
+      |                 ^
 ])
 AT_CHECK([./a.out], [0], [], [])
 AT_CLEANUP
diff --git a/gcc/cobol/UAT/testsuite.src/run_misc.at b/gcc/cobol/UAT/testsuite.src/run_misc.at
index dea7deebd756..13099218186a 100644
--- a/gcc/cobol/UAT/testsuite.src/run_misc.at
+++ b/gcc/cobol/UAT/testsuite.src/run_misc.at
@@ -32,8 +32,9 @@ AT_DATA([prog.cob], [
            STOP RUN.
 ])
 AT_CHECK([$COMPILE_ONLY prog.cob], [1], [],
-[prog.cob:6: error: 01 X: invalid LEVEL for OCCURS
-prog.cob:7: 1 errors in DATA DIVISION, compilation ceases at 'PROCEDURE        DIVISION'
+[prog.cob:6:31: error: 01 X: invalid LEVEL for OCCURS
+    6 |        01 X             PIC X OCCURS 10.
+      |                               ^
 cobol1: error: failed compiling prog.cob
 ])
 AT_CLEANUP
@@ -1542,8 +1543,12 @@ AT_DATA([prog.cob], [
            STOP RUN.
 ])
 AT_CHECK([$COMPILE prog.cob], [1], [],
-[prog.cob:14: error: cannot MOVE LOW_VALUES to numeric receiving field NUM9 at 'DISPLAY'
-prog.cob:26: error: cannot MOVE HIGH_VALUES to numeric receiving field NUM9 at 'DISPLAY'
+[prog.cob:13:17: error: cannot MOVE LOW_VALUES to numeric receiving field NUM9
+   13 |            MOVE LOW-VALUES TO NUM9
+      |                 ^
+prog.cob:25:17: error: cannot MOVE HIGH_VALUES to numeric receiving field NUM9
+   25 |            MOVE HIGH-VALUES TO NUM9
+      |                 ^
 cobol1: error: failed compiling prog.cob
 ])
 AT_CLEANUP
@@ -3058,7 +3063,9 @@ AT_DATA([prog.cob], [
        END PROGRAM "S U B".
 ])
 AT_CHECK([$COMPILE prog.cob], [1], [],
-[prog.cob:18: error: literal 'SUB ' must be a COBOL or C identifier at '"'
+[prog.cob:18:20: error: literal 'SUB ' must be a COBOL or C identifier
+   18 |        PROGRAM-ID. "SUB ".
+      |                    ^
 cobol1: error: failed compiling prog.cob
 ])
 AT_CLEANUP
diff --git a/gcc/cobol/cbldiag.h b/gcc/cobol/cbldiag.h
index 8e2cff36df8e..25284b63c2b3 100644
--- a/gcc/cobol/cbldiag.h
+++ b/gcc/cobol/cbldiag.h
@@ -37,6 +37,15 @@ const char * cobol_filename();
 void yyerror( const char fmt[], ... );
 bool yywarn( const char fmt[], ... );
 
+#ifndef YYLTYPE
+struct  YYLTYPE;
+#endif
+#ifndef YDFLTYPE
+struct  YDFLTYPE;
+#endif
+// an error at a location, called from the parser for semantic errors
+void error_msg( const YYLTYPE& loc, const char gmsgid[], ... );
+
 // for CDF and other warnings that refer back to an earlier line
 // (not in diagnostic framework yet)
 void yyerrorvl( int line, const char *filename, const char fmt[], ... );
diff --git a/gcc/cobol/cdf-copy.cc b/gcc/cobol/cdf-copy.cc
index c207305c469c..d30bc031c471 100644
--- a/gcc/cobol/cdf-copy.cc
+++ b/gcc/cobol/cdf-copy.cc
@@ -170,7 +170,7 @@ esc( size_t len, const char input[] ) {
 }
 
 static int
-glob_error(const char *epath, int eerrno) {
+asdfglob_error(const char *epath, int eerrno) {
   yyerror("COPY file search: '%s': %s", epath, xstrerror(eerrno));
   return 0;
 }
@@ -285,12 +285,10 @@ copybook_elem_t::open_file( const char directory[], bool literally ) {
   gcc_assert(path);
   
   if( literally ) {
-    if( yydebug ) {
-      dbgmsg("copybook_elem_t::open_file: trying %s", path);
-    }
+    dbgmsg("copybook_elem_t::open_file: trying %s", path);
 
     if( (this->fd = open(path, O_RDONLY)) == -1 ) {
-      if( yydebug ) yywarn("could not open %s", path);
+      dbgmsg("could not open %s", path);
       return fd;
     } 
     this->source = xstrdup(path);
@@ -304,15 +302,10 @@ copybook_elem_t::open_file( const char directory[], bool literally ) {
   gcc_assert( ! literally );
   
   if( extensions ) {
-    if( -1 == asprintf(&pattern, "%s{,.cpy,.CPY,.cbl,.CBL,.cob,.COB,%s}",
-                       path, this->extensions) ) {
-      cbl_err("could not create glob pattern");
-    }
+    pattern = xasprintf("%s{,.cpy,.CPY,.cbl,.CBL,.cob,.COB,%s}",
+                        path, this->extensions);
   } else {
-    if( -1 == asprintf(&pattern, "%s{,.cpy,.CPY,.cbl,.CBL,.cob,.COB}",
-                       path) ) {
-      cbl_err("could not create glob pattern");
-    }
+    pattern = xasprintf("%s{,.cpy,.CPY,.cbl,.CBL,.cob,.COB}", path);
   }
 
   free(copier);
@@ -329,7 +322,7 @@ copybook_elem_t::open_file( const char directory[], bool literally ) {
       yywarn("COPY file search: read error");
       break;
     case GLOB_NOMATCH:
-      if( yydebug) yywarn("COPY '%s': no files match %s", this->source, pattern);
+      dbgmsg("COPY '%s': no files match %s", this->source, pattern);
     default:
       break; // caller says no file found
     }
diff --git a/gcc/cobol/cdf.y b/gcc/cobol/cdf.y
index 568eca2482b3..0cfeb342758b 100644
--- a/gcc/cobol/cdf.y
+++ b/gcc/cobol/cdf.y
@@ -55,16 +55,14 @@ integer_literal( const char input[] ) {
 
 const char * cdf_token_str( int token );
 
-/* The renamed symbols include ‘yyparse’, ‘yylex’, ‘yyerror’,
-   ‘yynerrs’, ‘yylval’, ‘yylloc’, ‘yychar’ and ‘yydebug’.  [...] The
-   renamed macros include ‘YYSTYPE’, ‘YYLTYPE’, and ‘YYDEBUG’, which
-   is treated specifically — more about this below.... */
+/* "The renamed symbols include 'yyparse', 'yylex', 'yyerror',
+    'yynerrs', 'yylval', 'yylloc', 'yychar' and 'yydebug'.  [...] The
+    renamed macros include 'YYSTYPE', 'YYLTYPE', and 'YYDEBUG'" */
 
 extern int yylineno, yyleng;
 extern char *yytext;
 
 static int ydflex(void);
-////void ydferror( const char gmsgid[], ... );
 
 #define PROGRAM current_program_index()
 %}
diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc
index b5a1dc88024e..d2f9d453dd45 100644
--- a/gcc/cobol/lexio.cc
+++ b/gcc/cobol/lexio.cc
@@ -1634,7 +1634,7 @@ cdftext::free_form_reference_format( int input ) {
       default: // flag other characters in indicator area
         if( ! ISSPACE(indcol[0]) ) {
           yyerrorvl( mfile.lineno, cobol_filename(), 
-                     "error: stray indicator '%c' (0x%0x): \"%.*s\"",
+                     "error: stray indicator '%c' (0x%x): \"%.*s\"",
                      indcol[0], indcol[0],
                      int(mfile.line_length() - 1), mfile.cur );
           *indcol = SPACE;
diff --git a/gcc/cobol/parse.y b/gcc/cobol/parse.y
index 305baf00edf8..2fb7efffe10a 100644
--- a/gcc/cobol/parse.y
+++ b/gcc/cobol/parse.y
@@ -1005,7 +1005,7 @@ program_id:     PROGRAM_ID dot namestr[name] program_as program_attrs[attr] dot
 
                   const char *name = string_of($name);
 		  if( 0 == strcasecmp(name, "main") ) {
-                    yywarn("PROGRAM-ID 'main' is invalid for a Posix executable");
+                    dbgmsg("PROGRAM-ID 'main' is invalid for a Posix executable");
 		  }
 
                   parser_enter_program( name, false );
@@ -1016,7 +1016,7 @@ program_id:     PROGRAM_ID dot namestr[name] program_as program_attrs[attr] dot
                                            $attr.common, $attr.initial) ) {
                     auto L = symbol_program(current_program_index(), name);
                     assert(L);
-                    yyerror("PROGRAM-ID %s already defined on line %d",
+                    error_msg(@name, "PROGRAM-ID %s already defined on line %d",
                              name, L->line);
                     YYERROR;
                   }
@@ -1038,7 +1038,7 @@ function_id:    FUNCTION '.' NAME program_as program_attrs[attr] '.'
                   location_set(@1);
 
 		  if( 0 == strcasecmp($NAME, "main") ) {
-                    yywarn("FUNCTION 'main' is invalid for a Posix executable");
+                    dbgmsg("FUNCTION 'main' is invalid for a Posix executable");
 		  }
 
                   parser_enter_program( $NAME, true );
@@ -1049,13 +1049,13 @@ function_id:    FUNCTION '.' NAME program_as program_attrs[attr] '.'
                                       $attr.common, $attr.initial) ) {
                     auto L = symbol_program(current_program_index(), $NAME);
                     assert(L);
-                    yyerror("FUNCTION %s already defined on line %d",
-                             $NAME, L->line);
+                    error_msg(@NAME, "FUNCTION %s already defined on line %d",
+			      $NAME, L->line);
                     YYERROR;
                   }
                   if( keyword_tok($NAME, true) ) {
-                    yyerror("FUNCTION %s is an intrinsic function",
-                             $NAME);
+		    error_msg(@NAME, "FUNCTION %s is an intrinsic function",
+			      $NAME);
                     YYERROR;
                   }
                   current.udf_add(current_program_index());
@@ -1227,19 +1227,19 @@ opt_init_value: BINARY ZERO { $$ = constant_index(NULLS); }
 namestr:        ctx_name {
                   $$ = literal_of($1);
                   if( ! string_of($$) ) {
-                    yyerror("'%s' has embedded NUL", $$.data);
+                    error_msg(@1, "'%s' has embedded NUL", $$.data);
                     YYERROR;
                   }
                 }
         |       LITERAL {
                   if( $$.prefix[0] != '\0' ) {
-                    yyerror("literal cannot use %s prefix in this context",
-                             $$.prefix);
+                    error_msg(@1, "literal cannot use %s prefix in this context",
+                              $$.prefix);
                     YYERROR;
                   }
                   if( !is_cobol_word($$.data) ) {
-                    yyerror("literal '%s' must be a COBOL or C identifier",
-                             $$.data);
+		    error_msg(@1, "literal '%s' must be a COBOL or C identifier",
+                              $$.data);
                   }
                 }
                 ;
@@ -3448,8 +3448,8 @@ data_clause:    any_length        { $$ = any_length_e; }
 		    __attribute__((fallthrough));
                   case 77:
                   case 88:
-                    yyerror("%s %s: invalid LEVEL for OCCURS",
-			    field->level_str(), field->name );
+		    error_msg(@$, "%s %s: invalid LEVEL for OCCURS",
+			      field->level_str(), field->name );
                     break;
                   default:
                     assert( field->parent > 0 );
@@ -5948,7 +5948,7 @@ typename:       NAME
                 {
                   auto e = symbol_typedef(PROGRAM, $NAME);
                   if( ! e ) {
-                    yyerror("symbol '%s' not found", $NAME );
+		    error_msg(@1, "symbol '%s' not found", $NAME );
                     YYERROR;
                   }
                   $$ = cbl_field_of(e);
@@ -5962,7 +5962,7 @@ name:           qname
 
                   if( ($$ = field_find(names)) == NULL ) {
                     if( procedure_div_e == current_division  ) {
-                      yyerror("symbol '%s' not found", names.back() );
+		      error_msg(@1, "symbol '%s' not found", names.back() );
                       YYERROR;
                     }
                     /*
@@ -6195,10 +6195,10 @@ move:           MOVE scalar TO move_tgts[tgts]
                                             } );
 
                   if( p != $tgts->targets.end() ) {
-                      yyerror("cannot MOVE %s "
-                                "to numeric receiving field %s",
-                                constant_of(constant_index($src))->name,
-                                field->name );
+                    error_msg(@src, "cannot MOVE %s "
+			            "to numeric receiving field %s",
+			      constant_of(constant_index($src))->name,
+			      field->name );
                     YYERROR;
                   }
 
@@ -9663,7 +9663,6 @@ intrinsic:      function_udf
                                              r1, $r2, $r3, $r4) ) YYERROR;
                 }
         |       FORMATTED_DATETIME '(' error ')' {
-                  yyerror("FORMATTED_DATETIME: invalid parameter value");
                   YYERROR;
                 }
         |       FORMATTED_TIME '(' TIME_FMT[r1] expr[r2]
@@ -9844,7 +9843,7 @@ intrinsic:      function_udf
                                                  *$r2.arg2, $anycase, true );
                 }
         |       TRIM '(' error ')' {
-                  yyerror("invalid TRIM argument");
+                  error_msg(@error, "invalid TRIM argument");
                   YYERROR;
                 }
         |       TRIM '(' expr[r1] trim_trailing ')'
@@ -9862,7 +9861,7 @@ intrinsic:      function_udf
                      if( $r1->field->has_attr(blank_zero_e) ) {
                        break;
                      }
-                     yyerror("TRIM argument must be alphanumeric");
+                     error_msg(@r1, "TRIM argument must be alphanumeric");
                      YYERROR;
                      break;
                   }
@@ -9920,7 +9919,7 @@ intrinsic:      function_udf
                       output = strtof128(local, &pend);
                       // bad if strtof128 could not convert input
                       if( *pend != '\0' ) {
-                        yyerror("'%s' is not a numeric string", input);
+                        error_msg(@r1, "'%s' is not a numeric string", input);
                       }
                     }
                   }
@@ -10528,7 +10527,7 @@ cdf_use:        USE DEBUGGING on labels
         |       USE globally mistake procedure on filenames
 		{ 
                   if( ! current.declarative_section_name() ) {
-                    yyerror("USE valid only in DECLARATIVES");
+		    yyerror( "USE valid only in DECLARATIVES");
                     YYERROR;
                   }
                   bool global = $globally == GLOBAL;
@@ -10573,13 +10572,13 @@ cdf_use_except: EC NAME cdf_use_files[files]
                 {
                   auto ec = ec_type_of($NAME);
                   if( ec == ec_none_e ) {
-                    yyerror("not an EXCEPTION CONDITION: %s", $NAME);
+                    error_msg(@NAME, "not an EXCEPTION CONDITION: %s", $NAME);
                     YYERROR;
                   }
                   std::list<size_t> files;
                   if( $files ) {
                     if( ec_io_e != (ec_io_e & ec) ) {
-                      yyerror("not an I-O EXCEPTION CONDITION: %s", $NAME);
+                      error_msg(@NAME, "not an I-O EXCEPTION CONDITION: %s", $NAME);
                       YYERROR;
                     }
                     auto& culprits = $files->files;
diff --git a/gcc/cobol/scan.l b/gcc/cobol/scan.l
index ee5630b1b537..6b3103eddd9b 100644
--- a/gcc/cobol/scan.l
+++ b/gcc/cobol/scan.l
@@ -205,15 +205,15 @@ LINE_DIRECTIVE [#]line{SPC}[[:alnum:]]+{SPC}[""''].+\n
 			    ydflval.number = integer_of(yytext, true);
 			    return YDF_NUMBER;
 			  }
-			  if( 0 != yyleng % 2 ) {
-			    yyerror( "hex literal '%s' "
-				      "has an odd number (%d) of characters",
-				      yytext, yyleng );
-			    return NO_CONDITION; // invalid token
+			  if( 0 == yyleng % 2 ) {
+                            yylval.literal.set_data( yyleng/2, hex_decode(yytext) );
+			    update_location_col(yytext, -3);			    
+			    return LITERAL;
 			  }
-
-                          yylval.literal.set_data( yyleng/2, hex_decode(yytext) );
-			  return LITERAL;
+			  dbgmsg( "hex literal '%s' "
+				  "has an odd number (%d) of characters",
+				  yytext, yyleng );
+			  return '@'; // invalid token
 			}
   [''""] 		{ yy_pop_state(); }
 }
@@ -1117,7 +1117,7 @@ USE({SPC}FOR)?		{ return USE; }
 			  yy_push_state(quoted2); }
   N?X/{hexseq}		{ yylval.literal.set_prefix(yytext, yyleng);
 	    		  yy_push_state(hex_state); }
-  N?X{nonseq}		{ yyerror("invalid hexadecimal value: %s", yytext);
+  N?X{nonseq}		{ dbgmsg("invalid hexadecimal value: %s", yytext);
 			  return NO_CONDITION; }
   [[:blank:]]*\r?\n     {}
 
@@ -1210,7 +1210,7 @@ USE({SPC}FOR)?		{ return USE; }
   [^[:space:].,;]+([.,;][^[:space:].,;]+)* {
                          yylval.string = xstrdup(yytext); return picset(ALPHED); }
 
-  .     { yyerror("unrecognized character '%c' (0x%x) in PICTURE",
+  .     { dbgmsg("unrecognized character '%c' (0x%x) in PICTURE",
                     *yytext, *yytext ); return NO_CONDITION; }
 
 }
@@ -1256,9 +1256,11 @@ USE({SPC}FOR)?		{ return USE; }
   Z?['']{STRING1}['']   { auto *s = xstrdup(yytext);
 			  std::replace(s, s + strlen(s), '\'', '"');
 			  ydflval.string = s;
+			  update_location_col(s);			    
+			  return LITERAL; }
+  Z?[""]{STRING}[""]    { ydflval.string = xstrdup(yytext);
+			  update_location_col(yytext);			    
 			  return LITERAL; }
-  Z?[""]{STRING}[""]    { ydflval.string = xstrdup(yytext); return LITERAL; }
-
   [=]{4}                { static char nullstring[] = "";
                           ydflval.string = nullstring; return PSEUDOTEXT; }
   [=]{2}                { yy_push_state(quoteq); }
@@ -1268,6 +1270,7 @@ USE({SPC}FOR)?		{ return USE; }
   [^=]+[=]/[^=]       { tmpstring_append(yyleng); }
   [^=]+/[=]{2}        { yylval.string = xstrdup(tmpstring_append(yyleng));
                         ydflval.string = yylval.string;
+			update_location_col(yylval.string);			    
                         return PSEUDOTEXT; }
   [=]{2}              { tmpstring = NULL; yy_pop_state(); }
 }
@@ -1285,6 +1288,7 @@ USE({SPC}FOR)?		{ return USE; }
       			char *s = xstrdup(tmpstring? tmpstring : "\0");
                         yylval.literal.set_data(strlen(s), s);
                         ydflval.string = yylval.literal.data;
+			update_location_col(yylval.literal.data, -2);			    
                         tmpstring = NULL; pop_return LITERAL; }
 }
 
@@ -1301,6 +1305,7 @@ USE({SPC}FOR)?		{ return USE; }
       			char *s = xstrdup(tmpstring? tmpstring : "\0");
                         yylval.literal.set_data(strlen(s), s);
                         ydflval.string = yylval.literal.data;
+			update_location_col(yylval.literal.data, -2);			    
                         tmpstring = NULL; pop_return LITERAL; }
 }
 
@@ -1408,7 +1413,7 @@ USE({SPC}FOR)?		{ return USE; }
     B/{boolseq}			{ is_not = false; yy_push_state(bool_state); }
   N?X/{hexseq}			{ yylval.literal.set_prefix(yytext, yyleng);
 	    			  yy_push_state(hex_state); }
-  N?X{nonseq}		{ yyerror("invalid hexadecimal value: %s", yytext);
+  N?X{nonseq}		{ dbgmsg("invalid hexadecimal value: %s", yytext);
 			  return NO_CONDITION; }
 
   BX/{hexseq}			{ yylval.numstr.radix = hexadecimal_e;
@@ -1736,7 +1741,7 @@ USE({SPC}FOR)?		{ return USE; }
 
   {SPC}				// ignore
   {NAME}			{
-				  int token = NO_CONDITION;
+				  int token = NAME;
 				  char type = 0;
 				  auto elem = symbol_field(PROGRAM, 0, yytext);
 
@@ -1746,20 +1751,22 @@ USE({SPC}FOR)?		{ return USE; }
 				      type = date_time_fmt(f->data.initial);
 				      yylval.string = xstrdup(f->data.initial);
 				    }
+				  } else {
+				    yylval.string = xstrdup(yytext);
 				  }
 				  switch(type) {
 				  case 'D': token = DATETIME_FMT; break;
 				  case 'd': token = DATE_FMT; break;
 				  case 't': token = TIME_FMT; break;
 				  default:
-				    yyerror("format must be literal"); 
+				    dbgmsg("format must be literal"); 
 				    pop_return token;
 				    break;
 				  }
 				  pop_return token;
 				}
 
-  . 				{ yyless(0); pop_return NO_CONDITION; }
+  . 				{ yyless(0); yy_pop_state(); }
 }
 
 <function>{
diff --git a/gcc/cobol/scan_ante.h b/gcc/cobol/scan_ante.h
index fa00f4c70c88..b007ac0e4015 100644
--- a/gcc/cobol/scan_ante.h
+++ b/gcc/cobol/scan_ante.h
@@ -380,6 +380,19 @@ update_location() {
   }
 }
 
+static void
+update_location_col( const char str[], int correction = 0) {
+  auto col = yylloc.last_column - strlen(str) + correction;
+  if( col > 0 ) {
+    yylloc.first_column = col;
+  }
+  if( getenv("update_location") ) {
+    location_dump(__func__, __LINE__, "yylloc", yylloc);
+  }
+}
+    
+  
+
 /*
  * YY_DECL is the generated lexer.  The parser calls yylex().  yylex() invokes
  * next_token(), which calls this lexer function.  The Flex-generated code
diff --git a/gcc/cobol/util.cc b/gcc/cobol/util.cc
index 71919bf31551..d6f7ca27651c 100644
--- a/gcc/cobol/util.cc
+++ b/gcc/cobol/util.cc
@@ -1967,20 +1967,23 @@ class unique_stack : public std::stack<input_file_t>
       return true;
     }
     size_t n = c.size();
-    if( n > 1 || yydebug ) {
+    if( n > 1 ) {
+      int yydebug = 1;
+      std::swap(::yydebug, yydebug); // enable debug message for the nonce
       char *wd = get_current_dir_name();
       if( wd ) {
-	yywarn( "depth line copybook filename\n"
-	       "                 "
-	       "----- ---- --------"
-	       "----------------------------------------");
+	dbgmsg( "depth line copybook filename\n"
+		"                 "
+		"----- ---- --------"
+		"----------------------------------------");
 	for( const auto& v : c ) {
-	  yywarn( " %4zu %4d %s", c.size() - --n, v.lineno, no_wd(wd, v.name) );
+	  dbgmsg( " %4zu %4d %s", c.size() - --n, v.lineno, no_wd(wd, v.name) );
 	}
       } else {
-	yywarn("unable to get current working directory: %m");
+	dbgmsg("unable to get current working directory: %m");
       }
       free(wd);
+      std::swap(::yydebug, yydebug);
     }
     return false;
   }
@@ -2101,7 +2104,7 @@ location_dump( const char func[], int line, const char tag[], const YYLTYPE& loc
 
 static void
 verify_format( const char gmsgid[] ) {
-  static const char pattern[] = "%[[:digit:].]+[^s]";
+  static const char pattern[] = "%[[:digit:]][[:digit:].]*[^s]";
   static regex_t re;
   static int cflags = REG_EXTENDED;
   static int status = regcomp( &re, pattern, cflags );
@@ -2120,7 +2123,7 @@ verify_format( const char gmsgid[] ) {
   regmatch_t rm[30];
   
   if( REG_NOMATCH != regexec(&re, gmsgid, COUNT_OF(rm), rm, 0) ){
-    fprintf(stderr, "bad diagnositic format: '%s'", gmsgid);
+    fprintf(stderr, "bad diagnositic format: '%s'\n", gmsgid);
   }
 }
 #endif
@@ -2145,9 +2148,9 @@ extern int yychar;
 extern YYLTYPE yylloc;
 /*
  * temp_loc_t is a hack in lieu of "%define parse.error custom".  When
- * instantiated, if there is a lookahead token, it sets the global
- * token_location, which is passed to the diagnostic framework. The original
- * value is restored with the instantiated variable goes out of scope.
+ * instantiated, if there is a lookahead token (or one is provided), it sets
+ * the global token_location, which is passed to the diagnostic framework. The
+ * original value is restored when the instantiated variable goes out of scope.
  */
 class temp_loc_t : protected YYLTYPE {
   location_t orig;
@@ -2157,6 +2160,9 @@ class temp_loc_t : protected YYLTYPE {
     
     gcc_location_set(yylloc);
   }
+  temp_loc_t( const YYLTYPE& loc) : orig(token_location) {
+    gcc_location_set(loc);
+  }
   ~temp_loc_t() {
     if( orig != token_location ) {
       token_location = orig;
@@ -2164,6 +2170,21 @@ class temp_loc_t : protected YYLTYPE {
   }
 };
 
+void
+error_msg( const YYLTYPE& loc, const char gmsgid[], ... ) {
+  temp_loc_t looker(loc);
+  verify_format(gmsgid);
+  parse_error_inc();
+  global_dc->begin_group();
+  va_list ap;
+  va_start (ap, gmsgid);
+  rich_location richloc (line_table, token_location);
+  bool ret = global_dc->diagnostic_impl (&richloc, nullptr, option_id,
+					 gmsgid, &ap, DK_ERROR);
+  va_end (ap);
+  global_dc->end_group();
+}
+
 void
 yyerror( const char gmsgid[], ... ) {
   temp_loc_t looker;
-- 
GitLab