Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
8 changes: 8 additions & 0 deletions clang/lib/Parse/ParseCXXInlineMethods.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ NamedDecl *Parser::ParseCXXInlineMethodDef(
SkipUntil(tok::semi);
}

if (FunctionDecl *FD =
dyn_cast_if_present<FunctionDecl>(FnD->getPreviousDecl())) {
if (isa<CXXRecordDecl>(FD->getLexicalDeclContext()) ||
Actions.getDefaultedFunctionKind(FD).asComparison() ==
Sema::DefaultedComparisonKind::None)
Actions.CheckForFunctionRedefinition(FnD->getAsFunction(), FD);
}

return FnD;
}

Expand Down
47 changes: 25 additions & 22 deletions clang/test/SemaCXX/cxx2c-delete-with-message.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,31 +273,34 @@ 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 g() { return 3; }
friend consteval int g() = delete;

friend int h() { return 3; }
friend int h() = delete;

friend consteval int i() = delete; // expected-note {{previous definition is here}}
friend consteval int i() { return 3; } // expected-error {{redefinition of 'i'}}
struct s1 {
friend consteval int a() { return 3; } // expected-note {{previous definition is here}}
friend consteval int a() = delete("foo"); // expected-error {{redefinition of 'a'}}

friend consteval int b() { return 3; } // expected-note {{previous definition is here}}
friend consteval int b() = delete; // expected-error {{redefinition of 'b'}}

friend int c() { return 3; } // expected-note {{previous definition is here}}
friend int c() = delete; // expected-error {{redefinition of 'c'}}

friend consteval int d() = delete; // expected-note {{previous definition is here}}
friend consteval int d() { return 3; } // expected-error {{redefinition of 'd'}}
};

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}}
struct s2 {
friend consteval bool operator==(s2, s2) { return true; } // expected-note {{previous definition is here}}
friend consteval bool operator==(s2, s2) = default; // expected-error {{redefinition of 'operator=='}}
};

struct c {
friend consteval bool operator==(c, c) = default; // expected-note {{previous definition is here}}
friend consteval bool operator==(c, c) { return true; } // expected-error {{redefinition of 'operator=='}}
struct s3 {
friend consteval bool operator==(s3, s3) = default; // expected-note {{previous definition is here}}
friend consteval bool operator==(s3, s3) { return true; } // expected-error {{redefinition of 'operator=='}}
};

void e() {} // expected-note {{previous definition is here}}
struct s4 { friend void e() = delete; }; // expected-error {{redefinition of 'e'}}

struct s5 { friend void f() {} }; // expected-note {{previous definition is here}}
struct s6 { friend void f() = delete; }; // expected-error {{redefinition of 'f'}}

}
Loading