[clang] 786c721 - Add extension diagnostic for linemarker directives

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Wed May 11 03:42:16 PDT 2022


Author: Ken Matsui
Date: 2022-05-11T06:42:00-04:00
New Revision: 786c721c2bbd2e0646e314671e010859550423bf

URL: https://github.com/llvm/llvm-project/commit/786c721c2bbd2e0646e314671e010859550423bf
DIFF: https://github.com/llvm/llvm-project/commit/786c721c2bbd2e0646e314671e010859550423bf.diff

LOG: Add extension diagnostic for linemarker directives

This adds the -Wgnu-line-marker diagnostic flag, grouped under -Wgnu,
to warn about use of the GNU linemarker preprocessor extension.

Fixes #55067

Differential Revision: https://reviews.llvm.org/D124534

Added: 
    clang/test/Preprocessor/line-directive-system-headers.c

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/DiagnosticGroups.td
    clang/include/clang/Basic/DiagnosticLexKinds.td
    clang/lib/Lex/PPDirectives.cpp
    clang/test/Preprocessor/line-directive.c
    clang/test/SemaCXX/constexpr-string.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 9841ae5c52973..5a3b2066d68fc 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -214,6 +214,9 @@ Improvements to Clang's diagnostics
   the ``-Wunreachable-code`` flag) which is enabled by default and warns the
   user about ``_Generic`` selection associations which are unreachable because
   the type specified is an array type or a qualified type.
+- Added the ``-Wgnu-line-marker`` diagnostic flag (grouped under the ``-Wgnu``
+  flag) which is a portability warning about use of GNU linemarker preprocessor
+  directives. Fixes `Issue 55067 <https://github.com/llvm/llvm-project/issues/55067>`_.
 
 Non-comprehensive list of changes in this release
 -------------------------------------------------

diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 1159f49e76f71..a7c34038ba3f7 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -450,6 +450,7 @@ def : DiagGroup<"init-self">;
 def : DiagGroup<"inline">;
 def : DiagGroup<"invalid-pch">;
 def GNULabelsAsValue : DiagGroup<"gnu-label-as-value">;
+def GNULineMarker : DiagGroup<"gnu-line-marker">;
 def LiteralRange : DiagGroup<"literal-range">;
 def LocalTypeTemplateArgs : DiagGroup<"local-type-template-args",
                                       [CXX98CompatLocalTypeTemplateArgs]>;
@@ -1113,7 +1114,7 @@ def GNU : DiagGroup<"gnu", [GNUAlignofExpression, GNUAnonymousStruct,
                             VLAExtension, GNUFlexibleArrayInitializer,
                             GNUFlexibleArrayUnionMember, GNUFoldingConstant,
                             GNUImaginaryConstant, GNUIncludeNext,
-                            GNULabelsAsValue, GNUNullPointerArithmetic,
+                            GNULabelsAsValue, GNULineMarker, GNUNullPointerArithmetic,
                             GNUPointerArith, RedeclaredClassMember,
                             GNURedeclaredEnum, GNUStatementExpression,
                             GNUStaticFloatInit,

diff  --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index 543ce8a3649d1..01866d9d0eb7b 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -427,6 +427,10 @@ def note_macro_expansion_here : Note<"expansion of macro %0 requested here">;
 def ext_pp_opencl_variadic_macros : Extension<
   "variadic macros are a Clang extension in OpenCL">;
 
+def ext_pp_gnu_line_directive : Extension<
+  "this style of line directive is a GNU extension">,
+  InGroup<GNULineMarker>;
+
 def err_pp_invalid_directive : Error<"invalid preprocessing directive">;
 def err_pp_directive_required : Error<
   "%0 must be used within a preprocessing directive">;

diff  --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
index 2d942aacbf1db..1ef1ba16bcd31 100644
--- a/clang/lib/Lex/PPDirectives.cpp
+++ b/clang/lib/Lex/PPDirectives.cpp
@@ -1431,6 +1431,7 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
   // If the StrTok is "eod", then it wasn't present.  Otherwise, it must be a
   // string followed by eod.
   if (StrTok.is(tok::eod)) {
+    Diag(StrTok, diag::ext_pp_gnu_line_directive);
     // Treat this like "#line NN", which doesn't change file characteristics.
     FileKind = SourceMgr.getFileCharacteristic(DigitTok.getLocation());
   } else if (StrTok.isNot(tok::string_literal)) {
@@ -1458,6 +1459,9 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) {
     // If a filename was present, read any flags that are present.
     if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, FileKind, *this))
       return;
