[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 15 11:54:48 PST 2024
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200
>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 1/4] 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 6765721ae7002c1..9fcf2be2e45458e 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 414779a7970ab8e..0ad3ea64503d81e 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 4e7049571eeb7a3..e340028703b3b31 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 000000000000000..ce02309f0863863
--- /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)}}
+};
>From d43afccb027ea0e02c97ab9fbe55a1ad6c9d71dd Mon Sep 17 00:00:00 2001
From: Kelbon Nik <kelbonage at gmail.com>
Date: Mon, 15 Jan 2024 22:52:23 +0400
Subject: [PATCH 2/4] use precondition: NewFD is not null
---
clang/lib/Sema/SemaDecl.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index e340028703b3b31..dcbc5c3c842cca3 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11890,7 +11890,7 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
if (NewFD->hasAttr<PureAttr>() || NewFD->hasAttr<ConstAttr>()) {
- if (isa_and_nonnull<CXXConstructorDecl>(NewFD))
+ if (isa<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);
>From 3c5e6bcb2295f142f37f9bbd0d7801b3c67c3593 Mon Sep 17 00:00:00 2001
From: Kelbon Nik <kelbonage at gmail.com>
Date: Mon, 15 Jan 2024 23:49:57 +0400
Subject: [PATCH 3/4] not warn empty classes
---
clang/lib/Sema/SemaDecl.cpp | 6 ++++--
clang/test/Sema/incorrect_pure.cpp | 4 ++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index dcbc5c3c842cca3..1951177c4cad017 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11890,8 +11890,10 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
if (NewFD->hasAttr<PureAttr>() || NewFD->hasAttr<ConstAttr>()) {
- if (isa<CXXConstructorDecl>(NewFD))
- Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_constructor);
+ if (const CXXConstructorDecl* ctor = dyn_cast<NewFD>()) {
+ if (!ctor->getParent().isEmpty())
+ Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_constructor);
+ }
else if (NewFD->getReturnType()->isVoidType())
Diag(NewFD->getLocation(), diag::warn_pure_function_returns_void);
}
diff --git a/clang/test/Sema/incorrect_pure.cpp b/clang/test/Sema/incorrect_pure.cpp
index ce02309f0863863..8c19440a83c4c2b 100644
--- a/clang/test/Sema/incorrect_pure.cpp
+++ b/clang/test/Sema/incorrect_pure.cpp
@@ -3,5 +3,9 @@
[[gnu::pure]] void foo(); // expected-warning{{'pure' attribute on function returning 'void'}}
struct A {
+ int a;
[[gnu::pure]] A(); // expected-warning{{constructor cannot be 'pure' (undefined behavior)}}
};
+struct Empty {
+ [[gnu::pure]] Empty();
+};
>From 69f20399d665ecaf135b4e10c58ab853faa54d87 Mon Sep 17 00:00:00 2001
From: Kelbon Nik <kelbonage at gmail.com>
Date: Mon, 15 Jan 2024 23:54:35 +0400
Subject: [PATCH 4/4] format
---
clang/lib/Sema/SemaDecl.cpp | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 1951177c4cad017..f5a0ef327b7713a 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -11890,11 +11890,10 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
}
if (NewFD->hasAttr<PureAttr>() || NewFD->hasAttr<ConstAttr>()) {
- if (const CXXConstructorDecl* ctor = dyn_cast<NewFD>()) {
+ if (const CXXConstructorDecl *ctor = dyn_cast<NewFD>()) {
if (!ctor->getParent().isEmpty())
Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_constructor);
- }
- else if (NewFD->getReturnType()->isVoidType())
+ } else if (NewFD->getReturnType()->isVoidType())
Diag(NewFD->getLocation(), diag::warn_pure_function_returns_void);
}
More information about the cfe-commits
mailing list