diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -450,6 +450,7 @@ 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]>; @@ -1111,7 +1112,7 @@ 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 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -427,6 +427,10 @@ 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; + 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 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -1431,6 +1431,7 @@ // 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 @@ // 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.c b/clang/test/Preprocessor/line-directive-system-headers.c copy from clang/test/Preprocessor/line-directive.c copy to clang/test/Preprocessor/line-directive-system-headers.c --- a/clang/test/Preprocessor/line-directive.c +++ b/clang/test/Preprocessor/line-directive-system-headers.c @@ -1,16 +1,11 @@ -// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify -pedantic %s -// RUN: not %clang_cc1 -E %s 2>&1 | grep 'blonk.c:92:2: error: ABC' -// RUN: not %clang_cc1 -E %s 2>&1 | grep 'blonk.c:93:2: error: DEF' -// RUN: not %clang_cc1 -E %s 2>&1 | grep 'line-directive.c:11:2: error: MAIN7' -// RUN: not %clang_cc1 -E %s 2>&1 | grep 'enter-1:118:2: error: ENTER1' -// RUN: not %clang_cc1 -E %s 2>&1 | grep 'main:121:2: error: MAIN2' +// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify -pedantic -Wsystem-headers %s // expected-error@+1{{cannot pop empty include stack}} # 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}} @@ -27,13 +22,13 @@ #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}} -# 42 "foo" 1 3 // enter -# 42 "foo" 2 3 // exit +# 42 "foo" 1 3 // enter: expected-warning {{this style of line directive is a GNU extension}} +# 42 "foo" 2 3 // exit: expected-warning {{this style of line directive is a GNU extension}} # 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,32 +49,32 @@ // 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}} -# 192 "glomp.h" 3 // System header. -typedef int y; // ok -typedef int y; // ok +# 192 "glomp.h" 3 // System header.: expected-warning {{this style of line directive is a GNU extension}} +typedef int y; // expected-note {{previous definition is here}} +typedef int y; // expected-warning {{redefinition of typedef 'y' is a C11 feature}} -typedef int q; // q is in system header. +typedef int q; // q is in system header.: expected-note {{previous definition is here}} #line 42 "blonk.h" // doesn't change system headerness. -typedef int z; // ok -typedef int z; // ok +typedef int z; // expected-note {{previous definition is here}} +typedef int z; // expected-warning {{redefinition of typedef 'z' is a C11 feature}} -# 97 // doesn't change system headerness. +# 97 // doesn't change system headerness.: expected-warning {{this style of line directive is a GNU extension}} -typedef int z1; // ok -typedef int z1; // ok +typedef int z1; // expected-note {{previous definition is here}} +typedef int z1; // expected-warning {{redefinition of typedef 'z1' is a C11 feature}} -# 42 "blonk.h" // DOES change system headerness. +# 42 "blonk.h" // DOES change system headerness.: expected-warning {{this style of line directive is a GNU extension}} typedef int w; // expected-note {{previous definition is here}} typedef int w; // expected-warning {{redefinition of typedef 'w' is a C11 feature}} -typedef int q; // original definition in system header, should not diagnose. +typedef int q; // expected-warning {{redefinition of typedef 'q' is a C11 feature}} // This should not produce an "extra tokens at end of #line directive" warning, // because #line is allowed to contain expanded tokens. @@ -97,30 +92,30 @@ #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 41 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 _ */ // rdar://11550996 #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}} diff --git a/clang/test/Preprocessor/line-directive.c b/clang/test/Preprocessor/line-directive.c --- 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@-1{{MAIN7}} @@ -27,13 +27,13 @@ #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}} # 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 +54,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 +97,7 @@ #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 +106,7 @@ _\ _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 +115,12 @@ #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}} diff --git a/clang/test/SemaCXX/constexpr-string.cpp b/clang/test/SemaCXX/constexpr-string.cpp --- 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 @@ } # 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;