+    if (!SourceMgr.isWrittenInBuiltinFile(DigitTok.getLocation()) &&
+        !SourceMgr.isWrittenInCommandLineFile(DigitTok.getLocation()))
+      Diag(StrTok, diag::ext_pp_gnu_line_directive);
 
     // Exiting to an empty string means pop to the including file, so leave
     // FilenameID as -1 in that case.

diff  --git a/clang/test/Preprocessor/line-directive-system-headers.c b/clang/test/Preprocessor/line-directive-system-headers.c
new file mode 100644
index 0000000000000..cd9e89932c24b
--- /dev/null
+++ b/clang/test/Preprocessor/line-directive-system-headers.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify=system -Wsystem-headers %s
+
+int x;
+
+# 42 // #1
+// expected-warning@#1 {{this style of line directive is a GNU extension}}
+// system-warning@#1 {{this style of line directive is a GNU extension}}
+# 42 "foo" // #2
+// expected-warning@#2 {{this style of line directive is a GNU extension}}
+// system-warning@#2 {{this style of line directive is a GNU extension}}
+# 42 "foo" 2 // #3
+// expected-error@#3 {{invalid line marker flag '2': cannot pop empty include stack}}
+// system-error@#3 {{invalid line marker flag '2': cannot pop empty include stack}}
+# 42 "foo" 1 3  // #4: enter
+// Warnings silenced when -Wsystem-headers isn't passed.
+// system-warning@#4 {{this style of line directive is a GNU extension}}
+# 42 "foo" 2 3  // #5: exit
+// Warnings silenced when -Wsystem-headers isn't passed.
+// system-warning@#5 {{this style of line directive is a GNU extension}}
+# 42 "foo" 2 3 4 // #6
+// expected-error@#6 {{invalid line marker flag '2': cannot pop empty include stack}}
+// system-error@#6 {{invalid line marker flag '2': cannot pop empty include stack}}
+# 42 "foo" 3 4 // #7
+// expected-warning@#7 {{this style of line directive is a GNU extension}}
+// system-warning@#7 {{this style of line directive is a GNU extension}}
+
+
+// Verify that linemarker diddling of the system header flag works.
+
+# 192 "glomp.h" // #8: not a system header.
+// expected-warning@#8 {{this style of line directive is a GNU extension}}
+// system-warning@#8 {{this style of line directive is a GNU extension}}
+
+# 192 "glomp.h" 3 // #9: System header.
+// Warnings silenced when -Wsystem-headers isn't passed.
+// system-warning@#9 {{this style of line directive is a GNU extension}}
+
+#line 42 "blonk.h"  // doesn't change system headerness.
+
+# 97     // #10: doesn't change system headerness.
+// Warnings silenced when -Wsystem-headers isn't passed.
+// system-warning@#10 {{this style of line directive is a GNU extension}}
+
+# 42 "blonk.h"  // #11: DOES change system headerness.
+// Warnings silenced when -Wsystem-headers isn't passed.
+// system-warning@#11 {{this style of line directive is a GNU extension}}

diff  --git a/clang/test/Preprocessor/line-directive.c b/clang/test/Preprocessor/line-directive.c
index d0f615005e9e9..29ea709780f4b 100644
--- a/clang/test/Preprocessor/line-directive.c
+++ b/clang/test/Preprocessor/line-directive.c
@@ -9,8 +9,8 @@
 # 20 "" 2
 
 // a push/pop before any other line control
-# 10 "enter-0" 1
-# 11 "" 2 // pop to main file
+# 10 "enter-0" 1 // expected-warning {{this style of line directive is a GNU extension}}
+# 11 "" 2 // pop to main file: expected-warning {{this style of line directive is a GNU extension}}
 #error MAIN7
 // expected-error at -1{{MAIN7}}
 
@@ -27,13 +27,15 @@
 #define A 42 "foo"
 #line A
 
-# 42
-# 42 "foo"
+# 42 // expected-warning {{this style of line directive is a GNU extension}}
+# 42 "foo" // expected-warning {{this style of line directive is a GNU extension}}
 # 42 "foo" 2 // expected-error {{invalid line marker flag '2': cannot pop empty include stack}}
