[clang] 5029dce - Implement WG14 N2764 the [[noreturn]] attribute

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 14 06:38:35 PST 2022


Author: Aaron Ballman
Date: 2022-02-14T09:38:26-05:00
New Revision: 5029dce492b3cf3ac191eda0b5bf268c3acac2e0

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

LOG: Implement WG14 N2764 the [[noreturn]] attribute

This adds support for http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2764.pdf,
which was adopted at the Feb 2022 WG14 meeting. That paper adds
[[noreturn]] and [[_Noreturn]] to the list of supported attributes in
C2x. These attributes have the same semantics as the [[noreturn]]
attribute in C++.

The [[_Noreturn]] attribute was added as a deprecated feature so that
translation units which include <stdnoreturn.h> do not get an error on
use of [[noreturn]] because the macro expands to _Noreturn. Users can
use -Wno-deprecated-attributes to silence the diagnostic.

Use of <stdnotreturn.h> or the noreturn macro were both deprecated.
Users can define the _CLANG_DISABLE_CRT_DEPRECATION_WARNINGS macro to
suppress the deprecation diagnostics coming from the header file.

Added: 
    clang/test/Sema/c2x-noreturn.c

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/include/clang/Basic/Attr.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Headers/stdnoreturn.h
    clang/lib/Sema/SemaDeclAttr.cpp
    clang/test/AST/ast-dump-lambda.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 26860d3118020..d6115e0e4a51c 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -92,6 +92,11 @@ Windows Support
 C Language Changes in Clang
 ---------------------------
 
+C2x Feature Support
+-------------------
+
+- Implemented `WG14 N2674 The noreturn attribute <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2764.pdf>`_.
+
 C++ Language Changes in Clang
 -----------------------------
 

diff  --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 8e8b7bc16e3b2..f47bb413ea997 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -1209,10 +1209,10 @@ def C11NoReturn : InheritableAttr {
 }
 
 def CXX11NoReturn : InheritableAttr {
-  let Spellings = [CXX11<"", "noreturn", 200809>];
+  let Spellings = [CXX11<"", "noreturn", 200809>,
+                   C2x<"", "noreturn", 202202>, C2x<"", "_Noreturn", 202202>];
   let Subjects = SubjectList<[Function], ErrorDiag>;
   let Documentation = [CXX11NoReturnDocs];
-  let SimpleHandler = 1;
 }
 
 // Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1ea74e5e97f64..e7c204fef2a09 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4027,6 +4027,9 @@ def warn_vector_mode_deprecated : Warning<
   "specifying vector types with the 'mode' attribute is deprecated; "
   "use the 'vector_size' attribute instead">,
   InGroup<DeprecatedAttributes>;
+def warn_deprecated_noreturn_spelling : Warning<
+  "the '[[_Noreturn]]' attribute spelling is deprecated in C2x; use "
+  "'[[noreturn]]' instead">, InGroup<DeprecatedAttributes>;
 def err_complex_mode_vector_type : Error<
   "type of machine mode does not support base vector types">;
 def err_enum_mode_vector_type : Error<

diff  --git a/clang/lib/Headers/stdnoreturn.h b/clang/lib/Headers/stdnoreturn.h
index e83cd8153752c..92fd4a98a87bf 100644
--- a/clang/lib/Headers/stdnoreturn.h
+++ b/clang/lib/Headers/stdnoreturn.h
@@ -13,4 +13,13 @@
 #define noreturn _Noreturn
 #define __noreturn_is_defined 1
 
