aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-04-14 00:46:47 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2011-04-14 00:46:47 +0000
commit0d8dc460ae02e29d0b2abb4d6d093736e2f920ea (patch)
tree436c2fb3d20a8c7129be1c2bacd588d287dd71ff
parentfb67ccd9da412d652d62e2ac9675b0f1b14fdc73 (diff)
When creating an implicit member expression through a qualified-id, check that the class
named by the nested-name-specifier is same or base of the class in which the member expression appears. It seems we also had an ill-formed test case, mon dieu! Fixes rdar://8576107. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129493 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaExpr.cpp18
-rw-r--r--test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp17
2 files changed, 26 insertions, 9 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index eb84cff999..8ccb9b8180 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -1318,12 +1318,24 @@ static IMAKind ClassifyImplicitMemberAccess(Sema &SemaRef,
return IMA_Error_StaticContext;
}
+ CXXRecordDecl *
+ contextClass = cast<CXXMethodDecl>(DC)->getParent()->getCanonicalDecl();
+
+ // [class.mfct.non-static]p3:
+ // ...is used in the body of a non-static member function of class X,
+ // if name lookup (3.4.1) resolves the name in the id-expression to a
+ // non-static non-type member of some class C [...]
+ // ...if C is not X or a base class of X, the class member access expression
+ // is ill-formed.
+ if (R.getNamingClass() &&
+ contextClass != R.getNamingClass()->getCanonicalDecl() &&
+ contextClass->isProvablyNotDerivedFrom(R.getNamingClass()))
+ return (hasNonInstance ? IMA_Mixed_Unrelated : IMA_Error_Unrelated);
+
// If we can prove that the current context is unrelated to all the
// declaring classes, it can't be an implicit member reference (in
// which case it's an error if any of those members are selected).
- if (IsProvablyNotDerivedFrom(SemaRef,
- cast<CXXMethodDecl>(DC)->getParent(),
- Classes))
+ if (IsProvablyNotDerivedFrom(SemaRef, contextClass, Classes))
return (hasNonInstance ? IMA_Mixed_Unrelated : IMA_Error_Unrelated);
return (hasNonInstance ? IMA_Mixed : IMA_Instance);
diff --git a/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
index c81e4ef1b1..9116e7146f 100644
--- a/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
+++ b/test/CXX/class/class.mfct/class.mfct.non-static/p3.cpp
@@ -35,17 +35,22 @@ namespace test1 {
struct A {
void foo(Opaque1); // expected-note {{candidate}}
void foo(Opaque2); // expected-note {{candidate}}
- void test();
};
struct B : A {
-
+ void test();
};
- void A::test() {
- B::foo(Opaque1());
- B::foo(Opaque2());
- B::foo(Opaque3()); // expected-error {{no matching member function}}
+ struct C1 : A { };
+ struct C2 : B { };
+
+ void B::test() {
+ A::foo(Opaque1());
+ A::foo(Opaque2());
+ A::foo(Opaque3()); // expected-error {{no matching member function}}
+
+ C1::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}}
+ C2::foo(Opaque1()); // expected-error {{call to non-static member function without an object argument}}
}
}