From f3c1f0e13614d384f77b2b1fdea386c74c407d0f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 20 Nov 2009 00:59:20 +0000 Subject: [PATCH] When we have a non-dependent expression such as A::f that occurs within a non-static member function with a type-dependent "this", don't consider this to be a case for introduction of an implicit "(*this)." to refer to a specific member function unless we know (at template definition time) that A is a base class of *this. There is some disagreement here between GCC, EDG, and Clang about the handling of this case. I believe that Clang now has the correct, literal interpretation of the standard, but have asked for clarification (c++std-core-15483). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@89425 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaExprCXX.cpp | 5 ----- test/SemaTemplate/instantiate-method.cpp | 21 ++++++++++++++++++++- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 209d3069ca..6f0cb8a270 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -2335,11 +2335,6 @@ bool Sema::isImplicitMemberReference(const CXXScopeSpec *SS, NamedDecl *D, // class. If not, this isn't an implicit member reference. ThisType = MD->getThisType(Context); - // If the type of "this" is dependent, we can't tell if the member is in a - // base class or not, so treat this as a dependent implicit member reference. - if (ThisType->isDependentType()) - return true; - QualType CtxType = Context.getTypeDeclType(cast(Ctx)); QualType ClassType = Context.getTypeDeclType(cast(MD->getParent())); diff --git a/test/SemaTemplate/instantiate-method.cpp b/test/SemaTemplate/instantiate-method.cpp index df1e1d964e..a82e84d36c 100644 --- a/test/SemaTemplate/instantiate-method.cpp +++ b/test/SemaTemplate/instantiate-method.cpp @@ -84,6 +84,8 @@ int *a(A0 &x0, A1 &x1) { struct X0Base { int &f(); + int& g(int); + static double &g(double); }; template @@ -92,9 +94,26 @@ struct X0 : X0Base { template struct X1 : X0 { - int &f2() { return X0Base::f(); } + int &f2() { + return X0Base::f(); // expected-error{{call to non-static member function without an object argument}} + } }; void test_X1(X1 x1i) { int &ir = x1i.f2(); } + +template +struct X2 : X0Base, U { + int &f2() { return X0Base::f(); } +}; + +template +struct X3 { + void test(T x) { + double& d1 = X0Base::g(x); + } +}; + + +template struct X3; -- 2.50.1