[cfe-commits] r93510 - in /cfe/trunk: lib/Sema/Sema.h lib/Sema/SemaExpr.cpp lib/Sema/TreeTransform.h test/SemaTemplate/instantiate-member-expr.cpp

John McCall rjmccall at apple.com
Fri Jan 15 00:34:02 PST 2010


Author: rjmccall
Date: Fri Jan 15 02:34:02 2010
New Revision: 93510

URL: http://llvm.org/viewvc/llvm-project?rev=93510&view=rev
Log:
Don't repeat lookup when instantiating resolved member expressions.
Adjust BuildMemberReferenceExpr to perform the inheritance check on implicit
member accesses, which can arise from unqualified lookups and therefore may
reference decls from enclosing class scopes.

Fixes PR 5838.


Modified:
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaTemplate/instantiate-member-expr.cpp

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=93510&r1=93509&r2=93510&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Fri Jan 15 02:34:02 2010
@@ -1596,13 +1596,13 @@
                                             QualType BaseType,
                                             SourceLocation OpLoc, bool IsArrow,
                                             const CXXScopeSpec &SS,
+                                            NamedDecl *FirstQualifierInScope,
                                             LookupResult &R,
                                  const TemplateArgumentListInfo *TemplateArgs);
 
   OwningExprResult LookupMemberExpr(LookupResult &R, Expr *&Base,
                                     bool &IsArrow, SourceLocation OpLoc,
                                     const CXXScopeSpec &SS,
-                                    NamedDecl *FirstQualifierInScope,
                                     DeclPtrTy ObjCImpDecl);
 
   bool CheckQualifiedMemberReference(Expr *BaseExpr, QualType BaseType,

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=93510&r1=93509&r2=93510&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jan 15 02:34:02 2010
@@ -1397,7 +1397,9 @@
   return BuildMemberReferenceExpr(ExprArg(*this, This), ThisType,
                                   /*OpLoc*/ SourceLocation(),
                                   /*IsArrow*/ true,
-                                  SS, R, TemplateArgs);
+                                  SS,
+                                  /*FirstQualifierInScope*/ 0,
+                                  R, TemplateArgs);
 }
 
 bool Sema::UseArgumentDependentLookup(const CXXScopeSpec &SS,
@@ -2471,8 +2473,7 @@
   } else {
     OwningExprResult Result =
       LookupMemberExpr(R, Base, IsArrow, OpLoc,
-                       SS, FirstQualifierInScope,
-                       /*ObjCImpDecl*/ DeclPtrTy());
+                       SS, /*ObjCImpDecl*/ DeclPtrTy());
 
     if (Result.isInvalid()) {
       Owned(Base);
@@ -2484,13 +2485,15 @@
   }
 
   return BuildMemberReferenceExpr(ExprArg(*this, Base), BaseType,
-                                  OpLoc, IsArrow, SS, R, TemplateArgs);
+                                  OpLoc, IsArrow, SS, FirstQualifierInScope,
+                                  R, TemplateArgs);
 }
 
 Sema::OwningExprResult
 Sema::BuildMemberReferenceExpr(ExprArg Base, QualType BaseExprType,
                                SourceLocation OpLoc, bool IsArrow,
                                const CXXScopeSpec &SS,
+                               NamedDecl *FirstQualifierInScope,
                                LookupResult &R,
                          const TemplateArgumentListInfo *TemplateArgs) {
   Expr *BaseExpr = Base.takeAs<Expr>();
@@ -2520,11 +2523,17 @@
     return ExprError();
   }
 
-  // Diagnose qualified lookups that find only declarations from a
-  // non-base type.  Note that it's okay for lookup to find
-  // declarations from a non-base type as long as those aren't the
-  // ones picked by overload resolution.
-  if (SS.isSet() && CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R))
+  // Diagnose lookups that find only declarations from a non-base
+  // type.  This is possible for either qualified lookups (which may
+  // have been qualified with an unrelated type) or implicit member
+  // expressions (which were found with unqualified lookup and thus
+  // may have come from an enclosing scope).  Note that it's okay for
+  // lookup to find declarations from a non-base type as long as those
+  // aren't the ones picked by overload resolution.
+  if ((SS.isSet() || !BaseExpr ||
+       (isa<CXXThisExpr>(BaseExpr) &&
+        cast<CXXThisExpr>(BaseExpr)->isImplicit())) &&
+      CheckQualifiedMemberReference(BaseExpr, BaseType, SS, R))
     return ExprError();
 
   // Construct an unresolved result if we in fact got an unresolved