+#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"
+#endif
+
 #endif /* __STDNORETURN_H */

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index ddc7221e3713e..6d0c8f0974767 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -2175,6 +2175,16 @@ static void handleNoReturnAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
   D->addAttr(::new (S.Context) NoReturnAttr(S.Context, 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.
+  if (!S.getLangOpts().CPlusPlus &&
+      A.getSemanticSpelling() == CXX11NoReturnAttr::C2x_Noreturn)
+    S.Diag(A.getLoc(), diag::warn_deprecated_noreturn_spelling) << A.getRange();
+
+  D->addAttr(::new (S.Context) CXX11NoReturnAttr(S.Context, A));
+}
+
 static void handleNoCfCheckAttr(Sema &S, Decl *D, const ParsedAttr &Attrs) {
   if (!S.getLangOpts().CFProtectionBranch)
     S.Diag(Attrs.getLoc(), diag::warn_nocf_check_attribute_ignored);
@@ -8432,6 +8442,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
   case ParsedAttr::AT_NoReturn:
     handleNoReturnAttr(S, D, AL);
     break;
+  case ParsedAttr::AT_CXX11NoReturn:
+    handleStandardNoReturnAttr(S, D, AL);
+    break;
   case ParsedAttr::AT_AnyX86NoCfCheck:
     handleNoCfCheckAttr(S, D, AL);
     break;

diff  --git a/clang/test/AST/ast-dump-lambda.cpp b/clang/test/AST/ast-dump-lambda.cpp
index 7d16fa84b45bc..d93cf4a96b493 100644
--- a/clang/test/AST/ast-dump-lambda.cpp
+++ b/clang/test/AST/ast-dump-lambda.cpp
@@ -305,7 +305,7 @@ template <typename... Ts> void test(Ts... a) {
 // CHECK-NEXT:      | | `-Destructor simple irrelevant trivial needs_implicit
 // CHECK-NEXT:      | |-CXXMethodDecl {{.*}} <col:20, col:23> col:3{{( imported)?}} operator() 'auto () const' inline
 // CHECK-NEXT:      | | |-CompoundStmt {{.*}} <col:22, col:23>
-// CHECK-NEXT:      | | `-CXX11NoReturnAttr {{.*}} <col:8>
+// CHECK-NEXT:      | | `-CXX11NoReturnAttr {{.*}} <col:8> noreturn
 // CHECK-NEXT:      | |-CXXConversionDecl {{.*}} <col:3, col:23> col:3{{( imported)?}} implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
 // CHECK-NEXT:      | `-CXXMethodDecl {{.*}} <col:3, col:23> col:3{{( imported)?}} implicit __invoke 'auto ()' static inline
 // CHECK-NEXT:      `-CompoundStmt {{.*}} <col:22, col:23>

diff  --git a/clang/test/Sema/c2x-noreturn.c b/clang/test/Sema/c2x-noreturn.c
new file mode 100644
index 0000000000000..e522a43cf6eba
--- /dev/null
+++ b/clang/test/Sema/c2x-noreturn.c
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -verify=all,c2x -std=c2x -fsyntax-only %s
+// RUN: %clang_cc1 -verify=all -std=c17 -fdouble-square-bracket-attributes -fsyntax-only %s
+// RUN: %clang_cc1 -verify=none -Wno-deprecated-attributes -D_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS -std=c2x -fsyntax-only %s
+// RUN: %clang_cc1 -verify=none -Wno-deprecated-attributes -D_CLANG_DISABLE_CRT_DEPRECATION_WARNINGS -std=c17 -fdouble-square-bracket-attributes -fsyntax-only %s
+// none-no-diagnostics
+
+// Test preprocessor functionality.
+#if !__has_c_attribute(noreturn)
+#error "No noreturn attribute support?"
+#endif
+
+#if !__has_c_attribute(_Noreturn)
+#error "No _Noreturn attribute support?"
+#endif
+
+#if __has_c_attribute(noreturn) != __has_c_attribute(_Noreturn) || \
+    __has_c_attribute(noreturn) != 202202L
+#error "Wrong value for __has_c_attribute(noreturn)"
+#endif
+
+// If we're testings with deprecations disabled, we don't care about testing
+// the scenarios that trigger errors because we're only interested in the
+// deprecation warning behaviors.
+#ifndef _CLANG_DISABLE_CRT_DEPRECATION_WARNINGS
+// Test that the attribute accepts no args, applies to the correct subject, etc.
+[[noreturn(12)]] void func4(void); // all-error {{attribute 'noreturn' cannot have an argument list}}
+[[noreturn]] int not_a_func; // all-error {{'noreturn' attribute only applies to functions}}
+void func5(void) [[noreturn]]; // all-error {{'noreturn' attribute cannot be applied to types}}
+#endif
+
+_Noreturn void func1(void); // ok, using the function specifier
+[[noreturn]] void func2(void);
+
+// This is deprecated because it's only for compatibility with inclusion of the
+// <stdnoreturn.h> header where the noreturn macro expands to _Noreturn.
+[[_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}}
+
+[[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}}
+
+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}}
+
+noreturn void func8(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); // c2x-warning {{macro 'noreturn' has been marked as deprecated}} \
+                           // c2x-note at stdnoreturn.h:* {{macro marked 'deprecated' here}}
+
+// 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}}
+#error "No noreturn attribute support?"
+#endif
+
+#if !__has_c_attribute(_Noreturn)
+#error "No _Noreturn attribute support?"
+#endif


        


More information about the cfe-commits mailing list