]> granicus.if.org Git - clang/commitdiff
Diagnose non-dependent qualified friend function template declarations
authorRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 2 May 2019 00:49:05 +0000 (00:49 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Thu, 2 May 2019 00:49:05 +0000 (00:49 +0000)
that don't match any existing declaration. Don't get confused and treat
such declarations as template *specializations*.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@359746 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaOverload.cpp
test/SemaCXX/friend-template-redecl.cpp
test/SemaCXX/lambda-expressions.cpp

index 33ccdf0bba74133b8fe1cc48ffbd60112f24961e..a97e3573b9bac42614ac9d51eaf39632a4ebb8b1 100644 (file)
@@ -9086,8 +9086,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
         // nothing will diagnose that error later.
         if (isFriend &&
             (D.getCXXScopeSpec().getScopeRep()->isDependent() ||
-             (!Previous.empty() && (TemplateParamLists.size() ||
-                                    CurContext->isDependentContext())))) {
+             (!Previous.empty() && CurContext->isDependentContext()))) {
           // ignore these
         } else {
           // The user tried to provide an out-of-line definition for a
index 73f3e75c8051aa391bdbca38e377929ac2dd5c8d..2b0467fa8636fbfbfc99b119e9812b0525367b6a 100644 (file)
@@ -1056,6 +1056,7 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
   // third bullet. If the type of the friend is dependent, skip this lookup
   // until instantiation.
   if (New->getFriendObjectKind() && New->getQualifier() &&
+      !New->getDescribedFunctionTemplate() &&
       !New->getDependentSpecializationInfo() &&
       !New->getType()->isDependentType()) {
     LookupResult TemplateSpecResult(LookupResult::Temporary, Old);
index 3e05964fb28823bff9ea1f4fa84cb0a2d32d5f2f..4ee03c6f6387f7415c89f14f217a0d6a25b8ea72 100644 (file)
@@ -1,7 +1,5 @@
 // RUN: %clang_cc1 -std=c++17 -verify -emit-llvm-only %s
 
-// expected-no-diagnostics
-
 template <class T> void bar(const T &t) { foo(t); }
 
 template <class>
@@ -18,3 +16,11 @@ void f() {
   foo(x);
   bar(x);
 }
+
+template<typename T> void droid();
+struct X {
+  template<typename T> friend void ::droid();
+  template<int N> friend void ::droid(); // expected-error {{does not match}}
+  // FIXME: We should produce a note for the above candidate explaining why
+  // it's not the droid we're looking for.
+};
index 4565345fc665f6f06e1ec9ec56ca6deec695630a..1833400be3d1405919068e4175de25a0c029f7c2 100644 (file)
@@ -586,25 +586,30 @@ namespace PR25627_dont_odr_use_local_consts {
 
 namespace ConversionOperatorDoesNotHaveDeducedReturnType {
   auto x = [](int){};
-  auto y = [](auto) -> void {};
+  auto y = [](auto &v) -> void { v.n = 0; };
   using T = decltype(x);
   using U = decltype(y);
   using ExpectedTypeT = void (*)(int);
   template<typename T>
-    using ExpectedTypeU = void (*)(T);
+    using ExpectedTypeU = void (*)(T&);
 
   struct X {
+    friend auto T::operator()(int) const;
     friend T::operator ExpectedTypeT() const;
 
-    // Formally, this is invalid, because the return type of the conversion
-    // function for a generic lambda expression is an unspecified decltype
-    // type, which this should not match. However, this declaration is
-    // functionally equivalent to that one, so we're permitted to choose to
-    // accept this.
+    // FIXME: The first of these should match. The second should not.
     template<typename T>
-      friend U::operator ExpectedTypeU<T>() const;
+      friend void U::operator()(T&) const; // expected-error {{does not match}}
+    template<typename T>
+      friend U::operator ExpectedTypeU<T>() const; // expected-error {{does not match}}
+
+  private:
+    int n;
   };
 
+  // Should be OK: lambda's call operator is a friend.
+  void use(X &x) { y(x); }
+
   // This used to crash in return type deduction for the conversion opreator.
   struct A { int n; void f() { +[](decltype(n)) {}; } };
 }