[gcc r17-2908] cobol: Ignore comments in strings.

"James K. Lowden via Gcc-cvs" <[email protected]> Mon, 3 Aug 2026 21:08:03 +0000 (GMT)
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:366ebd458e5baec989e171360be4692153a59da6

commit r17-2908-g366ebd458e5baec989e171360be4692153a59da6
Author: James K. Lowden <[email protected]>
Date:   Mon Aug 3 16:48:30 2026 -0400

    cobol: Ignore comments in strings.
    
    Change the file reader to recognize string constants, and not treat
    the sequence "*>" as an inline comment if it appears in a
    string. Credit to George Neill for the patch.
    
    gcc/cobol/ChangeLog:
    
            * lexio.cc (skip_quoted_literal): New function.
            (remove_inline_comment): Use new function.

Diff:
---
 gcc/cobol/lexio.cc | 38 ++++++++++++++++++++++++++++++++------
 1 file changed, 32 insertions(+), 6 deletions(-)

diff --git a/gcc/cobol/lexio.cc b/gcc/cobol/lexio.cc
index 54b8aa814bc8..d4cb4a258f3c 100644
--- a/gcc/cobol/lexio.cc
+++ b/gcc/cobol/lexio.cc
@@ -88,18 +88,44 @@ source_format_t::indicated( char *bol, const char *eol, char ch ) {
   return ch == '\0' || ch == *bol? bol : NULL;
 }
 
+/* Advance past a quoted literal */
+static char *
+skip_quoted_literal( char *p, char *pend ) {
+  const char delimiter = *p++;
+  while( p < pend ) {
+    p = std::find(p, pend, delimiter);
+    if( p == pend )
+      return pend;
+    if( p + 1 < pend && p[1] == delimiter ) {
+      p += 2; // nested quote
+      continue;
+    }
+    return ++p;
+  }
+  return pend;
+}
+
 static char *
 remove_inline_comment( char *bol, char *eol ) {
   char *nl = std::find(bol, eol, '\n');
 
   if( bol < nl ) {
-    static char ends = '\0';
-    std::swap(*nl, ends);
-    char *comment = strstr(bol, "*>");
-    if( comment ) {
-      std::fill(comment, nl, SPACE);
+    /* skip *> in alphanumeric literals */
+    static const char markers[] = { '\'', '"', '*' };
+    for( char *p = bol; p < nl; ) {
+      p = std::find_first_of(p, nl, markers, markers + sizeof(markers));
+      if( p == nl )
+        break;
+      if( isquote(*p) ) {
+        p = skip_quoted_literal(p, nl);
+        continue;
+      }
+      if( p + 1 < nl && p[1] == '>' ) {
+        std::fill(p, nl, SPACE);
+        break;
+      }
+      p++;
     }
-    std::swap(*nl, ends);
   }
   return eol;
 }