From 4c55d45b13e9a09b48c4dffefae04ea21e2e5822 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 23 Aug 2013 15:42:01 +0000 Subject: [PATCH] Respect -Wnewline-eof even in C++11 mode. If the user has requested this warning, we should emit it, even if it's not an extension in the current language mode. However, being an extension is more important, so prefer the pedantic warning or the pedantic-compatibility warning if those are enabled. llvm-svn: 189110 --- clang/include/clang/Basic/DiagnosticGroups.td | 1 + .../include/clang/Basic/DiagnosticLexKinds.td | 4 ++- clang/lib/Lex/Lexer.cpp | 26 ++++++++++++++++--- clang/test/Lexer/newline-eof-c++11.cpp | 5 ---- clang/test/Lexer/newline-eof-c++98-compat.cpp | 1 + clang/test/Lexer/newline-eof.c | 12 ++++++--- 6 files changed, 36 insertions(+), 13 deletions(-) delete mode 100644 clang/test/Lexer/newline-eof-c++11.cpp 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