Skip to content

[C2y] Implement WG14 N3411 #130180

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 2 commits into from
Mar 7, 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
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ C Language Changes

C2y Feature Support
^^^^^^^^^^^^^^^^^^^
- Implemented N3411 which allows a source file to not end with a newline
character. This is still reported as a conforming extension in earlier
language modes.

C23 Feature Support
^^^^^^^^^^^^^^^^^^^
Expand Down
15 changes: 7 additions & 8 deletions clang/lib/Lex/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3192,23 +3192,22 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
DiagnosticsEngine &Diags = PP->getDiagnostics();
SourceLocation EndLoc = getSourceLocation(BufferEnd);
unsigned DiagID;
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)) {
if (!Diags.isIgnored(diag::warn_cxx98_compat_no_newline_eof, EndLoc))
DiagID = diag::warn_cxx98_compat_no_newline_eof;
} else {
DiagID = diag::warn_no_newline_eof;
}
} else {
DiagID = diag::ext_no_newline_eof;
// This is conforming in C2y, but is an extension in earlier language
// modes.
if (!LangOpts.C2y)
DiagID = diag::ext_no_newline_eof;
Comment on lines +3204 to +3207
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that the corresponding change in C++ was introduced by a CWG issue (CWG787). Would it be preferred to treat N3411 as a DR?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, WG14 has a list of such things and this paper isn't on the list: https://www.open-std.org/jtc1/sc22/wg14/www/previous.html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interestingly, GCC does not warn https://compiler-explorer.com/z/vWMf6W551 , so I question the value of bundling that warning in -fpedantic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-pedantic exists to diagnose extensions and this is definitively an extension. So that's a GCC bug IMO. :-)

}

Diag(BufferEnd, DiagID)
<< FixItHint::CreateInsertion(EndLoc, "\n");
Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
}

BufferPtr = CurPtr;
Expand Down
15 changes: 15 additions & 0 deletions clang/test/C/C2y/n3411.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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 %s

/* WG14 N3411: Yes
* Slay Some Earthly Demons XII
*
* Allow a non-empty source file to end without a final newline character. Note
* that this file intentionally does not end with a trailing newline.
*/
// good-no-diagnostics

int x; // Ensure the file contains at least one declaration.
// expected-warning {{no newline at end of file}}
2 changes: 1 addition & 1 deletion clang/www/c_status.html
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ <h2 id="c2y">C2y implementation status</h2>
<tr>
<td>Slay Some Earthly Demons XII</td>
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3411.pdf">N3411</a></td>
<td class="unknown" align="center">Unknown</td>
<td class="unreleased" align="center">Clang 21</td>
</tr>
<tr>
<td>Slay Some Earthly Demons XIII</td>
Expand Down