[clang] Warning for incorrect useof 'pure' attribute (PR #78200)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 15 10:35:06 PST 2024


https://github.com/kelbon created https://github.com/llvm/llvm-project/pull/78200

None

>From b080d04eb30254502ccd5d59d76b5197db1fa88d Mon Sep 17 00:00:00 2001
From: Kelbon Nik <kelbonage at gmail.com>
Date: Mon, 15 Jan 2024 22:24:34 +0400
Subject: [PATCH] add warning and test

---
 clang/include/clang/Basic/DiagnosticGroups.td    | 1 +
 clang/include/clang/Basic/DiagnosticSemaKinds.td | 7 +++++++
 clang/lib/Sema/SemaDecl.cpp                      | 7 +++++++
 clang/test/Sema/incorrect_pure.cpp               | 7 +++++++
 4 files changed, 22 insertions(+)
 create mode 100644 clang/test/Sema/incorrect_pure.cpp

diff --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index 6765721ae7002c..9fcf2be2e45458 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -414,6 +414,7 @@ def : DiagGroup<"c++2a-compat", [CXX20Compat]>;
 def : DiagGroup<"c++2a-compat-pedantic", [CXX20CompatPedantic]>;
 
 def ExitTimeDestructors : DiagGroup<"exit-time-destructors">;
+def IncorrectAttributeUsage : DiagGroup<"incorrect-attribute-usage">;
 def FlexibleArrayExtensions : DiagGroup<"flexible-array-extensions">;
 def FourByteMultiChar : DiagGroup<"four-char-constants">;
 def GlobalConstructors : DiagGroup<"global-constructors"> {
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 414779a7970ab8..0ad3ea64503d81 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -692,6 +692,13 @@ def warn_maybe_falloff_nonvoid_function : Warning<
 def warn_falloff_nonvoid_function : Warning<
   "non-void function does not return a value">,
   InGroup<ReturnType>;
+def warn_pure_attr_on_cxx_constructor : Warning<
+  "constructor cannot be 'pure' (undefined behavior)">,
+  InGroup<IncorrectAttributeUsage>;
+def warn_pure_function_returns_void : Warning<
+  "'pure' attribute on function returning 'void'">,
+  InGroup<IncorrectAttributeUsage>;
+
 def err_maybe_falloff_nonvoid_block : Error<
   "non-void block does not return a value in all control paths">;
 def err_falloff_nonvoid_block : Error<
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 4e7049571eeb7a..e340028703b3b3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11889,6 +11889,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
     NewFD->setInvalidDecl();
   }
 
+  if (NewFD->hasAttr<PureAttr>() || NewFD->hasAttr<ConstAttr>()) {
+    if (isa_and_nonnull<CXXConstructorDecl>(NewFD))
+      Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_constructor);
+    else if (NewFD->getReturnType()->isVoidType())
+      Diag(NewFD->getLocation(), diag::warn_pure_function_returns_void);
+  }
+
   // C++11 [dcl.constexpr]p8:
   //   A constexpr specifier for a non-static member function that is not
   //   a constructor declares that member function to be const.
diff --git a/clang/test/Sema/incorrect_pure.cpp b/clang/test/Sema/incorrect_pure.cpp
new file mode 100644
index 00000000000000..ce02309f086386
--- /dev/null
+++ b/clang/test/Sema/incorrect_pure.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+[[gnu::pure]] void foo(); // expected-warning{{'pure' attribute on function returning 'void'}}
+
+struct A {
+    [[gnu::pure]] A(); // expected-warning{{constructor cannot be 'pure' (undefined behavior)}}
+};



More information about the cfe-commits mailing list