[clang] [clang-tools-extra] Suppress pedantic diagnostic for a file not ending in EOL (PR #131794)
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 18 09:11:41 PDT 2025
https://github.com/AaronBallman updated https://github.com/llvm/llvm-project/pull/131794
>From 22c4b9d7808df33d3e6a31b3456cd8b2e8a95bfa Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 18 Mar 2025 08:34:18 -0400
Subject: [PATCH 1/7] Suppress pedantic diagnostic for a file not ending in EOL
WG14 added N3411 to the list of papers which apply to older versions of
C, and WG21 adopted CWG787 as a Defect Report in C++11. So we no longer
should be issuing a pedantic diagnostic about a file which does not end
with a newline character.
We do, however, continue to support -Wnewline-eof as an opt-in
diagnostic.
---
clang-tools-extra/clangd/Preamble.cpp | 1 -
clang/docs/ReleaseNotes.rst | 5 ++++-
.../include/clang/Basic/DiagnosticLexKinds.td | 2 --
clang/lib/Lex/Lexer.cpp | 18 ++++++------------
clang/test/C/C2y/n3411.c | 3 ++-
clang/test/Lexer/newline-eof.c | 15 ++++++++++-----
6 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index b634981bb46bd..233d827e6ed7b 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -628,7 +628,6 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
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.
return Bounds.Size != ContentsBuffer->getBufferSize()
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 0adbc19f40096..71d7f9f85e739 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -128,7 +128,10 @@ C2y Feature Support
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.
+ reported as a conforming extension in earlier language modes. Note,
+ ``-pedantic`` will no longer diagnose this in either C or C++ modes as an
+ extension. 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
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index bdb7e9350b5f7..cf226856864c0 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -52,8 +52,6 @@ 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;
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index 96d5d4f440768..fcc53f91b5728 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3194,18 +3194,12 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
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;
- }
+ // 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 (LangOpts.CPlusPlus11 &&
+ !Diags.isIgnored(diag::warn_cxx98_compat_no_newline_eof, EndLoc))
+ DiagID = diag::warn_cxx98_compat_no_newline_eof;
Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
}
diff --git a/clang/test/C/C2y/n3411.c b/clang/test/C/C2y/n3411.c
index 934a7c70fa67e..0fea769e30460 100644
--- a/clang/test/C/C2y/n3411.c
+++ b/clang/test/C/C2y/n3411.c
@@ -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
diff --git a/clang/test/Lexer/newline-eof.c b/clang/test/Lexer/newline-eof.c
index 9f5033384e16f..22245ac357efc 100644
--- a/clang/test/Lexer/newline-eof.c
+++ b/clang/test/Lexer/newline-eof.c
@@ -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
>From c7568b7ccf3932f9420d123954e2db9a97908c05 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 18 Mar 2025 09:16:43 -0400
Subject: [PATCH 2/7] Add C++ DR test
Note: I wasn't able to run the python script to regenerate the
cxx_dr_status.html page due to encoding errors, so that still needs to
be run.
---
clang/test/CXX/drs/cwg787.cpp | 13 +++++++++++++
1 file changed, 13 insertions(+)
create mode 100644 clang/test/CXX/drs/cwg787.cpp
diff --git a/clang/test/CXX/drs/cwg787.cpp b/clang/test/CXX/drs/cwg787.cpp
new file mode 100644
index 0000000000000..15f6bdebba9ac
--- /dev/null
+++ b/clang/test/CXX/drs/cwg787.cpp
@@ -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: 3.0
\ No newline at end of file
>From e7ce604b002577d24e4148e70b6d4b59b1d05d16 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 18 Mar 2025 09:18:31 -0400
Subject: [PATCH 3/7] Update release notes
---
clang/docs/ReleaseNotes.rst | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 71d7f9f85e739..01485fcb51ec3 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -127,8 +127,7 @@ 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. Note,
+ 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 as an
extension. This feature was adopted as applying to obsolete versions of C in
WG14 and as a defect report in WG21 (CWG787).
>From 754cfabbc55a825af68d464ad3c221223e8d5706 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 18 Mar 2025 09:29:13 -0400
Subject: [PATCH 4/7] Remove the C++98 compat diagnostic
Review comments pointed out that this is no longer a necessary
diagnostic given that C++11 adopted the change as a defect report.
---
.../include/clang/Basic/DiagnosticLexKinds.td | 4 ----
clang/lib/Lex/Lexer.cpp | 22 +++++--------------
clang/test/Lexer/newline-eof-c++98-compat.cpp | 5 -----
3 files changed, 6 insertions(+), 25 deletions(-)
delete mode 100644 clang/test/Lexer/newline-eof-c++98-compat.cpp
diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.td b/clang/include/clang/Basic/DiagnosticLexKinds.td
index cf226856864c0..912b8bd46e194 100644
--- a/clang/include/clang/Basic/DiagnosticLexKinds.td
+++ b/clang/include/clang/Basic/DiagnosticLexKinds.td
@@ -55,10 +55,6 @@ def ext_line_comment : Extension<
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<
diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
index fcc53f91b5728..3128627490e28 100644
--- a/clang/lib/Lex/Lexer.cpp
+++ b/clang/lib/Lex/Lexer.cpp
@@ -3187,22 +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;
-
- // 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 (LangOpts.CPlusPlus11 &&
- !Diags.isIgnored(diag::warn_cxx98_compat_no_newline_eof, EndLoc))
- DiagID = diag::warn_cxx98_compat_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;
diff --git a/clang/test/Lexer/newline-eof-c++98-compat.cpp b/clang/test/Lexer/newline-eof-c++98-compat.cpp
deleted file mode 100644
index 9af0b889537b8..0000000000000
--- a/clang/test/Lexer/newline-eof-c++98-compat.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-// 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
>From fcee1963ff9dbcf62f110efd593acb8a9f23582a Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 18 Mar 2025 10:28:56 -0400
Subject: [PATCH 5/7] Fix build error
---
clang-tools-extra/clangd/Preamble.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index 233d827e6ed7b..de756cdb70c09 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -627,7 +627,6 @@ 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:
// If the preamble doesn't span the whole file, drop the no newline at
// eof warnings.
return Bounds.Size != ContentsBuffer->getBufferSize()
>From c8337b3c5e6db9eadc840cd7dfc6e5b6b1f0b447 Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 18 Mar 2025 11:30:52 -0400
Subject: [PATCH 6/7] Update DR test based on review feedback
---
clang/test/CXX/drs/cwg787.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/test/CXX/drs/cwg787.cpp b/clang/test/CXX/drs/cwg787.cpp
index 15f6bdebba9ac..4b5aeb6487a00 100644
--- a/clang/test/CXX/drs/cwg787.cpp
+++ b/clang/test/CXX/drs/cwg787.cpp
@@ -10,4 +10,4 @@
// This file intentionally does not end with a newline. CWG787 made this
// well-defined behavior.
-// cwg787: 3.0
\ No newline at end of file
+// cwg787: 21
\ No newline at end of file
>From 42ca9cb8fff929911383f561d10d2fa12b43381c Mon Sep 17 00:00:00 2001
From: Aaron Ballman <aaron at aaronballman.com>
Date: Tue, 18 Mar 2025 12:11:15 -0400
Subject: [PATCH 7/7] Update based on review feedback
---
clang-tools-extra/clangd/Preamble.cpp | 2 +-
clang/docs/ReleaseNotes.rst | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/clangd/Preamble.cpp b/clang-tools-extra/clangd/Preamble.cpp
index de756cdb70c09..6fab3e2191426 100644
--- a/clang-tools-extra/clangd/Preamble.cpp
+++ b/clang-tools-extra/clangd/Preamble.cpp
@@ -628,7 +628,7 @@ buildPreamble(PathRef FileName, CompilerInvocation CI,
switch (Info.getID()) {
case diag::warn_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;
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 01485fcb51ec3..f4fe4a529bd92 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -128,9 +128,9 @@ C2y Feature Support
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. Note,
- ``-pedantic`` will no longer diagnose this in either C or C++ modes as an
- extension. This feature was adopted as applying to obsolete versions of C in
- WG14 and as a defect report in WG21 (CWG787).
+ ``-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
More information about the cfe-commits
mailing list