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 @@ -1335,7 +1335,10 @@ unsigned FlagVal; Token FlagTok; PP.Lex(FlagTok); - if (FlagTok.is(tok::eod)) return false; + if (FlagTok.is(tok::eod)) { + PP.Diag(FlagTok, diag::ext_pp_gnu_line_directive); + return false; + } if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP)) return true; @@ -1431,6 +1434,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)) { 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 @@ -27,8 +27,8 @@ #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 @@ -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,7 +115,7 @@ #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" +# 115 "main" // expected-warning {{this style of line directive is a GNU extension}} # 116 "enter-1" 1 # 117 "enter-2" 1 # 118 "" 2 // pop to enter-1