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
-------------------------------------------------
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]>;
VLAExtension, GNUFlexibleArrayInitializer,
GNUFlexibleArrayUnionMember, GNUFoldingConstant,
GNUImaginaryConstant, GNUIncludeNext,
- GNULabelsAsValue, GNUNullPointerArithmetic,
+ GNULabelsAsValue, GNULineMarker, GNUNullPointerArithmetic,
GNUPointerArith, RedeclaredClassMember,
GNURedeclaredEnum, GNUStatementExpression,
GNUStaticFloatInit,
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">;
// 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)) {
// 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.
--- /dev/null
+// 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}}
# 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@-1{{MAIN7}}
#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}}
// 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}}
#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 */
_\
_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 _ */
#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@-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@-1{{MAIN2}}
// 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;
}
# 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;