https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/136717
>From cca0eacad86036539b41971794cc2ee0d1e2d577 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Tue, 22 Apr 2025 18:35:46 +0300 Subject: [PATCH 1/2] [Clang] diagnose deleted/defaulted redeclaration of defined friend functions --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Parse/ParseCXXInlineMethods.cpp | 7 ++++++ .../SemaCXX/cxx2c-delete-with-message.cpp | 22 ++++++++----------- 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 5ccd346a93b4f..4362c23ce4058 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -462,6 +462,8 @@ Bug Fixes in This Version - Fixed a crash when ``#embed`` appears as a part of a failed constant evaluation. The crashes were happening during diagnostics emission due to unimplemented statement printer. (#GH132641) +- Clang now correctly diagnoses the deleted/defaulted redeclaration of defined + friend functions. (#GH135680) Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index b1064eb02b907..ab19c4d6dd706 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -142,6 +142,13 @@ NamedDecl *Parser::ParseCXXInlineMethodDef( SkipUntil(tok::semi); } + Decl *PrevDecl = FnD->getPreviousDecl(); + if (PrevDecl && isa<FunctionDecl>(PrevDecl) && + PrevDecl->getLexicalDeclContext() == FnD->getLexicalDeclContext()) { + Actions.CheckForFunctionRedefinition(FnD->getAsFunction(), + cast<FunctionDecl>(PrevDecl)); + } + return FnD; } diff --git a/clang/test/SemaCXX/cxx2c-delete-with-message.cpp b/clang/test/SemaCXX/cxx2c-delete-with-message.cpp index 5609da18c05aa..e4a68bdcf2a4d 100644 --- a/clang/test/SemaCXX/cxx2c-delete-with-message.cpp +++ b/clang/test/SemaCXX/cxx2c-delete-with-message.cpp @@ -274,26 +274,22 @@ void operators() { namespace gh135506 { struct a { - // FIXME: We currently don't diagnose these invalid redeclarations if the - // second declaration is defaulted or deleted. This probably needs to be - // handled in ParseCXXInlineMethodDef() after parsing the defaulted/deleted - // body. - friend consteval int f() { return 3; } - friend consteval int f() = delete("foo"); + friend consteval int f() { return 3; } // expected-note {{previous definition is here}} + friend consteval int f() = delete("foo"); // expected-error {{redefinition of 'f'}} - friend consteval int g() { return 3; } - friend consteval int g() = delete; + friend consteval int g() { return 3; } // expected-note {{previous definition is here}} + friend consteval int g() = delete; // expected-error {{redefinition of 'g'}} - friend int h() { return 3; } - friend int h() = delete; + friend int h() { return 3; } // expected-note {{previous definition is here}} + friend int h() = delete; // expected-error {{redefinition of 'h'}} - friend consteval int i() = delete; // expected-note {{previous definition is here}} + friend consteval int i() = delete; // expected-note {{previous definition is here}} friend consteval int i() { return 3; } // expected-error {{redefinition of 'i'}} }; struct b { - friend consteval bool operator==(b, b) { return true; } // expected-note {{previous declaration is here}} - friend consteval bool operator==(b, b) = default; // expected-error {{defaulting this equality comparison operator is not allowed because it was already declared outside the class}} + friend consteval bool operator==(b, b) { return true; } // expected-note {{previous definition is here}} + friend consteval bool operator==(b, b) = default; // expected-error {{redefinition of 'operator=='}} }; struct c { >From 3efff6ca1726eb4b20ad801a8f55130b8bc38780 Mon Sep 17 00:00:00 2001 From: Oleksandr Tarasiuk <oleksandr.taras...@outlook.com> Date: Tue, 22 Apr 2025 19:02:01 +0300 Subject: [PATCH 2/2] use isa_and_present helper --- clang/lib/Parse/ParseCXXInlineMethods.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index ab19c4d6dd706..5f8ef891dd06f 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -143,7 +143,7 @@ NamedDecl *Parser::ParseCXXInlineMethodDef( } Decl *PrevDecl = FnD->getPreviousDecl(); - if (PrevDecl && isa<FunctionDecl>(PrevDecl) && + if (isa_and_present<FunctionDecl>(PrevDecl) && PrevDecl->getLexicalDeclContext() == FnD->getLexicalDeclContext()) { Actions.CheckForFunctionRedefinition(FnD->getAsFunction(), cast<FunctionDecl>(PrevDecl)); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits