Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Parse/ParseCXXInlineMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
SkipUntil(tok::semi);
}

Decl *PrevDecl = FnD->getPreviousDecl();
if (isa_and_present<FunctionDecl>(PrevDecl) &&
PrevDecl->getLexicalDeclContext() == FnD->getLexicalDeclContext()) {
Actions.CheckForFunctionRedefinition(FnD->getAsFunction(),
cast<FunctionDecl>(PrevDecl));
}

return FnD;
}

Expand Down
22 changes: 9 additions & 13 deletions clang/test/SemaCXX/cxx2c-delete-with-message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Loading