[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
AaronBallman wrote: > > LGTM, thank you! > > What's next? I cannot push changes Thanks for mentioning that; I've pushed the changes on your behalf. Thank you for the improvements! https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/AaronBallman closed https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
kelbon wrote: > LGTM, thank you! What's next? I cannot push changes https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/AaronBallman approved this pull request. LGTM, thank you! https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From fb05243d0c0c3702b1615239a9337df337ad0c7c Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 01/13] 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 03b0122d1c08f7..1df075119a482f 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 5472b43aafd4f3..69ce7c50764fac 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11898,6 +11898,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 00..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)}} +}; >From e89f96c76d730a3cd9e1647837366a38f88118a3 Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 02/13] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803..727217f228b054 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From fb05243d0c0c3702b1615239a9337df337ad0c7c Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 01/12] 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 03b0122d1c08f7..1df075119a482f 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 5472b43aafd4f3..69ce7c50764fac 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11898,6 +11898,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 00..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)}} +}; >From e89f96c76d730a3cd9e1647837366a38f88118a3 Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 02/12] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803..727217f228b054 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From fb05243d0c0c3702b1615239a9337df337ad0c7c Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 01/11] 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 03b0122d1c08f75..1df075119a482fb 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 5472b43aafd4f39..69ce7c50764fac2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11898,6 +11898,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 000..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 e89f96c76d730a3cd9e1647837366a38f88118a3 Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 02/11] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803f..727217f228b0542 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clan
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From fb05243d0c0c3702b1615239a9337df337ad0c7c Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 01/10] 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 03b0122d1c08f75..1df075119a482fb 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 5472b43aafd4f39..69ce7c50764fac2 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11898,6 +11898,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 000..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 e89f96c76d730a3cd9e1647837366a38f88118a3 Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 02/10] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803f..727217f228b0542 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clan
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11801,6 +11801,26 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, AaronBallman wrote: ```suggestion static void DiagnoseConstPureAttributeConflicts(Sema &S, ``` The function does something very specific so we might as well give it a more specific name. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -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; +def warn_const_attr_with_pure_attr : Warning< + "'const' attribute imposes more restrictions, 'pure' attribute ignored">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'%select{pure|const}0' attribute on function returning 'void', attribute ignored">, + InGroup; AaronBallman wrote: ```suggestion def warn_const_attr_with_pure_attr : Warning< "'const' attribute imposes more restrictions; 'pure' attribute ignored">, InGroup; def warn_pure_function_returns_void : Warning< "'%select{pure|const}0' attribute on function returning 'void'; attribute ignored">, InGroup; ``` minor nit for consistency with other related diagnostics. Btw, to be explicit, I think it's reasonable that we do not reuse the usual "mutually exclusive attributes" functionality here because we have a very specific way to correct this situation whereas the usual behavior for mutual exclusion is that the first one wins. So adding a new diagnostic and using custom logic is appropriate IMO. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11801,6 +11801,26 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttrs(); + } + if (!IsPure && !IsConst) +return; AaronBallman wrote: ```suggestion // If there are no pure or const attributes, there's nothing to check. if (!IsPure || !IsConst) return; // If the function is marked both pure and const, we retain the const attribute // because it makes stronger guarantees than the pure attribute, and we drop // the pure attribute explicitly to prevent later confusion about semantics. if (IsPure && IsConst) { S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); NewFD->dropAttrs(); } ``` Rearranging the logic and adding some comments. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -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; +def warn_const_attr_with_pure_attr : Warning< + "'const' attribute imposes more restrictions, 'pure' attribute ignored">, + InGroup; erichkeane wrote: I think the changes made here are sufficiently closely related, they are definitely 'near the line', but are sufficiently close (in that it is fixing up teh diagnostics for the pure/const attributes). https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/erichkeane edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/erichkeane approved this pull request. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From fb05243d0c0c3702b1615239a9337df337ad0c7c Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/9] 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 03b0122d1c08f7..1df075119a482f 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 5472b43aafd4f3..69ce7c50764fac 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11898,6 +11898,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 00..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)}} +}; >From e89f96c76d730a3cd9e1647837366a38f88118a3 Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 2/9] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803..727217f228b054 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eva
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From fb05243d0c0c3702b1615239a9337df337ad0c7c Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/8] 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 03b0122d1c08f7..1df075119a482f 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 5472b43aafd4f3..69ce7c50764fac 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11898,6 +11898,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 00..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)}} +}; >From e89f96c76d730a3cd9e1647837366a38f88118a3 Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 2/8] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803..727217f228b054 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eva
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From fb05243d0c0c3702b1615239a9337df337ad0c7c Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/7] 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 03b0122d1c08f7..1df075119a482f 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 5472b43aafd4f3..69ce7c50764fac 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11898,6 +11898,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 00..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)}} +}; >From e89f96c76d730a3cd9e1647837366a38f88118a3 Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 2/7] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803..727217f228b054 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eva
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11802,6 +11802,27 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { ChuanqiXu9 wrote: Then we should handle different attributes in different places. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -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; +def warn_const_attr_with_pure_attr : Warning< + "'const' attribute imposes more restrictions, 'pure' attribute ignored">, + InGroup; ChuanqiXu9 wrote: While this is not required, **incorrect** is too broad. e.g., a lot of clang's change can be summarized as fixing incorrect implementation for C++. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -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; +def warn_const_attr_with_pure_attr : Warning< + "'const' attribute imposes more restrictions, 'pure' attribute ignored">, + InGroup; kelbon wrote: But it is same case - incorrect 'pure' usage https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11802,6 +11802,27 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { kelbon wrote: Early return is good, but i think it may be customization point, where different attributes/contract checks will be in future, so early return will cause more changes in future https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11802,6 +11802,27 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { ChuanqiXu9 wrote: ```suggestion if (!IsPure && !IsConst) return; ... ``` nit: we prefer short indentation. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/ChuanqiXu9 approved this pull request. LGTM https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -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; +def warn_const_attr_with_pure_attr : Warning< + "'const' attribute imposes more restrictions, 'pure' attribute ignored">, + InGroup; ChuanqiXu9 wrote: nit: generally we prefer one patch does one thing manner. So maybe we can add this in later patches. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/ChuanqiXu9 edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From e8c799b54c3e0b8088dbc19aaac0ef066baf136e Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/6] 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 03b0122d1c08f75..1df075119a482fb 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 dae98f3a7406e87..86dc022fbe055d8 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11899,6 +11899,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 000..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 d152fa4881d6052bfad33c922f276d4909c305ec Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 2/6] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803f..727217f228b0542 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_an
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From e8c799b54c3e0b8088dbc19aaac0ef066baf136e Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/5] 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 03b0122d1c08f7..1df075119a482f 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 dae98f3a7406e8..86dc022fbe055d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11899,6 +11899,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 00..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)}} +}; >From d152fa4881d6052bfad33c922f276d4909c305ec Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 2/5] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803..727217f228b054 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eva
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From e8c799b54c3e0b8088dbc19aaac0ef066baf136e Mon Sep 17 00:00:00 2001 From: Kelbon Nik 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 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 03b0122d1c08f7..1df075119a482f 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 dae98f3a7406e8..86dc022fbe055d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11899,6 +11899,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 00..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)}} +}; >From d152fa4881d6052bfad33c922f276d4909c305ec Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 2/4] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803..727217f228b054 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eva
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/Endilll edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/Endilll edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { Endilll wrote: I wonder if start of a lifetime and end of the lifetime that is tied to constructor and destructor can be considered side effects in this context, preventing them from ever being pure functions. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon updated https://github.com/llvm/llvm-project/pull/78200 >From e8c799b54c3e0b8088dbc19aaac0ef066baf136e Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/3] 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 03b0122d1c08f7..1df075119a482f 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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 dae98f3a7406e8..86dc022fbe055d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -11899,6 +11899,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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 00..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)}} +}; >From d152fa4881d6052bfad33c922f276d4909c305ec Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 2/3] fix old incorrect test --- clang/test/Analysis/call-invalidation.cpp | 8 clang/test/CodeGen/pragma-weak.c| 6 +++--- clang/test/Interpreter/disambiguate-decl-stmt.cpp | 4 ++-- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- clang/test/SemaCXX/warn-unused-value-cxx11.cpp | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/clang/test/Analysis/call-invalidation.cpp b/clang/test/Analysis/call-invalidation.cpp index ef6505e19cf803..727217f228b054 100644 --- a/clang/test/Analysis/call-invalidation.cpp +++ b/clang/test/Analysis/call-invalidation.cpp @@ -90,8 +90,8 @@ void testConstReferenceStruct() { } -void usePointerPure(int * const *) __attribute__((pure)); -void usePointerConst(int * const *) __attribute__((const)); +int usePointerPure(int * const *) __attribute__((pure)); +int usePointerConst(int * const *) __attribute__((const)); void testPureConst() { extern int global; @@ -104,11 +104,11 @@ void testPureConst() { clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerPure(&p); + (void)usePointerPure(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eval(global == -5); // expected-warning{{TRUE}} - usePointerConst(&p); + (void)usePointerConst(&p); clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} clang_analyzer_eva
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 01/11] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; >From d43afccb027ea0e02c97ab9fbe55a1ad6c9d71dd Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 02/11] 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 e340028703b3b3..dcbc5c3c842cca 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 03/11] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f6..6ae146f0d08c7d 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal definitions)
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,26 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { +// constructors and destructors also functions which returns void +if (NewFD->getReturnType()->isVoidType()) { + S.Diag(NewFD->getLocation(), diag::warn_pure_function_returns_void) + << IsConst; + NewFD->dropAttr(); + NewFD->dropAttr(); AaronBallman wrote: Ah shoot, you're right https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,26 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { +// constructors and destructors also functions which returns void +if (NewFD->getReturnType()->isVoidType()) { + S.Diag(NewFD->getLocation(), diag::warn_pure_function_returns_void) + << IsConst; + NewFD->dropAttr(); + NewFD->dropAttr(); erichkeane wrote: Done here: https://github.com/llvm/llvm-project/pull/78476 Note that the 2nd and the 3rd from your list are actually from different decls, so don't help. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,26 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { +// constructors and destructors also functions which returns void +if (NewFD->getReturnType()->isVoidType()) { + S.Diag(NewFD->getLocation(), diag::warn_pure_function_returns_void) + << IsConst; + NewFD->dropAttr(); + NewFD->dropAttr(); erichkeane wrote: We already have 'dropAttrs' that does 'drop all attrs', so I was worried about that. Perhaps I'll spend a little time writing up a variadic `dropAttrs` and `hasAttr` https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,26 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { +// constructors and destructors also functions which returns void +if (NewFD->getReturnType()->isVoidType()) { + S.Diag(NewFD->getLocation(), diag::warn_pure_function_returns_void) + << IsConst; + NewFD->dropAttr(); + NewFD->dropAttr(); AaronBallman wrote: I see the following cases where we'd use that: https://github.com/llvm/llvm-project/blob/a96b4671b97b167230986bd2811676064c608596/clang/lib/Sema/SemaDecl.cpp#L7071 https://github.com/llvm/llvm-project/blob/a96b4671b97b167230986bd2811676064c608596/clang/lib/Sema/SemaDecl.cpp#L7264 https://github.com/llvm/llvm-project/blob/a96b4671b97b167230986bd2811676064c608596/clang/lib/Sema/SemaDecl.cpp#L7270 https://github.com/llvm/llvm-project/blob/5b65f6f5864ff23e4d87ab1d954a77be343b4c4b/clang/lib/Sema/SemaDeclCXX.cpp#L6548 https://github.com/llvm/llvm-project/blob/5b65f6f5864ff23e4d87ab1d954a77be343b4c4b/clang/lib/Sema/SemaTemplate.cpp#L9233 so it's not the most common pattern in the world but it would simplify some code. I would name it `dropAttrs()` though so it's clear that it drops all of the attributes, not just one of them. I wouldn't insist on introducing the API for this patch, but it would be a reasonable follow-up. (FWIW, `hasAttr` would be a bigger win in terms of variadic template support.) https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,26 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { +// constructors and destructors also functions which returns void erichkeane wrote: ```suggestion // Constructors and destructors are functions which return void, so are handled here as well. ``` https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,26 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + bool IsPure = NewFD->hasAttr(); + bool IsConst = NewFD->hasAttr(); + + if (IsPure && IsConst) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (IsPure || IsConst) { +// constructors and destructors also functions which returns void +if (NewFD->getReturnType()->isVoidType()) { + S.Diag(NewFD->getLocation(), diag::warn_pure_function_returns_void) + << IsConst; + NewFD->dropAttr(); + NewFD->dropAttr(); erichkeane wrote: There is perhaps use in changing `dropAttr` to be a variadic template, and dropping a bunch at once. I realize 'N' is small here, but turns from O(2N) to O(N). So in DeclBase.h: ``` template void dropAttr() { if (!HasAttrs) return; AttrVec &Vec = getAttrs(); llvm::erase_if(Vec, [](Attr *A) { return isa(A) ; }); if (Vec.empty()) HasAttrs = false; } }; ``` WDYT Aaron? Is this something we'd use? https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 01/10] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 000..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 Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 02/10] 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 03/10] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f67..6ae146f0d08c7d3 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/9] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; >From d43afccb027ea0e02c97ab9fbe55a1ad6c9d71dd Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/9] 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 e340028703b3b3..dcbc5c3c842cca 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 3/9] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f6..6ae146f0d08c7d 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal definitions) stru
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/8] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 000..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 Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/8] 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 3/8] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f67..6ae146f0d08c7d3 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal defini
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { erichkeane wrote: >(not counting placement new) Thats a big 'not counting' there... `A a = A(args...);` That isn't calling the constructor, that is effectively 'constructing an object, then copying it to the LHS (though we omit the copy)'. `A a{args...};` is also valid, which shows that it isn't the same. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { kelbon wrote: > I don't agree that a constructor 'returns a value'. Both a constructor and a > destructor are the same in that they are functions that modify their 1st > parameter (the this parameter) or 'throw'. They are effectively the same > thing. > > I don't see how a constructor could ever make sense with 'pure', same as it > doesn't make sense on destructors. > > We should be handling them the same. But user cannot separate the creation of an object and its construction from C++ code (not counting placement new) ```cpp struct A { ... fields ... [[pure]] A(...args); }; ... A a = A(args...); ... ``` But on other side user can write: ```cpp struct A { ... }; [[puer]] A A_constructor(...args); ``` And it will be correct, so, why i was hoping we let user create it less verbose in C++ interface https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); erichkeane wrote: Got it, had those reversed in my head. Thanks for the clarification. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); kelbon wrote: > The const attribute imposes greater restrictions on a function’s definition > than the similar pure attribute. https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { erichkeane wrote: I don't agree that a constructor 'returns a value'. Both a constructor and a destructor are the same in that they are functions that modify their 1st parameter (the this parameter) or 'throw'. They are effectively the same thing. I don't see how a constructor could ever make sense with 'pure', same as it doesn't make sense on destructors. We should be handling them the same. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); erichkeane wrote: Why drop 'pure'? It is more constrained than const, right? it would seem that keeping 'pure' around and dropping const would be more consistent. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { AaronBallman wrote: > My point is that semantically a constructor has a return value, the user can > think of a constructor as a function that returns a value. And in the future > we may change the behavior so that marking the constructor 'pure' will make > sense. I don't know if it's common for people to think of a constructor as a function that returns a value, but I can squint and see that line of thinking. CC @erichkeane for more opinions. > This leads to just ignoring 'pure'/'const' on constructors without warning > now to make possible change it in future (but gcc thinks it is UB) I think we can change it in the future either way, this is about diagnostic wording. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { kelbon wrote: My point is that semantically a constructor has a return value, the user can think of a constructor as a function that returns a value. And in the future we may change the behavior so that marking the constructor 'pure' will make sense. But with functions and destructors it will never make sense https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { AaronBallman wrote: I don't see why constructors and destructors should be handled differently. Neither has a way to specify a return value. My mental model for this is: pure and const only make sense on functions that are called for their return value. So anything which does not return a value is suspect to have either of these attributes. For ctor and dtor, there's no possible return value and so there is only one possible remedy (remove the attribute). For functions returning void, there are two possible remedies, remove the attribute or give the function a non-void return type. Another situation worth thinking about is a function marked `noreturn` but I think those functions are typically declared with a `void` return type anyway and so I'm not certain we need special logic to diagnose this case. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { kelbon wrote: Destructors handled in 'function returning void' case and i think pure constructor is different from 'pure' function returning void while destructor is not https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -692,6 +692,16 @@ def warn_maybe_falloff_nonvoid_function : Warning< def warn_falloff_nonvoid_function : Warning< "non-void function does not return a value">, InGroup; +def warn_const_attr_with_pure_attr : Warning< + "'const' attribute imposes greater restrictions than 'pure', 'pure' attribute ignored">, AaronBallman wrote: ```suggestion "'const' attribute imposes greater restrictions than 'pure'; 'pure' attribute ignored">, ``` Minor change, may have to re-flow the line to fit within 80 columns. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { AaronBallman wrote: ```suggestion if (isa(NewFD)) { ``` And destructors as well, yes? (Will need to update the diagnostic accordingly.) https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); AaronBallman wrote: ```suggestion bool IsPure = NewFD->hasAttr(); bool IsConst = NewFD->hasAttr(); ``` adjusting for coding style nits. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -560,7 +560,8 @@ Improvements to Clang's diagnostics - Clang now diagnoses unexpanded packs within the template argument lists of function template specializations. - Clang now diagnoses attempts to bind a bitfield to an NTTP of a reference type as erroneous converted constant expression and not as a reference to subobject. - +- Clang now diagnoses incorrect usage of 'const' and 'pure' attributes (``-Wincorrect-pure-usage``), AaronBallman wrote: ```suggestion - Clang now diagnoses incorrect usage of ``const`` and ``pure`` attributes (``-Wincorrect-pure-usage``), ``` https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -692,6 +692,16 @@ def warn_maybe_falloff_nonvoid_function : Warning< def warn_falloff_nonvoid_function : Warning< "non-void function does not return a value">, InGroup; +def warn_const_attr_with_pure_attr : Warning< + "'const' attribute imposes greater restrictions than 'pure', 'pure' attribute ignored">, + InGroup; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be '%select{pure|const}0', attribute ignored">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'%select{pure|const}0' attribute on function returning 'void'">, AaronBallman wrote: I think this should also say `; attribute ignored` and be under the `IgnoredAttribtues` warning group. The attribute has no semantics for a function which returns `void`. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -692,6 +692,16 @@ def warn_maybe_falloff_nonvoid_function : Warning< def warn_falloff_nonvoid_function : Warning< "non-void function does not return a value">, InGroup; +def warn_const_attr_with_pure_attr : Warning< + "'const' attribute imposes greater restrictions than 'pure', 'pure' attribute ignored">, + InGroup; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be '%select{pure|const}0', attribute ignored">, AaronBallman wrote: ```suggestion "constructor cannot be '%select{pure|const}0'; attribute ignored">, ``` https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11792,6 +11792,32 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD, OldDecl, Previous); } +static void CheckFunctionDeclarationAttributesUsage(Sema &S, +FunctionDecl *NewFD) { + const bool is_pure = NewFD->hasAttr(); + const bool is_const = NewFD->hasAttr(); + + if (is_pure && is_const) { +S.Diag(NewFD->getLocation(), diag::warn_const_attr_with_pure_attr); +NewFD->dropAttr(); + } + if (is_pure || is_const) { +if (isa(NewFD)) { + // 'pure' constructor is an insidious error: + // while constructor semantically 'returns' object + // but it should modify memory by implicit 'this' pointer + S.Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_constructor) + << (is_const ? 1 : 0); AaronBallman wrote: ```suggestion S.Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_constructor) << IsConst; ``` https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/7] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 000..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 Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/7] 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 3/7] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f67..6ae146f0d08c7d3 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal defini
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/6] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 000..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 Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/6] 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 3/6] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f67..6ae146f0d08c7d3 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal defini
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
AaronBallman wrote: > > The changes should also come with a release note so users know about the > > improved diagnostics. > > Dont know how to do it, can you please reference what i need to do? Modify https://github.com/llvm/llvm-project/blob/main/clang/docs/ReleaseNotes.rst to have a new entry under `Improvements to Clang's diagnostics` > > How about: '%select{pure|const}0' attribute applied to a function which > > %select{returns 'void'|has no return value}1; attribute ignored? Then it > > handles both situations, both attributes, and we don't need to invent a new > > warning group (it can go under IgnoredAttributes). > > -Current behavior: silent UB -I think how this should work in future: valid > and special case of [[pure]] -This PR: warning + UB > But now i dont think it is not a good idea to ignore attribute, because GCC > does not ignores it (so, code will work until compiled with GCC and breaks) GCC doesn't define the behavior in these cases, right? If so, then the code is nonportable to begin with and dropping the attribute + warning about ignoring them seems like the correct behavior. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
kelbon wrote: > The changes should also come with a release note so users know about the > improved diagnostics. Dont know how to do it, can you please reference what i need to do? > How about: '%select{pure|const}0' attribute applied to a function which > %select{returns 'void'|has no return value}1; attribute ignored? Then it > handles both situations, both attributes, and we don't need to invent a new > warning group (it can go under IgnoredAttributes). -Currennt behavior: silent UB -I think how this should work in future: valid and special case of [[pure]] -This PR: warning + UB But now i dont think it is not a good idea to ignore attribute, because GCC does not ignores it (so, code will work until compiled with GCC and breaks) Also i will add warning for destructors (i was working and forget about it) https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; AaronBallman wrote: Also, I don't think it's always UB to mark a constructor as being pure, it's just not a sensible operation because a constructor does not produce a value. (For example, this constructor doesn't violate any principles of function purity except that it's not called for its value: `struct S { [[gnu::pure]] S() {} };`) And I think the same logic applies to marking a destructor as pure; it doesn't make sense as an operation. How about: `'%select{pure|const}0' attribute applied to a function which %select{returns 'void'|has no return value}1; attribute ignored`? Then it handles both situations, both attributes, and we don't need to invent a new warning group (it can go under `IgnoredAttributes`). https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/AaronBallman commented: The changes should also come with a release note so users know about the improved diagnostics. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/AaronBallman edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/5] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; >From d43afccb027ea0e02c97ab9fbe55a1ad6c9d71dd Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/5] 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 e340028703b3b3..dcbc5c3c842cca 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 3/5] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f6..6ae146f0d08c7d 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal definitions) stru
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11889,6 +11889,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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); kelbon wrote: I think it may be confusing, because name 'const' is similar to keyword 'const', specially for constructor ```cpp struct A { A() const; } ``` But i will check now to improve it https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 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 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; >From d43afccb027ea0e02c97ab9fbe55a1ad6c9d71dd Mon Sep 17 00:00:00 2001 From: Kelbon Nik 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 e340028703b3b3..dcbc5c3c842cca 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 3/4] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f6..6ae146f0d08c7d 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal definitions) stru
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11889,6 +11889,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(NewFD)) + Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_constructor); +else if (NewFD->getReturnType()->isVoidType()) ChuanqiXu9 wrote: Also let's get some comments for the rationale here even if you feel it is obivious. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; ChuanqiXu9 wrote: ```suggestion InGroup<>; ``` It looks a little bit far to invent `IncorrectAttributeUsage` group here https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
@@ -11889,6 +11889,13 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, NewFD->setInvalidDecl(); } + if (NewFD->hasAttr() || NewFD->hasAttr()) { +if (isa(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); ChuanqiXu9 wrote: Then the title and the diagnostic might be confusing if the user are using `[[gnu::const]]`. You can look at the use of `%select` in `clang/include/clang/Basic/DiagnosticSemaKinds.td` to improve this. Also we need a test for `[[gnu::const]]` too. https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/3] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 000..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 Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/3] 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 950ca9de1c05d561a1123c088455a3e21bd9795b Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Tue, 16 Jan 2024 00:03:47 +0400 Subject: [PATCH 3/3] fix old incorrect test --- clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp index 9d68a0e5d358f67..6ae146f0d08c7d3 100644 --- a/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp +++ b/clang/test/SemaCXX/cxx0x-cursory-default-delete.cpp @@ -194,7 +194,7 @@ struct except_spec_d_match : except_spec_a, except_spec_b { // gcc-compatibility: allow attributes on default definitions // (but not normal defini
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/2] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; >From d43afccb027ea0e02c97ab9fbe55a1ad6c9d71dd Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/2] 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 e340028703b3b3..dcbc5c3c842cca 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 000..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 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 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() || NewFD->hasAttr()) { -if (isa(NewFD)) - Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_c
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
github-actions[bot] wrote: :warning: C/C++ code formatter, clang-format found issues in your code. :warning: You can test this locally with the following command: ``bash git-clang-format --diff ba131b7017ce99d56a0584e630ed542d8cd48488 3c5e6bcb2295f142f37f9bbd0d7801b3c67c3593 -- clang/test/Sema/incorrect_pure.cpp clang/lib/Sema/SemaDecl.cpp `` View the diff from clang-format here. ``diff diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 1951177c4c..f5a0ef327b 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() || NewFD->hasAttr()) { -if (const CXXConstructorDecl* ctor = dyn_cast()) { +if (const CXXConstructorDecl *ctor = dyn_cast()) { 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); } `` https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/3] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; >From d43afccb027ea0e02c97ab9fbe55a1ad6c9d71dd Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/3] 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 e340028703b3b3..dcbc5c3c842cca 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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 Date: Mon, 15 Jan 2024 23:49:57 +0400 Subject: [PATCH 3/3] 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 dcbc5c3c842cca..1951177c4cad01 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() || NewFD->hasAttr()) { -if (isa(NewFD)) - Diag(NewFD->getLocation(), diag::warn_pure_attr_on_cxx_constructor);
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 Date: Mon, 15 Jan 2024 22:24:34 +0400 Subject: [PATCH 1/2] 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; >From d43afccb027ea0e02c97ab9fbe55a1ad6c9d71dd Mon Sep 17 00:00:00 2001 From: Kelbon Nik Date: Mon, 15 Jan 2024 22:52:23 +0400 Subject: [PATCH 2/2] 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 e340028703b3b3..dcbc5c3c842cca 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() || NewFD->hasAttr()) { -if (isa_and_nonnull(NewFD)) +if (isa(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); ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
https://github.com/kelbon edited https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
llvmbot wrote: @llvm/pr-subscribers-clang Author: None (kelbon) Changes --- Full diff: https://github.com/llvm/llvm-project/pull/78200.diff 4 Files Affected: - (modified) clang/include/clang/Basic/DiagnosticGroups.td (+1) - (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+7) - (modified) clang/lib/Sema/SemaDecl.cpp (+7) - (added) clang/test/Sema/incorrect_pure.cpp (+7) ``diff 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; `` https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
github-actions[bot] wrote: Thank you for submitting a Pull Request (PR) to the LLVM Project! This PR will be automatically labeled and the relevant teams will be notified. If you wish to, you can add reviewers by using the "Reviewers" section on this page. If this is not working for you, it is probably because you do not have write permissions for the repository. In which case you can instead tag reviewers by name in a comment by using `@` followed by their GitHub username. If you have received no comments on your PR for a week, you can request a review by "ping"ing the PR by adding a comment “Ping”. The common courtesy "ping" rate is once a week. Please remember that you are asking for valuable time from other developers. If you have further questions, they may be answered by the [LLVM GitHub User Guide](https://llvm.org/docs/GitHub.html). You can also ask questions in a comment on this PR, on the [LLVM Discord](https://discord.com/invite/xS7Z362) or on the [forums](https://discourse.llvm.org/). https://github.com/llvm/llvm-project/pull/78200 ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang] Warning for incorrect useof 'pure' attribute (PR #78200)
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 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; +def warn_pure_attr_on_cxx_constructor : Warning< + "constructor cannot be 'pure' (undefined behavior)">, + InGroup; +def warn_pure_function_returns_void : Warning< + "'pure' attribute on function returning 'void'">, + InGroup; + 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() || NewFD->hasAttr()) { +if (isa_and_nonnull(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 00..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)}} +}; ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits