Skip to content

Commit

Permalink
[clang] Fix assertion failure with deleted overloaded unary operators (
Browse files Browse the repository at this point in the history
…#78316)

When emitting notes related to wrong number of arguments do not consider
object argument.

Fixes #78314
  • Loading branch information
Fznamznon committed Jan 22, 2024
1 parent 6c47419 commit 11d1310
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 7 deletions.
2 changes: 2 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,8 @@ Bug Fixes in This Version
- Fix an issue with missing symbol definitions when the first coroutine
statement appears in a discarded ``if constexpr`` branch.
Fixes (`#78290 <https://github.com/llvm/llvm-project/issues/78290>`_)
- Fixed assertion failure with deleted overloaded unary operators.
Fixes (`#78314 <https://github.com/llvm/llvm-project/issues/78314>`_)

Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
9 changes: 7 additions & 2 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14332,12 +14332,17 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
return ExprError();

case OR_Deleted:
// CreateOverloadedUnaryOp fills the first element of ArgsArray with the
// object whose method was called. Later in NoteCandidates size of ArgsArray
// is passed further and it eventually ends up compared to number of
// function candidate parameters which never includes the object parameter,
// so slice ArgsArray to make sure apples are compared to apples.
CandidateSet.NoteCandidates(
PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_deleted_oper)
<< UnaryOperator::getOpcodeStr(Opc)
<< Input->getSourceRange()),
*this, OCD_AllCandidates, ArgsArray, UnaryOperator::getOpcodeStr(Opc),
OpLoc);
*this, OCD_AllCandidates, ArgsArray.drop_front(),
UnaryOperator::getOpcodeStr(Opc), OpLoc);
return ExprError();
}

Expand Down
57 changes: 52 additions & 5 deletions clang/test/SemaCXX/overloaded-operator.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx23 -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx23 -std=c++23 %s

class X { };

X operator+(X, X);
Expand Down Expand Up @@ -33,7 +35,9 @@ struct A {

A make_A();

bool operator==(A&, Z&); // expected-note 3{{candidate function}}
bool operator==(A&, Z&); // expected-note 3{{candidate function}} \
// cxx23-note 2{{candidate function}}


void h(A a, const A ac, Z z) {
make_A() == z; // expected-warning{{equality comparison result unused}}
Expand Down Expand Up @@ -68,7 +72,9 @@ struct E2 {
};

// C++ [over.match.oper]p3 - enum restriction.
float& operator==(E1, E2); // expected-note{{candidate function}}
float& operator==(E1, E2); // expected-note{{candidate function}} \
// cxx23-note{{candidate function}}


void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) {
float &f1 = (e1 == e2);
Expand All @@ -86,7 +92,8 @@ class pr5244_foo
};

bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}}
bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}}
bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}} \
// cxx23-note{{candidate function}}

enum pr5244_bar
{
Expand Down Expand Up @@ -130,7 +137,7 @@ struct SmartPtr {
};

void test_smartptr(SmartPtr ptr, const SmartPtr cptr,
const volatile SmartPtr cvptr) {
const volatile SmartPtr cvptr) { // cxx23-warning {{volatile-qualified parameter type 'const volatile SmartPtr' is deprecated}}
int &ir = *ptr;
long &lr = *cptr;
long &lr2 = *cvptr;
Expand Down Expand Up @@ -598,3 +605,43 @@ namespace B {
}
void g(B::X x) { A::f(x); }
}

namespace GH78314 {

class a {
public:
void operator--() = delete; // expected-note {{candidate function has been explicitly deleted}} \
// expected-note {{candidate function not viable: requires 0 arguments, but 1 was provided}}
void operator--(int) = delete; // expected-note {{candidate function has been explicitly deleted}} \
// expected-note {{candidate function not viable: requires 1 argument, but 0 were provided}}
};

class c {
void operator--(this c) = delete; //precxx23-error {{explicit object parameters are incompatible with C++ standards before C++2b}} \
// expected-note {{candidate function has been explicitly deleted}} \
// expected-note {{candidate function not viable: requires 0 non-object arguments, but 1 was provided}}
void operator--(this c, int) = delete; //precxx23-error {{explicit object parameters are incompatible with C++ standards before C++2b}} \
// expected-note {{candidate function has been explicitly deleted}} \
// expected-note {{candidate function not viable: requires 1 non-object argument, but 0 were provided}}
};

void foo() {
a aa;
--aa; // expected-error {{overload resolution selected deleted operator '--'}}
aa--; // expected-error {{overload resolution selected deleted operator '--'}}

c cc;
--cc; // expected-error {{overload resolution selected deleted operator '--'}}
cc--; // expected-error {{overload resolution selected deleted operator '--'}}
}

class b {
void operator++() = delete; // expected-note {{candidate function has been explicitly deleted}}
template <class> void operator++(int) { // expected-note {{function template not viable: requires 1 argument, but 0 were provided}}
b bb;
++bb; // expected-error {{overload resolution selected deleted operator '++'}}
}
};


}

0 comments on commit 11d1310

Please sign in to comment.