+// The next two lines do not get diagnosed because they are considered to be
+// within the system header, where diagnostics are suppressed.
 # 42 "foo" 1 3  // enter
 # 42 "foo" 2 3  // exit
 # 42 "foo" 2 3 4 // expected-error {{invalid line marker flag '2': cannot pop empty include stack}}
-# 42 "foo" 3 4
+# 42 "foo" 3 4 // expected-warning {{this style of line directive is a GNU extension}}
 
 # 'a'            // expected-error {{invalid preprocessing directive}}
 # 42 'f'         // expected-error {{invalid filename for line marker directive}}
@@ -54,7 +56,7 @@
 
 // Verify that linemarker diddling of the system header flag works.
 
-# 192 "glomp.h" // not a system header.
+# 192 "glomp.h" // not a system header.: expected-warning {{this style of line directive is a GNU extension}}
 typedef int x;  // expected-note {{previous definition is here}}
 typedef int x;  // expected-warning {{redefinition of typedef 'x' is a C11 feature}}
 
@@ -97,7 +99,7 @@ typedef int q;  // original definition in system header, should not diagnose.
 #line 010  // expected-warning {{#line directive interprets number as decimal, not octal}}
 extern int array[__LINE__ == 10 ? 1:-1];
 
-# 020      // expected-warning {{GNU line marker directive interprets number as decimal, not octal}}
+# 020      // expected-warning {{GNU line marker directive interprets number as decimal, not octal}} expected-warning {{this style of line directive is a GNU extension}}
 extern int array_gnuline[__LINE__ == 20 ? 1:-1];
 
 /* PR3917 */
@@ -106,7 +108,7 @@ extern char array2[\
 _\
 _LINE__ == 42 ? 1: -1];  /* line marker is location of first _ */
 
-# 51
+# 51 // expected-warning {{this style of line directive is a GNU extension}}
 extern char array2_gnuline[\
 _\
 _LINE__ == 52 ? 1: -1];  /* line marker is location of first _ */
@@ -115,12 +117,12 @@ _LINE__ == 52 ? 1: -1];  /* line marker is location of first _ */
 #line 0 "line-directive.c" // expected-warning {{#line directive with zero argument is a GNU extension}}
 undefined t; // expected-error {{unknown type name 'undefined'}}
 
-# 115 "main"
-# 116 "enter-1" 1
-# 117 "enter-2" 1
-# 118 "" 2 // pop to enter-1
+# 115 "main" // expected-warning {{this style of line directive is a GNU extension}}
+# 116 "enter-1" 1 // expected-warning {{this style of line directive is a GNU extension}}
+# 117 "enter-2" 1 // expected-warning {{this style of line directive is a GNU extension}}
+# 118 "" 2 // pop to enter-1: expected-warning {{this style of line directive is a GNU extension}}
 #error ENTER1
 // expected-error at -1{{ENTER1}}
-# 121 "" 2 // pop to "main"
+# 121 "" 2 // pop to "main": expected-warning {{this style of line directive is a GNU extension}}
 #error MAIN2
 // expected-error at -1{{MAIN2}}

diff  --git a/clang/test/SemaCXX/constexpr-string.cpp b/clang/test/SemaCXX/constexpr-string.cpp
index 401f64945ef5c..cfee3566bbff7 100644
--- a/clang/test/SemaCXX/constexpr-string.cpp
+++ b/clang/test/SemaCXX/constexpr-string.cpp
@@ -7,7 +7,7 @@
 // RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-signed-char
 // RUN: %clang_cc1 %s -triple armebv7-unknown-linux -std=c++2a -fsyntax-only -verify -pedantic -Wno-vla-extension -fno-wchar -DNO_PREDEFINED_WCHAR_T
 
-# 9 "/usr/include/string.h" 1 3 4
+# 9 "/usr/include/string.h" 1 3 4  // expected-warning {{this style of line directive is a GNU extension}}
 extern "C" {
   typedef decltype(sizeof(int)) size_t;
 
@@ -29,7 +29,7 @@ extern "C" {
 }
 # 25 "SemaCXX/constexpr-string.cpp" 2
 
-# 27 "/usr/include/wchar.h" 1 3 4
+# 27 "/usr/include/wchar.h" 1 3 4  // expected-warning {{this style of line directive is a GNU extension}}
 extern "C" {
 #if NO_PREDEFINED_WCHAR_T
   typedef decltype(L'0') wchar_t;


        


More information about the cfe-commits mailing list