@@ -2666,7 +2675,6 @@
 Sema::LookupMemberExpr(LookupResult &R, Expr *&BaseExpr,
                        bool &IsArrow, SourceLocation OpLoc,
                        const CXXScopeSpec &SS,
-                       NamedDecl *FirstQualifierInScope,
                        DeclPtrTy ObjCImpDecl) {
   assert(BaseExpr && "no base expression");
 
@@ -3101,7 +3109,7 @@
         << Property->getDeclName();          
 
       return LookupMemberExpr(Res, BaseExpr, IsArrow, OpLoc, SS,
-                              FirstQualifierInScope, ObjCImpDecl);
+                              ObjCImpDecl);
     }
 
     return ExprError(Diag(MemberLoc, diag::err_property_not_found)
@@ -3204,8 +3212,7 @@
       DecomposeTemplateName(R, Id);
     } else {
       Result = LookupMemberExpr(R, Base, IsArrow, OpLoc,
-                                SS, FirstQualifierInScope,
-                                ObjCImpDecl);
+                                SS, ObjCImpDecl);
 
       if (Result.isInvalid()) {
         Owned(Base);
@@ -3226,7 +3233,8 @@
     }
 
     Result = BuildMemberReferenceExpr(ExprArg(*this, Base), Base->getType(),
-                                      OpLoc, IsArrow, SS, R, TemplateArgs);
+                                      OpLoc, IsArrow, SS, FirstQualifierInScope,
+                                      R, TemplateArgs);
   }
 
   return move(Result);

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=93510&r1=93509&r2=93510&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri Jan 15 02:34:02 2010
@@ -975,12 +975,15 @@
 
     QualType BaseType = ((Expr*) Base.get())->getType();
 
-    // FIXME: wait, this is re-performing lookup?
+    LookupResult R(getSema(), Member->getDeclName(), MemberLoc,
+                   Sema::LookupMemberName);
+    R.addDecl(Member);
+    R.resolveKind();
+
     return getSema().BuildMemberReferenceExpr(move(Base), BaseType,
                                               OpLoc, isArrow,
                                               SS, FirstQualifierInScope,
-                                              Member->getDeclName(), MemberLoc,
-                                              ExplicitTemplateArgs);
+                                              R, ExplicitTemplateArgs);
   }
 
   /// \brief Build a new binary operator expression.
@@ -1561,6 +1564,7 @@
                                                bool IsArrow,
                                                NestedNameSpecifier *Qualifier,
                                                SourceRange QualifierRange,
+                                               NamedDecl *FirstQualifierInScope,
                                                LookupResult &R,
                                 const TemplateArgumentListInfo *TemplateArgs) {
     CXXScopeSpec SS;
@@ -1569,7 +1573,8 @@
 
     return SemaRef.BuildMemberReferenceExpr(move(BaseE), BaseType,
                                             OperatorLoc, IsArrow,
-                                            SS, R, TemplateArgs);
+                                            SS, FirstQualifierInScope,
+                                            R, TemplateArgs);
   }
 
   /// \brief Build a new Objective-C @encode expression.
@@ -3713,6 +3718,12 @@
   SourceLocation FakeOperatorLoc
     = SemaRef.PP.getLocForEndOfToken(E->getBase()->getSourceRange().getEnd());
 
+  // FIXME: to do this check properly, we will need to preserve the
+  // first-qualifier-in-scope here, just in case we had a dependent
+  // base (and therefore couldn't do the check) and a
+  // nested-name-qualifier (and therefore could do the lookup).
+  NamedDecl *FirstQualifierInScope = 0;
+
   return getDerived().RebuildMemberExpr(move(Base), FakeOperatorLoc,
                                         E->isArrow(),
                                         Qualifier,
@@ -3721,7 +3732,7 @@
                                         Member,
                                         (E->hasExplicitTemplateArgumentList()
                                            ? &TransArgs : 0),
-                                        0);
+                                        FirstQualifierInScope);
 }
 
 template<typename Derived>
@@ -5029,6 +5040,12 @@
       TransArgs.addArgument(Loc);
     }
   }
+
+  // FIXME: to do this check properly, we will need to preserve the
+  // first-qualifier-in-scope here, just in case we had a dependent
+  // base (and therefore couldn't do the check) and a
+  // nested-name-qualifier (and therefore could do the lookup).
+  NamedDecl *FirstQualifierInScope = 0;
   
   return getDerived().RebuildUnresolvedMemberExpr(move(Base),
                                                   BaseType,
@@ -5036,6 +5053,7 @@
                                                   Old->isArrow(),
                                                   Qualifier,
                                                   Old->getQualifierRange(),
+                                                  FirstQualifierInScope,
                                                   R,
                                               (Old->hasExplicitTemplateArgs()
                                                   ? &TransArgs : 0));

Modified: cfe/trunk/test/SemaTemplate/instantiate-member-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-member-expr.cpp?rev=93510&r1=93509&r2=93510&view=diff

==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-member-expr.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-member-expr.cpp Fri Jan 15 02:34:02 2010
@@ -25,3 +25,27 @@
 void f(GRExprEngine& Eng) {
    Eng.registerCheck(new RetainReleaseChecker); // expected-note {{in instantiation of function template specialization 'GRExprEngine::registerCheck<class RetainReleaseChecker>' requested here}}
 }
+
+// PR 5838
+namespace test1 {
+  template<typename T> struct A {
+    int a;
+  };
+
+  template<typename T> struct B : A<float>, A<T> {
+    void f() {
+      a = 0; // should not be ambiguous
+    }
+  };
+  template struct B<int>;
+
+  struct O {
+    int a;
+    template<typename T> struct B : A<T> {
+      void f() {
+        a = 0; // expected-error {{type 'struct test1::O' is not a direct or virtual base of ''B<int>''}}
+      }
+    };
+  };
+  template struct O::B<int>; // expected-note {{in instantiation}}
+}





More information about the cfe-commits mailing list