[clang] 11d1310 - [clang] Fix assertion failure with deleted overloaded unary operators (#78316)

via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 22 01:06:31 PST 2024


Author: Mariya Podchishchaeva
Date: 2024-01-22T10:06:26+01:00
New Revision: 11d1310b57a9f2defb4d65a35b90a69020c52e46

URL: https://github.com/llvm/llvm-project/commit/11d1310b57a9f2defb4d65a35b90a69020c52e46
DIFF: https://github.com/llvm/llvm-project/commit/11d1310b57a9f2defb4d65a35b90a69020c52e46.diff

LOG: [clang] Fix assertion failure with deleted overloaded unary operators (#78316)

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

Fixes https://github.com/llvm/llvm-project/issues/78314

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/Sema/SemaOverload.cpp
    clang/test/SemaCXX/overloaded-operator.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7c9f9ecca727a4..4888ffe6f4dfc8 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -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
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff  --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 697a1c0cfc404e..030878899b8122 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -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();
   }
 

diff  --git a/clang/test/SemaCXX/overloaded-operator.cpp b/clang/test/SemaCXX/overloaded-operator.cpp
index 83a7e65b43dd01..887848c29b83c5 100644
--- a/clang/test/SemaCXX/overloaded-operator.cpp
+++ b/clang/test/SemaCXX/overloaded-operator.cpp
@@ -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);
@@ -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}}
@@ -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);
@@ -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
 {
@@ -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;
@@ -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 '++'}}
+  }
+};
+
+
+}


        


More information about the cfe-commits mailing list