]> granicus.if.org Git - clang/commitdiff
When we have a non-dependent expression such as
authorDouglas Gregor <dgregor@apple.com>
Fri, 20 Nov 2009 00:59:20 +0000 (00:59 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 20 Nov 2009 00:59:20 +0000 (00:59 +0000)
  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
test/SemaTemplate/instantiate-method.cpp

index 209d3069cafeb4fab3ba27e3f9d742a1f5e3864e..6f0cb8a27007b5251c7d3573bc19be9c11246d18 100644 (file)
@@ -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<CXXRecordDecl>(Ctx));
   QualType ClassType
     = Context.getTypeDeclType(cast<CXXRecordDecl>(MD->getParent()));
index df1e1d964eb6d3196da9ed0965e36723a516cfca..a82e84d36c99e69eec3a030d04337196ca6e6b6e 100644 (file)
@@ -84,6 +84,8 @@ int *a(A0<int> &x0, A1<int> &x1) {
 
 struct X0Base {
   int &f();
+  int& g(int);
+  static double &g(double);
 };
 
 template<typename T>
@@ -92,9 +94,26 @@ struct X0 : X0Base {
 
 template<typename U>
 struct X1 : X0<U> {
-  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<int> x1i) {
   int &ir = x1i.f2();
 }
+
+template<typename U>
+struct X2 : X0Base, U {
+  int &f2() { return X0Base::f(); }
+};
+
+template<typename T>
+struct X3 {
+  void test(T x) {
+    double& d1 = X0Base::g(x);
+  }
+};
+
+
+template struct X3<double>;