cjdb updated this revision to Diff 445286.
cjdb edited the summary of this revision.
cjdb added a comment.

updates an inaccuracy in the commit message


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D129951

Files:
  clang/include/clang/AST/DeclBase.h
  clang/lib/AST/DeclBase.cpp
  clang/lib/Sema/SemaOverload.cpp
  clang/test/SemaCXX/disable-adl.cpp

Index: clang/test/SemaCXX/disable-adl.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/disable-adl.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+// expected-n...@disable-adl.cpp:* 2{{}}
+
+namespace std {
+  struct S1 {};
+  S1 inhibited(S1);
+
+  namespace ranges {
+    struct S2 {};
+    void hidden(S2);
+    int inhibited(S1);
+  }
+}
+
+void test_functions() {
+  hidden(std::ranges::S2{});
+  // expected-error@-1{{use of undeclared identifier 'hidden'; did you mean 'std::ranges::hidden'?}}
+
+  using namespace std::ranges;
+  int x = inhibited(std::S1{}); // no error
+}
+
+namespace std {
+  template<typename T>
+  S1 inhibited_template(T);
+
+  namespace ranges {
+    template<typename T>
+    void hidden_template(T);
+
+    template<typename T>
+    int inhibited_template(T);
+  }
+}
+
+void test_function_templates() {
+  hidden_template(std::ranges::S2{});
+  // expected-error@-1{{use of undeclared identifier 'hidden_template'; did you mean 'std::ranges::hidden_template'?}}
+
+  using namespace std::ranges;
+  int x = inhibited_template(std::S1{});
+}
+
+namespace std {
+  S1 inhibited_mixed(S1);
+
+  namespace ranges {
+    template<typename T>
+    int inhibited_mixed(T);
+  }
+}
+
+void test_mixed() {
+  using namespace std::ranges;
+  int x = inhibited_mixed(std::S1{});
+}
+
+// Should be covered by the hidden functions checks, but just to be sure.
+void test_ranges_hidden() {
+  {
+    std::S1 a = inhibited(std::S1{});
+    std::S1 b = inhibited_template(std::S1{});
+    std::S1 c = inhibited_mixed(std::S1{});
+  }
+  {
+    using namespace std;
+    std::S1 a = inhibited(std::S1{});
+    std::S1 b = inhibited_template(std::S1{});
+    std::S1 c = inhibited_mixed(std::S1{});
+  }
+}
+
+namespace std {
+  namespace ranges {
+    void operator-(S2);
+
+    struct hidden_friend_operator {
+      friend void operator-(hidden_friend_operator i, int) {}
+    };
+
+    struct hidden_friend_swap {
+      friend void swap(hidden_friend_swap, hidden_friend_swap) {}
+    };
+  }
+}
+
+void test_friends_and_operators() {
+  -std::ranges::S2{};                        // no error
+  std::ranges::hidden_friend_operator{} - 1; // no error
+
+  swap(std::ranges::hidden_friend_swap{}, std::ranges::hidden_friend_swap{});
+  // expected-error@-1{{use of undeclared identifier 'swap'}}
+}
Index: clang/lib/Sema/SemaOverload.cpp
===================================================================
--- clang/lib/Sema/SemaOverload.cpp
+++ clang/lib/Sema/SemaOverload.cpp
@@ -9452,6 +9452,12 @@
   for (ADLResult::iterator I = Fns.begin(), E = Fns.end(); I != E; ++I) {
     DeclAccessPair FoundDecl = DeclAccessPair::make(*I, AS_none);
 
+    // Functions in 'std::ranges' are hidden from ADL per [range.iter.ops]/2 and
+    // [algorithms.requirements]/2.
+    if ((*I)->isInStdRangesNamespace() &&
+        Name.getNameKind() == DeclarationName::NameKind::Identifier)
+      continue;
+
     if (FunctionDecl *FD = dyn_cast<FunctionDecl>(*I)) {
       if (ExplicitTemplateArgs)
         continue;
@@ -9650,7 +9656,7 @@
                                           const OverloadCandidate &Cand1,
                                           const OverloadCandidate &Cand2) {
   // FIXME: Per P2113R0 we also need to compare the template parameter lists
-  // when comparing template functions. 
+  // when comparing template functions.
   if (Cand1.Function && Cand2.Function && Cand1.Function->hasPrototype() &&
       Cand2.Function->hasPrototype()) {
     auto *PT1 = cast<FunctionProtoType>(Cand1.Function->getFunctionType());
@@ -12828,6 +12834,12 @@
                                CandidateSet, PartialOverloading,
                                /*KnownValid*/ true);
 
+  // Functions in 'std::ranges' inhibit ADL per [range.iter.ops]/2 and
+  // [algorithms.requirements]/2.
+  if (!ULE->decls().empty() && ULE->decls_begin()->isInStdRangesNamespace() &&
+      ULE->getName().getNameKind() == DeclarationName::NameKind::Identifier)
+    return;
+
   if (ULE->requiresADL())
     AddArgumentDependentLookupCandidates(ULE->getName(), ULE->getExprLoc(),
                                          Args, ExplicitTemplateArgs,
Index: clang/lib/AST/DeclBase.cpp
===================================================================
--- clang/lib/AST/DeclBase.cpp
+++ clang/lib/AST/DeclBase.cpp
@@ -396,6 +396,11 @@
   return DC && DC->isStdNamespace();
 }
 
+bool Decl::isInStdRangesNamespace() const {
+  const DeclContext *DC = getDeclContext();
+  return DC && DC->isStdRangesNamespace();
+}
+
 TranslationUnitDecl *Decl::getTranslationUnitDecl() {
   if (auto *TUD = dyn_cast<TranslationUnitDecl>(this))
     return TUD;
@@ -1149,6 +1154,19 @@
   return II && II->isStr("std");
 }
 
+bool DeclContext::isStdRangesNamespace() const {
+  if (!isNamespace())
+    return false;
+
+  const auto *ND = cast<NamespaceDecl>(this);
+  if (!ND->getParent()->isStdNamespace()) {
+    return false;
+  }
+
+  const IdentifierInfo *II = ND->getIdentifier();
+  return II && II->isStr("ranges");
+}
+
 bool DeclContext::isDependentContext() const {
   if (isFileContext())
     return false;
Index: clang/include/clang/AST/DeclBase.h
===================================================================
--- clang/include/clang/AST/DeclBase.h
+++ clang/include/clang/AST/DeclBase.h
@@ -465,6 +465,7 @@
   bool isInAnonymousNamespace() const;
 
   bool isInStdNamespace() const;
+  bool isInStdRangesNamespace() const;
 
   ASTContext &getASTContext() const LLVM_READONLY;
 
@@ -1986,6 +1987,7 @@
   bool isNamespace() const { return getDeclKind() == Decl::Namespace; }
 
   bool isStdNamespace() const;
+  bool isStdRangesNamespace() const;
 
   bool isInlineNamespace() const;
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D129951: ... Christopher Di Bella via Phabricator via cfe-commits
    • [PATCH] D129... Christopher Di Bella via Phabricator via cfe-commits
    • [PATCH] D129... Christopher Di Bella via Phabricator via cfe-commits
    • [PATCH] D129... Christopher Di Bella via Phabricator via cfe-commits
    • [PATCH] D129... Christopher Di Bella via Phabricator via cfe-commits
    • [PATCH] D129... Richard Smith - zygoloid via Phabricator via cfe-commits
    • [PATCH] D129... Christopher Di Bella via Phabricator via cfe-commits

Reply via email to