summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaCXX/friend.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2019-01-07 06:00:46 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2019-01-07 06:00:46 +0000
commit8ce732b46f5570d21f0e92ea783387b2e5a3b846 (patch)
tree3cf8aefe6223556ba47b2d07890d3bce1301252f /clang/test/SemaCXX/friend.cpp
parent1ac0839098029ce987ce89f0a8c3faf380e50bd1 (diff)
downloadbcm5719-llvm-8ce732b46f5570d21f0e92ea783387b2e5a3b846.tar.gz
bcm5719-llvm-8ce732b46f5570d21f0e92ea783387b2e5a3b846.zip
DR674, PR38883, PR40238: Qualified friend lookup should look for a
template specialization if there is no matching non-template function. This exposed a couple of related bugs: - we would sometimes substitute into a friend template instead of a suitable non-friend declaration; this would now crash because we'd decide the specialization of the friend is a redeclaration of itself - ADL failed to properly handle the case where an invisible local extern declaration redeclares an invisible friend Both are fixed herein: in particular, we now never make invisible friends or local extern declarations visible to name lookup unless they are the only declaration of the entity. (We already mostly did this for local extern declarations.) llvm-svn: 350505
Diffstat (limited to 'clang/test/SemaCXX/friend.cpp')
-rw-r--r--clang/test/SemaCXX/friend.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/clang/test/SemaCXX/friend.cpp b/clang/test/SemaCXX/friend.cpp
index 61e96922f6d..822b1de39a1 100644
--- a/clang/test/SemaCXX/friend.cpp
+++ b/clang/test/SemaCXX/friend.cpp
@@ -162,7 +162,7 @@ namespace test9 {
class C {
};
struct A {
- friend void C::f(int, int, int) {} // expected-error {{no function named 'f' with type 'void (int, int, int)' was found in the specified scope}}
+ friend void C::f(int, int, int) {} // expected-error {{friend function definition cannot be qualified with 'C::'}}
};
}
@@ -230,6 +230,10 @@ namespace test10 {
friend void f10_d(X);
};
+ struct W {
+ friend void f10_d(W);
+ };
+
void g(X x, Y y, Z z) {
f10_d(); // expected-error {{undeclared identifier}}
::test10::f10_d(); // expected-error {{no member named 'f10_d'}}
@@ -245,14 +249,13 @@ namespace test10 {
::test10::f10_d(z); // expected-error {{no type named 'f10_d'}}
}
- void local_externs(X x, Y y) {
- extern void f10_d();
- extern void f10_d(X);
+ void local_externs(W w, X x, Y y) {
+ extern void f10_d(); // expected-note {{candidate}}
+ extern void f10_d(X); // expected-note {{candidate}}
f10_d();
f10_d(x);
- // FIXME: This lookup should fail, because the local extern declaration
- // should suppress ADL.
f10_d(y);
+ f10_d(w); // expected-error {{no matching}}
{
int f10_d;
f10_d(); // expected-error {{not a function}}
@@ -402,12 +405,27 @@ namespace PR33222 {
};
Y<float> yf; // expected-note {{instantiation}}
- int h();
+ int h(); // expected-note {{previous}}
template<typename T> struct Z {
- // FIXME: The note here should point at the non-friend declaration, not the
- // instantiation in Z<int>.
- friend T h(); // expected-error {{return type}} expected-note {{previous}}
+ friend T h(); // expected-error {{return type}}
};
Z<int> zi;
Z<float> zf; // expected-note {{instantiation}}
}
+
+namespace qualified_friend_no_match {
+ void f(int); // expected-note {{type mismatch at 1st parameter}}
+ template<typename T> void f(T*); // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}}
+ struct X {
+ friend void qualified_friend_no_match::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in namespace 'qualified_friend_no_match'}}
+ friend void qualified_friend_no_match::g(); // expected-error {{friend declaration of 'g' does not match any declaration in namespace 'qualified_friend_no_match'}}
+ };
+
+ struct Y {
+ void f(int); // expected-note {{type mismatch at 1st parameter}}
+ template<typename T> void f(T*); // expected-note {{could not match 'type-parameter-0-0 *' against 'double'}}
+ };
+ struct Z {
+ friend void Y::f(double); // expected-error {{friend declaration of 'f' does not match any declaration in 'qualified_friend_no_match::Y'}}
+ };
+}
OpenPOWER on IntegriCloud