// 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
// 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);
// 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>
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.
+};
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)) {}; } };
}