[clang] a766545 - Update the diagnostic behavior of [[noreturn]] in C2x

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 14 11:04:58 PST 2022


Author: Aaron Ballman
Date: 2022-02-14T14:04:32-05:00
New Revision: a766545402d8569532294d097d026cf2e837b5c2

URL: https://github.com/llvm/llvm-project/commit/a766545402d8569532294d097d026cf2e837b5c2
DIFF: https://github.com/llvm/llvm-project/commit/a766545402d8569532294d097d026cf2e837b5c2.diff

LOG: 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 5029dce492b3cf3ac191eda0b5bf268c3acac2e0.

Added: 
    

Modified: 
    clang/lib/Headers/stdnoreturn.h
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/Sema/c2x-noreturn.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/Headers/stdnoreturn.h b/clang/lib/Headers/stdnoreturn.h
index 92fd4a98a87bf..944e6904c7df6 100644
--- a/clang/lib/Headers/stdnoreturn.h
+++ b/clang/lib/Headers/stdnoreturn.h
@@ -15,11 +15,13 @@
 
 #if __STDC_VERSION__ > 201710L &&                                              \
     !defined(_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS)
-/* The noreturn macro is deprecated in C2x. */
-#pragma clang deprecated(noreturn)
-
-/* Including the header file in C2x is also deprecated. */
-#warning "the '<stdnoreturn.h>' header is deprecated in C2x"
+/* The noreturn macro is deprecated in C2x. We do not mark it as such because
+   including the header file in C2x is also deprecated and we do not want to
+   issue a confusing diagnostic for code which includes <stdnoreturn.h>
+   followed by code that writes [[noreturn]]. The issue with such code is not
+   with the attribute, or the use of 'noreturn', but the inclusion of the
+   header. */
+#warning "the '<stdnoreturn.h>' header is deprecated in C2x; either use the '_Noreturn' keyword or the '[[noreturn]]' attribute"
 #endif
 
 #endif /* __STDNORETURN_H */

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 6d0c8f0974767..3034abdf04028 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2177,9 +2177,14 @@ static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
 
 static void handleStandardNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &A) {
   // The [[_Noreturn]] spelling is deprecated in C2x, so if that was used,
-  // issue an appropriate diagnostic.
+  // issue an appropriate diagnostic. However, don't issue a diagnostic if the
+  // attribute name comes from a macro expansion. We don't want to punish users
+  // who write [[noreturn]] after including <stdnoreturn.h> (where 'noreturn'
+  // is defined as a macro which expands to '_Noreturn').
   if (!S.getLangOpts().CPlusPlus &&
-      A.getSemanticSpelling() == CXX11NoReturnAttr::C2x_Noreturn)
+      A.getSemanticSpelling() == CXX11NoReturnAttr::C2x_Noreturn &&
+      !(A.getLoc().isMacroID() &&
+        S.getSourceManager().isInSystemMacro(A.getLoc())))
     S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << A.getRange();
 
   D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));

diff  --git a/clang/test/Sema/c2x-noreturn.c b/clang/test/Sema/c2x-noreturn.c
index e522a43cf6eba..6c119736f6454 100644
--- a/clang/test/Sema/c2x-noreturn.c
+++ b/clang/test/Sema/c2x-noreturn.c
@@ -36,29 +36,30 @@ _Noreturn void func1(void); // ok, using the function specifier
 [[_Noreturn]] void func3(void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}}
 
 // Test the behavior of including <stdnoreturn.h>
-#include <stdnoreturn.h> // c2x-warning at stdnoreturn.h:* {{the '<stdnoreturn.h>' header is deprecated in C2x}}
+#include <stdnoreturn.h> // c2x-warning at stdnoreturn.h:* {{the '<stdnoreturn.h>' header is deprecated in C2x; either use the '_Noreturn' keyword or the '[[noreturn]]' attribute}}
 
-[[noreturn]] void func6(void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}} \
-                               // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
-                               // c2x-note at stdnoreturn.h:* {{macro marked 'deprecated' here}}
+[[noreturn]] void func6(void);
 
-void func7 [[noreturn]] (void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}} \
-                                // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
-                                // c2x-note at stdnoreturn.h:* {{macro marked 'deprecated' here}}
+void func7 [[noreturn]] (void);
 
-noreturn void func8(void); // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
-                           // c2x-note at stdnoreturn.h:* {{macro marked 'deprecated' here}}
+noreturn void func8(void);
 
-// Ensure the function specifier form still works
-void noreturn func9(void); // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
-                           // c2x-note at stdnoreturn.h:* {{macro marked 'deprecated' here}}
+// Ensure the function specifier form still works.
+void noreturn func9(void);
+
+// Ensure that spelling the deprecated form of the attribute is still diagnosed.
+[[_Noreturn]] void func10(void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}}
 
 // Test preprocessor functionality after including <stdnoreturn.h>.
-#if !__has_c_attribute(noreturn) // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
-                                 // c2x-note at stdnoreturn.h:* {{macro marked 'deprecated' here}}
+#if !__has_c_attribute(noreturn)
 #error "No noreturn attribute support?"
 #endif
 
 #if !__has_c_attribute(_Noreturn)
 #error "No _Noreturn attribute support?"
 #endif
+
+// Test that a macro which expands to _Noreturn is still diagnosed when it
+// doesn't come from a system header.
+#define NORETURN _Noreturn
+[[NORETURN]] void func11(void); // all-warning {{the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use '[[noreturn]]' instead}}


        


More information about the cfe-commits mailing list