Skip to content

Commit a766545

Browse files
committed
Update the diagnostic behavior of [[noreturn]] in C2x
Post-commit review feedback suggested dropping the deprecated diagnostic for the 'noreturn' macro (the diagnostic from the header file suffices and the macro diagnostic could be confusing) and to only issue the deprecated diagnostic for [[_Noreturn]] when the attribute identifier is either directly written or not from a system macro. Amends the commit made in 5029dce.
1 parent d0fb3ea commit a766545

File tree

3 files changed

+29
-21
lines changed

3 files changed

+29
-21
lines changed

clang/lib/Headers/stdnoreturn.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515

1616
#if __STDC_VERSION__ > 201710L && \
1717
!defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS)
18-
/* The noreturn macro is deprecated in C2x. */
19-
#pragma clang deprecated(noreturn)
20-
21-
/* Including the header file in C2x is also deprecated. */
22-
#warning "the '<stdnoreturn.h>' header is deprecated in C2x"
18+
/* The noreturn macro is deprecated in C2x. We do not mark it as such because
19+
including the header file in C2x is also deprecated and we do not want to
20+
issue a confusing diagnostic for code which includes <stdnoreturn.h>
21+
followed by code that writes [[noreturn]]. The issue with such code is not
22+
with the attribute, or the use of 'noreturn', but the inclusion of the
23+
header. */
24+
#warning "the '<stdnoreturn.h>' header is deprecated in C2x; either use the '_Noreturn' keyword or the '[[noreturn]]' attribute"
2325
#endif
2426

2527
#endif /* __STDNORETURN_H */

clang/lib/Sema/SemaDeclAttr.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,9 +2177,14 @@ static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
21772177

21782178
static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A) {
21792179
// The [[_Noreturn]] spelling is deprecated in C2x, so if that was used,
2180-
// issue an appropriate diagnostic.
2180+
// issue an appropriate diagnostic. However, don't issue a diagnostic if the
2181+
// attribute name comes from a macro expansion. We don't want to punish users
2182+
// who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'
2183+
// is defined as a macro which expands to '_Noreturn').
21812184
if (!S.getLangOpts().CPlusPlus &&
2182-
A.getSemanticSpelling() == CXX11NoReturnAttr::C2x_Noreturn)
2185+
A.getSemanticSpelling() == CXX11NoReturnAttr::C2x_Noreturn &&
2186+
!(A.getLoc().isMacroID() &&
2187+
S.getSourceManager().isInSystemMacro(A.getLoc())))
21832188
S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << A.getRange();
21842189

21852190
D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));

clang/test/Sema/c2x-noreturn.c

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,29 +36,30 @@ _Noreturn void func1(void); // ok, using the function specifier
3636
[[_Noreturn]] void func3(void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}}
3737

3838
// Test the behavior of including <stdnoreturn.h>
39-
#include <stdnoreturn.h> // [email protected]:* {{the '<stdnoreturn.h>' header is deprecated in C2x}}
39+
#include <stdnoreturn.h> // [email protected]:* {{the '<stdnoreturn.h>' header is deprecated in C2x; either use the '_Noreturn' keyword or the '[[noreturn]]' attribute}}
4040

41-
[[noreturn]] void func6(void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}} \
42-
// c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
43-
// [email protected]:* {{macro marked 'deprecated' here}}
41+
[[noreturn]] void func6(void);
4442

45-
void func7 [[noreturn]] (void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}} \
46-
// c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
47-
// [email protected]:* {{macro marked 'deprecated' here}}
43+
void func7 [[noreturn]] (void);
4844

49-
noreturn void func8(void); // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
50-
// [email protected]:* {{macro marked 'deprecated' here}}
45+
noreturn void func8(void);
5146

52-
// Ensure the function specifier form still works
53-
void noreturn func9(void); // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
54-
// [email protected]:* {{macro marked 'deprecated' here}}
47+
// Ensure the function specifier form still works.
48+
void noreturn func9(void);
49+
50+
// Ensure that spelling the deprecated form of the attribute is still diagnosed.
51+
[[_Noreturn]] void func10(void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}}
5552

5653
// Test preprocessor functionality after including <stdnoreturn.h>.
57-
#if !__has_c_attribute(noreturn) // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
58-
// [email protected]:* {{macro marked 'deprecated' here}}
54+
#if !__has_c_attribute(noreturn)
5955
#error "No noreturn attribute support?"
6056
#endif
6157

6258
#if !__has_c_attribute(_Noreturn)
6359
#error "No _Noreturn attribute support?"
6460
#endif
61+
62+
// Test that a macro which expands to _Noreturn is still diagnosed when it
63+
// doesn't come from a system header.
64+
#define NORETURN _Noreturn
65+
[[NORETURN]] void func11(void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}}

0 commit comments

Comments
 (0)