Skip to content

Commit 517b2b6

Browse files
committed
[C2y] Implement WG14 N3411
This paper allows a source file to end without a newline. Clang has supported this as a conforming extension for a long time, so this suppresses the diagnotic in C2y mode but continues to diagnose as an extension in earlier language modes. It also continues to diagnose if the user passes -Wnewline-eof explicitly.
1 parent f3effc2 commit 517b2b6

File tree

4 files changed

+25
-9
lines changed

4 files changed

+25
-9
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ C Language Changes
108108

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

112115
C23 Feature Support
113116
^^^^^^^^^^^^^^^^^^^

clang/lib/Lex/Lexer.cpp

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3192,23 +3192,22 @@ bool Lexer::LexEndOfFile(Token &Result, const char *CurPtr) {
31923192
if (CurPtr != BufferStart && (CurPtr[-1] != '\n' && CurPtr[-1] != '\r')) {
31933193
DiagnosticsEngine &Diags = PP->getDiagnostics();
31943194
SourceLocation EndLoc = getSourceLocation(BufferEnd);
3195-
unsigned DiagID;
3195+
unsigned DiagID = diag::warn_no_newline_eof;
31963196

31973197
if (LangOpts.CPlusPlus11) {
31983198
// C++11 [lex.phases] 2.2 p2
31993199
// Prefer the C++98 pedantic compatibility warning over the generic,
32003200
// non-extension, user-requested "missing newline at EOF" warning.
3201-
if (!Diags.isIgnored(diag::warn_cxx98_compat_no_newline_eof, EndLoc)) {
3201+
if (!Diags.isIgnored(diag::warn_cxx98_compat_no_newline_eof, EndLoc))
32023202
DiagID = diag::warn_cxx98_compat_no_newline_eof;
3203-
} else {
3204-
DiagID = diag::warn_no_newline_eof;
3205-
}
32063203
} else {
3207-
DiagID = diag::ext_no_newline_eof;
3204+
// This is conforming in C2y, but is an extension in earlier language
3205+
// modes.
3206+
if (!LangOpts.C2y)
3207+
DiagID = diag::ext_no_newline_eof;
32083208
}
32093209

3210-
Diag(BufferEnd, DiagID)
3211-
<< FixItHint::CreateInsertion(EndLoc, "\n");
3210+
Diag(BufferEnd, DiagID) << FixItHint::CreateInsertion(EndLoc, "\n");
32123211
}
32133212

32143213
BufferPtr = CurPtr;

clang/test/C/C2y/n3411.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %clang_cc1 -verify=c2y -std=c2y -Wall -pedantic %s
2+
// RUN: %clang_cc1 -verify -Wnewline-eof -std=c2y -Wall -pedantic %s
3+
// RUN: %clang_cc1 -verify -std=c23 -Wall -pedantic %s
4+
5+
/* WG14 N3411: Yes
6+
* Slay Some Earthly Demons XII
7+
*
8+
* Allow a non-empty source file to end without a final newline character. Note
9+
* that this file intentionally does not end with a trailing newline.
10+
*/
11+
// c2y-no-diagnostics
12+
13+
int x; // Ensure the file contains at least one declaration.
14+
// expected-warning {{no newline at end of file}}

clang/www/c_status.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ <h2 id="c2y">C2y implementation status</h2>
294294
<tr>
295295
<td>Slay Some Earthly Demons XII</td>
296296
<td><a href="https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3411.pdf">N3411</a></td>
297-
<td class="unknown" align="center">Unknown</td>
297+
<td class="unreleased" align="center">Clang 21</td>
298298
</tr>
299299
<tr>
300300
<td>Slay Some Earthly Demons XIII</td>

0 commit comments

Comments
 (0)