Skip to content

Suppress pedantic diagnostic for a file not ending in EOL #131794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions clang-tools-extra/clangd/Preamble.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,10 +627,8 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
return DiagnosticsEngine::Ignored;
switch (Info.getID()) {
case diag::warn_no_newline_eof:
case diag::warn_cxx98_compat_no_newline_eof:
case diag::ext_no_newline_eof:
// If the preamble doesn't span the whole file, drop the no newline at
// eof warnings.
// eof warning.
return Bounds.Size != ContentsBuffer->getBufferSize()
? DiagnosticsEngine::Level::Ignored
: DiagLevel;
Expand Down
6 changes: 4 additions & 2 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ C2y Feature Support
that ``_Generic`` selection associations may now have ``void`` type, but it
also removes UB with code like ``(void)(void)1;``.
- Implemented `WG14 N3411 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3411.pdf>`_
which allows a source file to not end with a newline character. This is still
reported as a conforming extension in earlier language modes.
which allows a source file to not end with a newline character. Note,
``-pedantic`` will no longer diagnose this in either C or C++ modes. This
feature was adopted as applying to obsolete versions of C in WG14 and as a
defect report in WG21 (CWG787).
- Implemented `WG14 N3353 <https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3353.htm>_`
which adds the new ``0o`` and ``0O`` ocal literal prefixes and deprecates
octal literals other than ``0`` which do not start with the new prefix. This
Expand Down
6 changes: 0 additions & 6 deletions clang/include/clang/Basic/DiagnosticLexKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,9 @@ def ext_multi_line_line_comment : Extension<"multi-line // comment">,
def ext_line_comment : Extension<
"// comments are not allowed in this language">,
InGroup<Comment>;
def ext_no_newline_eof : Extension<"no newline at end of file">,
InGroup<NewlineEOF>;
def warn_no_newline_eof : Warning<"no newline at end of file">,
InGroup<NewlineEOF>, DefaultIgnore;

def warn_cxx98_compat_no_newline_eof : Warning<
"C++98 requires newline at end of file">,
InGroup<CXX98CompatPedantic>, DefaultIgnore;

def ext_dollar_in_identifier : Extension<"'$' in identifier">,
InGroup<DiagGroup<"dollar-in-identifier-extension">>;
def ext_charize_microsoft : Extension<
Expand Down
28 changes: 6 additions & 22 deletions clang/lib/Lex/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3187,28 +3187,12 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
ConditionalStack.pop_back();
}

// 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')) {
DiagnosticsEngine &Diags = PP->getDiagnostics();
SourceLocation EndLoc = getSourceLocation(BufferEnd);
unsigned DiagID = diag::warn_no_newline_eof;

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.isIgnored(diag::warn_cxx98_compat_no_newline_eof, EndLoc))
DiagID = diag::warn_cxx98_compat_no_newline_eof;
} else {
// This is conforming in C2y, but is an extension in earlier language
// modes.
if (!LangOpts.C2y)
DiagID = diag::ext_no_newline_eof;
}

Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
}
// Before C++11 and C2y, a file not ending with a newline was UB. Both
// standards changed this behavior (as a DR or equivalent), but we still have
// an opt-in diagnostic to warn about it.
if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r'))
Diag(BufferEnd, diag::warn_no_newline_eof)
<< FixItHint::CreateInsertion(getSourceLocation(BufferEnd), "\n");

BufferPtr = CurPtr;

Expand Down
3 changes: 2 additions & 1 deletion clang/test/C/C2y/n3411.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
// RUN: %clang_cc1 -verify=good -std=c2y -Wall -pedantic %s
// RUN: %clang_cc1 -verify -Wnewline-eof -std=c2y -Wall -pedantic %s
// RUN: %clang_cc1 -verify -std=c23 -Wall -pedantic %s
// RUN: %clang_cc1 -verify=good -std=c23 -Wall -pedantic %s
// RUN: %clang_cc1 -verify=good -std=c23 %s
// RUN: %clang_cc1 -verify -Wnewline-eof -std=c23 %s

/* WG14 N3411: Yes
* Slay Some Earthly Demons XII
Expand Down
13 changes: 13 additions & 0 deletions clang/test/CXX/drs/cwg787.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++14 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++17 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++20 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++23 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++2c %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// expected-no-diagnostics

// This file intentionally does not end with a newline. CWG787 made this
// well-defined behavior.

// cwg787: 21
5 changes: 0 additions & 5 deletions clang/test/Lexer/newline-eof-c++98-compat.cpp

This file was deleted.

15 changes: 10 additions & 5 deletions clang/test/Lexer/newline-eof.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
// RUN: %clang_cc1 -fsyntax-only -Wnewline-eof -verify %s
// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++03 -pedantic -verify %s
// RUN: %clang_cc1 -fsyntax-only -Wnewline-eof %s 2>&1 | FileCheck %s
// Allowing a file to end without a newline was adopted as a Defect Report in
// WG21 (CWG787) and in WG14 (added to the list of changes which apply to
// earlier revisions of C in C2y). So it should not issue a pedantic diagnostic
// in any language mode.

// In C++11 mode, this is allowed, so don't warn in pedantic mode.
// RUN: %clang_cc1 -fsyntax-only -Wnewline-eof -verify %s
// RUN: %clang_cc1 -fsyntax-only -pedantic -verify=good %s
// RUN: %clang_cc1 -fsyntax-only -std=c89 -pedantic -Wno-comment -verify=good %s
// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++03 -pedantic -verify=good %s
// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -Wnewline-eof -verify %s
// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++11 -Werror -pedantic %s
// RUN: %clang_cc1 -fsyntax-only -Wnewline-eof %s 2>&1 | FileCheck %s
// good-no-diagnostics

// Make sure the diagnostic shows up properly at the end of the last line.
// CHECK: newline-eof.c:[[@LINE+3]]:67
Expand Down
Loading