diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td index e46182badcf4..dbbf7f65a87a 100644 --- a/clang/include/clang/Basic/DiagnosticGroups.td +++ b/clang/include/clang/Basic/DiagnosticGroups.td @@ -190,6 +190,7 @@ def MismatchedReturnTypes : DiagGroup<"mismatched-return-types">; def MismatchedTags : DiagGroup<"mismatched-tags">; def MissingFieldInitializers : DiagGroup<"missing-field-initializers">; def ModuleConflict : DiagGroup<"module-conflict">; +def NewlineEOF : DiagGroup<"newline-eof">; def NullArithmetic : DiagGroup<"null-arithmetic">; def NullCharacter : DiagGroup<"null-character">; def NullDereference : DiagGroup<"null-dereference">; diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td index 90a3d71c777a..ed798ab960e4 100644 --- a/clang/include/clang/Basic/DiagnosticLexKinds.td +++ b/clang/include/clang/Basic/DiagnosticLexKinds.td @@ -47,7 +47,9 @@ def ext_line_comment : Extension< "// comments are not allowed in this language">, InGroup; def ext_no_newline_eof : Extension<"no newline at end of file">, - InGroup>; + InGroup; +def warn_no_newline_eof : Warning<"no newline at end of file">, + InGroup, DefaultIgnore; def warn_cxx98_compat_no_newline_eof : Warning< "C++98 requires newline at end of file">, diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index c28781dc5f2b..e3e01da8416f 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -2410,10 +2410,28 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) { // C99 5.1.1.2p2: If the file is non-empty and didn't end in a newline, issue // a pedwarn. - if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) - Diag(BufferEnd, LangOpts.CPlusPlus11 ? // C++11 [lex.phases] 2.2 p2 - diag::warn_cxx98_compat_no_newline_eof : diag::ext_no_newline_eof) - << FixItHint::CreateInsertion(getSourceLocation(BufferEnd), "\n"); + if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) { + DiagnosticsEngine &Diags = PP->getDiagnostics(); + SourceLocation EndLoc = getSourceLocation(BufferEnd); + unsigned DiagID; + + if (LangOpts.CPlusPlus11) { + // C++11 [lex.phases] 2.2 p2 + // Prefer the C++98 pedantic compatibility warning over the generic, + // non-extension, user-requested "missing newline at EOF" warning. + if (Diags.getDiagnosticLevel(diag::warn_cxx98_compat_no_newline_eof, + EndLoc) != DiagnosticsEngine::Ignored) { + DiagID = diag::warn_cxx98_compat_no_newline_eof; + } else { + DiagID = diag::warn_no_newline_eof; + } + } else { + DiagID = diag::ext_no_newline_eof; + } + + Diag(BufferEnd, DiagID) + << FixItHint::CreateInsertion(EndLoc, "\n"); + } BufferPtr = CurPtr; diff --git a/clang/test/Lexer/newline-eof-c++11.cpp b/clang/test/Lexer/newline-eof-c++11.cpp deleted file mode 100644 index eeabe8bb9fc3..000000000000 --- a/clang/test/Lexer/newline-eof-c++11.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -std=c++11 -Wnewline-eof -verify %s -// expected-no-diagnostics - -// The following line isn't terminated, don't fix it. -void foo() {} \ No newline at end of file diff --git a/clang/test/Lexer/newline-eof-c++98-compat.cpp b/clang/test/Lexer/newline-eof-c++98-compat.cpp index 3e5c8e226235..9af0b889537b 100644 --- a/clang/test/Lexer/newline-eof-c++98-compat.cpp +++ b/clang/test/Lexer/newline-eof-c++98-compat.cpp @@ -1,4 +1,5 @@ // RUN: %clang_cc1 -fsyntax-only -Wc++98-compat-pedantic -std=c++11 -verify %s +// RUN: %clang_cc1 -fsyntax-only -Wc++98-compat-pedantic -Wnewline-eof -std=c++11 -verify %s // The following line isn't terminated, don't fix it. void foo() {} // expected-warning{{C++98 requires newline at end of file}} \ No newline at end of file diff --git a/clang/test/Lexer/newline-eof.c b/clang/test/Lexer/newline-eof.c index a4a18835cf5f..d762519aaae5 100644 --- a/clang/test/Lexer/newline-eof.c +++ b/clang/test/Lexer/newline-eof.c @@ -1,9 +1,15 @@ -// RUN: %clang_cc1 -fsyntax-only -Wnewline-eof -verify %s -// RUN: %clang_cc1 -fsyntax-only -Wnewline-eof %s 2>&1 | FileCheck %s +// RUN: %clang -fsyntax-only -Wnewline-eof -verify %s +// RUN: %clang -fsyntax-only -pedantic -verify %s +// RUN: %clang -fsyntax-only -x c++ -std=c++03 -pedantic -verify %s +// RUN: %clang -fsyntax-only -Wnewline-eof %s 2>&1 | FileCheck %s // rdar://9133072 +// In C++11 mode, this is allowed, so don't warn in pedantic mode. +// RUN: %clang -fsyntax-only -x c++ -std=c++11 -Wnewline-eof -verify %s +// RUN: %clang -fsyntax-only -x c++ -std=c++11 -pedantic %s + // Make sure the diagnostic shows up properly at the end of the last line. -// CHECK: newline-eof.c:9:63 +// CHECK: newline-eof.c:[[@LINE+3]]:63 // The following line isn't terminated, don't fix it. void foo() {} // expected-warning{{no newline at end of file}} \ No newline at end of file