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 <kelbon...@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 <kelbon...@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 <kelbon...@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 <kelbon...@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); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits