shafik updated this revision to Diff 544960.
shafik marked an inline comment as done.
shafik added a comment.

- Updated so that we ignore ambiguous overload candidate if the name lookup was 
also ambiguous.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D155387/new/

https://reviews.llvm.org/D155387

Files:
  clang/include/clang/Sema/Lookup.h
  clang/lib/Sema/SemaOverload.cpp
  clang/lib/Sema/SemaTemplate.cpp
  clang/test/CXX/class.derived/class.member.lookup/gh22413.cpp
  clang/test/CXX/class.derived/class.member.lookup/p11.cpp
  clang/test/SemaCXX/arrow-operator.cpp

Index: clang/test/SemaCXX/arrow-operator.cpp
===================================================================
--- clang/test/SemaCXX/arrow-operator.cpp
+++ clang/test/SemaCXX/arrow-operator.cpp
@@ -4,11 +4,13 @@
 };
 
 struct A {
-  T* operator->(); // expected-note{{candidate function}}
+  T* operator->();
+                   // expected-note@-1 {{member found by ambiguous name lookup}}
 };
 
 struct B {
-  T* operator->(); // expected-note{{candidate function}}
+  T* operator->();
+                   // expected-note@-1 {{member found by ambiguous name lookup}}
 };
 
 struct C : A, B {
@@ -19,7 +21,8 @@
 struct E; // expected-note {{forward declaration of 'E'}}
 
 void f(C &c, D& d, E& e) {
-  c->f(); // expected-error{{use of overloaded operator '->' is ambiguous}}
+  c->f();
+          // expected-error@-1 {{member 'operator->' found in multiple base classes of different types}}
   d->f();
   e->f(); // expected-error{{incomplete definition of type}}
 }
Index: clang/test/CXX/class.derived/class.member.lookup/p11.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/class.derived/class.member.lookup/p11.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct B1 {
+  void f();
+  static void f(int);
+  int i; // expected-note 2{{member found by ambiguous name lookup}}
+};
+struct B2 {
+  void f(double);
+};
+struct I1: B1 { };
+struct I2: B1 { };
+
+struct D: I1, I2, B2 {
+  using B1::f;
+  using B2::f;
+  void g() {
+    f(); // expected-error {{ambiguous conversion from derived class 'D' to base class 'B1'}}
+    f(0); // ok
+    f(0.0); // ok
+    // FIXME next line should be well-formed
+    int B1::* mpB1 = &D::i; // expected-error {{non-static member 'i' found in multiple base-class subobjects of type 'B1'}}
+    int D::* mpD = &D::i; // expected-error {{non-static member 'i' found in multiple base-class subobjects of type 'B1'}}
+  }
+};
Index: clang/test/CXX/class.derived/class.member.lookup/gh22413.cpp
===================================================================
--- /dev/null
+++ clang/test/CXX/class.derived/class.member.lookup/gh22413.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A {
+  void operator()(int); // expected-note {{member found by ambiguous name lookup}}
+  void f(int); // expected-note {{member found by ambiguous name lookup}}
+};
+struct B {
+  void operator()(); // expected-note {{member found by ambiguous name lookup}}
+  void f() {} // expected-note {{member found by ambiguous name lookup}}
+};
+
+struct C : A, B {};
+
+int f() {
+    C c;
+    c(); // expected-error {{member 'operator()' found in multiple base classes of different types}}
+    c.f(10); //expected-error {{member 'f' found in multiple base classes of different types}}
+    return 0;
+}
Index: clang/lib/Sema/SemaTemplate.cpp
===================================================================
--- clang/lib/Sema/SemaTemplate.cpp
+++ clang/lib/Sema/SemaTemplate.cpp
@@ -593,7 +593,7 @@
       //     postfix-expression and does not name a class template, the name
       //     found in the class of the object expression is used, otherwise
       FoundOuter.clear();
-    } else if (!Found.isSuppressingDiagnostics()) {
+    } else if (!Found.isSuppressingAmbiguousDiagnostics()) {
       //   - if the name found is a class template, it must refer to the same
       //     entity as the one found in the class of the object expression,
       //     otherwise the program is ill-formed.
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -949,7 +949,7 @@
     LookupResult Members(S, NotEqOp, OpLoc,
                          Sema::LookupNameKind::LookupMemberName);
     S.LookupQualifiedName(Members, RHSRec->getDecl());
-    Members.suppressDiagnostics();
+    Members.suppressAccessDiagnostics();
     for (NamedDecl *Op : Members)
       if (FunctionsCorrespond(S.Context, EqFD, Op->getAsFunction()))
         return false;
@@ -960,7 +960,7 @@
                           Sema::LookupNameKind::LookupOperatorName);
   S.LookupName(NonMembers,
                S.getScopeForContext(EqFD->getEnclosingNamespaceContext()));
-  NonMembers.suppressDiagnostics();
+  NonMembers.suppressAccessDiagnostics();
   for (NamedDecl *Op : NonMembers) {
     auto *FD = Op->getAsFunction();
     if(auto* UD = dyn_cast<UsingShadowDecl>(Op))
@@ -7941,7 +7941,7 @@
 
     LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName);
     LookupQualifiedName(Operators, T1Rec->getDecl());
-    Operators.suppressDiagnostics();
+    Operators.suppressAccessDiagnostics();
 
     for (LookupResult::iterator Oper = Operators.begin(),
                                 OperEnd = Operators.end();
@@ -14927,7 +14927,7 @@
   const auto *Record = Object.get()->getType()->castAs<RecordType>();
   LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName);
   LookupQualifiedName(R, Record->getDecl());
-  R.suppressDiagnostics();
+  R.suppressAccessDiagnostics();
 
   for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
        Oper != OperEnd; ++Oper) {
@@ -15007,12 +15007,13 @@
     break;
   }
   case OR_Ambiguous:
-    CandidateSet.NoteCandidates(
-        PartialDiagnosticAt(Object.get()->getBeginLoc(),
-                            PDiag(diag::err_ovl_ambiguous_object_call)
-                                << Object.get()->getType()
-                                << Object.get()->getSourceRange()),
-        *this, OCD_AmbiguousCandidates, Args);
+    if (!R.isAmbiguous())
+      CandidateSet.NoteCandidates(
+          PartialDiagnosticAt(Object.get()->getBeginLoc(),
+                              PDiag(diag::err_ovl_ambiguous_object_call)
+                                  << Object.get()->getType()
+                                  << Object.get()->getSourceRange()),
+          *this, OCD_AmbiguousCandidates, Args);
     break;
 
   case OR_Deleted:
@@ -15175,7 +15176,7 @@
 
   LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName);
   LookupQualifiedName(R, Base->getType()->castAs<RecordType>()->getDecl());
-  R.suppressDiagnostics();
+  R.suppressAccessDiagnostics();
 
   for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
        Oper != OperEnd; ++Oper) {
@@ -15216,11 +15217,12 @@
     return ExprError();
   }
   case OR_Ambiguous:
-    CandidateSet.NoteCandidates(
-        PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary)
-                                       << "->" << Base->getType()
-                                       << Base->getSourceRange()),
-        *this, OCD_AmbiguousCandidates, Base);
+    if (!R.isAmbiguous())
+      CandidateSet.NoteCandidates(
+          PartialDiagnosticAt(OpLoc, PDiag(diag::err_ovl_ambiguous_oper_unary)
+                                         << "->" << Base->getType()
+                                         << Base->getSourceRange()),
+          *this, OCD_AmbiguousCandidates, Base);
     return ExprError();
 
   case OR_Deleted:
Index: clang/include/clang/Sema/Lookup.h
===================================================================
--- clang/include/clang/Sema/Lookup.h
+++ clang/include/clang/Sema/Lookup.h
@@ -148,20 +148,22 @@
       : SemaPtr(&SemaRef), NameInfo(NameInfo), LookupKind(LookupKind),
         Redecl(Redecl != Sema::NotForRedeclaration),
         ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
-        Diagnose(Redecl == Sema::NotForRedeclaration) {
+        DiagnoseAccess(Redecl == Sema::NotForRedeclaration),
+        DiagnoseAmbiguous(Redecl == Sema::NotForRedeclaration) {
     configure();
   }
 
   // TODO: consider whether this constructor should be restricted to take
   // as input a const IdentifierInfo* (instead of Name),
   // forcing other cases towards the constructor taking a DNInfo.
-  LookupResult(Sema &SemaRef, DeclarationName Name,
-               SourceLocation NameLoc, Sema::LookupNameKind LookupKind,
+  LookupResult(Sema &SemaRef, DeclarationName Name, SourceLocation NameLoc,
+               Sema::LookupNameKind LookupKind,
                Sema::RedeclarationKind Redecl = Sema::NotForRedeclaration)
       : SemaPtr(&SemaRef), NameInfo(Name, NameLoc), LookupKind(LookupKind),
         Redecl(Redecl != Sema::NotForRedeclaration),
         ExternalRedecl(Redecl == Sema::ForExternalRedeclaration),
-        Diagnose(Redecl == Sema::NotForRedeclaration) {
+        DiagnoseAccess(Redecl == Sema::NotForRedeclaration),
+        DiagnoseAmbiguous(Redecl == Sema::NotForRedeclaration) {
     configure();
   }
 
@@ -192,12 +194,14 @@
         Redecl(std::move(Other.Redecl)),
         ExternalRedecl(std::move(Other.ExternalRedecl)),
         HideTags(std::move(Other.HideTags)),
-        Diagnose(std::move(Other.Diagnose)),
+        DiagnoseAccess(std::move(Other.DiagnoseAccess)),
+        DiagnoseAmbiguous(std::move(Other.DiagnoseAmbiguous)),
         AllowHidden(std::move(Other.AllowHidden)),
         Shadowed(std::move(Other.Shadowed)),
         TemplateNameLookup(std::move(Other.TemplateNameLookup)) {
     Other.Paths = nullptr;
-    Other.Diagnose = false;
+    Other.DiagnoseAccess = false;
+    Other.DiagnoseAmbiguous = false;
   }
 
   LookupResult &operator=(LookupResult &&Other) {
@@ -215,17 +219,22 @@
     Redecl = std::move(Other.Redecl);
     ExternalRedecl = std::move(Other.ExternalRedecl);
     HideTags = std::move(Other.HideTags);
-    Diagnose = std::move(Other.Diagnose);
+    DiagnoseAccess = std::move(Other.DiagnoseAccess);
+    DiagnoseAmbiguous = std::move(Other.DiagnoseAmbiguous);
     AllowHidden = std::move(Other.AllowHidden);
     Shadowed = std::move(Other.Shadowed);
     TemplateNameLookup = std::move(Other.TemplateNameLookup);
     Other.Paths = nullptr;
-    Other.Diagnose = false;
+    Other.DiagnoseAccess = false;
+    Other.DiagnoseAmbiguous = false;
     return *this;
   }
 
   ~LookupResult() {
-    if (Diagnose) diagnose();
+    if (DiagnoseAccess)
+      diagnoseAccess();
+    if (DiagnoseAmbiguous)
+      diagnoseAmbiguous();
     if (Paths) deletePaths(Paths);
   }
 
@@ -607,13 +616,20 @@
   /// Suppress the diagnostics that would normally fire because of this
   /// lookup.  This happens during (e.g.) redeclaration lookups.
   void suppressDiagnostics() {
-    Diagnose = false;
+    DiagnoseAccess = false;
+    DiagnoseAmbiguous = false;
   }
 
-  /// Determines whether this lookup is suppressing diagnostics.
-  bool isSuppressingDiagnostics() const {
-    return !Diagnose;
-  }
+  /// Suppress the diagnostics that would normally fire because of this
+  /// lookup due to access control violations.
+  void suppressAccessDiagnostics() { DiagnoseAccess = false; }
+
+  /// Determines whether this lookup is suppressing access control diagnostics.
+  bool isSuppressingAccessDiagnostics() const { return !DiagnoseAccess; }
+
+  /// Determines whether this lookup is suppressing ambiguous lookup
+  /// diagnostics.
+  bool isSuppressingAmbiguousDiagnostics() const { return !DiagnoseAmbiguous; }
 
   /// Sets a 'context' source range.
   void setContextRange(SourceRange SR) {
@@ -726,11 +742,14 @@
   }
 
 private:
-  void diagnose() {
+  void diagnoseAccess() {
+    if (isClassLookup() && getSema().getLangOpts().AccessControl)
+      getSema().CheckLookupAccess(*this);
+  }
+
+  void diagnoseAmbiguous() {
     if (isAmbiguous())
       getSema().DiagnoseAmbiguousLookup(*this);
-    else if (isClassLookup() && getSema().getLangOpts().AccessControl)
-      getSema().CheckLookupAccess(*this);
   }
 
   void setAmbiguous(AmbiguityKind AK) {
@@ -776,7 +795,8 @@
   ///   are present
   bool HideTags = true;
 
-  bool Diagnose = false;
+  bool DiagnoseAccess = false;
+  bool DiagnoseAmbiguous = false;
 
   /// True if we should allow hidden declarations to be 'visible'.
   bool AllowHidden = false;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to