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@stdnoreturn.h:* {{the 
'<stdnoreturn.h>' header is deprecated in C2x}}
+#include <stdnoreturn.h> // c2x-warning@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@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@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@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@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@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}}


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to