Itanium mangler: don't trip an assertion when unresolved members have implicit bases.
authorDouglas Gregor <dgregor@apple.com>
Thu, 21 May 2015 18:28:18 +0000 (18:28 +0000)
committerDouglas Gregor <dgregor@apple.com>
Thu, 21 May 2015 18:28:18 +0000 (18:28 +0000)
When we find a member of the current instantation, the base of the
unresolved member expression is implicit; use nullptr for such
bases. This is not a change in behavior: the AST already contains null
in such cases, so non-asserts builds do the right thing already. Fixes
rdar://problem/21020559.

llvm-svn: 237929

clang/lib/AST/ItaniumMangle.cpp
clang/test/CodeGenCXX/mangle-exprs.cpp

index 7acaf09..f281217 100644 (file)
@@ -2885,9 +2885,9 @@ recurse:
 
   case Expr::UnresolvedMemberExprClass: {
     const UnresolvedMemberExpr *ME = cast<UnresolvedMemberExpr>(E);
-    mangleMemberExpr(ME->getBase(), ME->isArrow(),
-                     ME->getQualifier(), nullptr, ME->getMemberName(),
-                     Arity);
+    mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(),
+                     ME->isArrow(), ME->getQualifier(), nullptr,
+                     ME->getMemberName(), Arity);
     if (ME->hasExplicitTemplateArgs())
       mangleTemplateArgs(ME->getExplicitTemplateArgs());
     break;
@@ -2896,8 +2896,9 @@ recurse:
   case Expr::CXXDependentScopeMemberExprClass: {
     const CXXDependentScopeMemberExpr *ME
       = cast<CXXDependentScopeMemberExpr>(E);
-    mangleMemberExpr(ME->getBase(), ME->isArrow(),
-                     ME->getQualifier(), ME->getFirstQualifierFoundInScope(),
+    mangleMemberExpr(ME->isImplicitAccess() ? nullptr : ME->getBase(),
+                     ME->isArrow(), ME->getQualifier(),
+                     ME->getFirstQualifierFoundInScope(),
                      ME->getMember(), Arity);
     if (ME->hasExplicitTemplateArgs())
       mangleTemplateArgs(ME->getExplicitTemplateArgs());
index ee2d546..ee7594b 100644 (file)
@@ -329,3 +329,15 @@ namespace test7 {
     fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_
   }
 }
+
+
+namespace test8 {
+  template <class>
+  struct X {
+    template<typename T> T foo() const { return 0; }
+    template <class T> auto bar() const -> decltype(foo<T>()) { return 0; }
+  };
+
+  // CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv
+  template int X<int>::bar<int>() const;
+}