<div dir="ltr">(fixes PR20221)</div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jul 8, 2014 at 6:19 PM, Reid Kleckner <span dir="ltr"><<a href="mailto:rnk@google.com" target="_blank">rnk@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi rsmith,<br>
<br>
This fixes compilation errors about incomplete types used with WebKit's<br>
RefPtr template.  Simply an out of line constructor should not<br>
instantiate all inline and defaulted virtual methods.<br>
<br>
<a href="http://reviews.llvm.org/D4429" target="_blank">http://reviews.llvm.org/D4429</a><br>
<br>
Files:<br>
  lib/Sema/SemaExpr.cpp<br>
  test/SemaTemplate/virtual-member-functions.cpp<br>
<br>
Index: lib/Sema/SemaExpr.cpp<br>
===================================================================<br>
--- lib/Sema/SemaExpr.cpp<br>
+++ lib/Sema/SemaExpr.cpp<br>
@@ -11445,8 +11445,6 @@<br>
     } else if (Constructor->getInheritedConstructor()) {<br>
       DefineInheritingConstructor(Loc, Constructor);<br>
     }<br>
-<br>
-    MarkVTableUsed(Loc, Constructor->getParent());<br>
   } else if (CXXDestructorDecl *Destructor =<br>
                  dyn_cast<CXXDestructorDecl>(Func)) {<br>
     Destructor = cast<CXXDestructorDecl>(Destructor->getFirstDecl());<br>
Index: test/SemaTemplate/virtual-member-functions.cpp<br>
===================================================================<br>
--- test/SemaTemplate/virtual-member-functions.cpp<br>
+++ test/SemaTemplate/virtual-member-functions.cpp<br>
@@ -44,16 +44,16 @@<br>
<br>
 template<typename T><br>
 struct HasOutOfLineKey {<br>
-  HasOutOfLineKey() { }<br>
+  HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}<br>
   virtual T *f(float *fp);<br>
 };<br>
<br>
 template<typename T><br>
 T *HasOutOfLineKey<T>::f(float *fp) {<br>
   return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}<br>
 }<br>
<br>
-HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}<br>
+HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}<br>
<br>
 namespace std {<br>
   class type_info;<br>
@@ -102,3 +102,53 @@<br>
   Y* f(X<void>* x) { return dynamic_cast<Y*>(x); } // expected-note {{in instantiation of member function 'DynamicCast::X<void>::foo' requested here}}<br>
   Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }<br>
 }<br>
+<br>
+namespace avoid_using_vtable {<br>
+// We shouldn't emit the vtable for this code, in any ABI.  If we emit the<br>
+// vtable, we emit an implicit virtual dtor, which calls ~RefPtr, which requires<br>
+// a complete type for DeclaredOnly.<br>
+//<br>
+// Previously we would reference the vtable in the MS C++ ABI, even though we<br>
+// don't need to emit either the ctor or the dtor.  In the Itanium C++ ABI, the<br>
+// 'trace' method is the key function, so even though we use the vtable, we<br>
+// don't emit it.<br>
+<br>
+template <typename T><br>
+struct RefPtr {<br>
+  T *m_ptr;<br>
+  ~RefPtr() { m_ptr->deref(); }<br>
+};<br>
+struct DeclaredOnly;<br>
+struct Base {<br>
+  virtual ~Base();<br>
+};<br>
+<br>
+struct AvoidVTable : Base {<br>
+  RefPtr<DeclaredOnly> m_insertionStyle;<br>
+  virtual void trace();<br>
+  AvoidVTable();<br>
+};<br>
+// Don't call the dtor, because that will emit an implicit dtor, and require a<br>
+// complete type for DeclaredOnly.<br>
+void foo() { new AvoidVTable; }<br>
+}<br>
+<br>
+namespace vtable_uses_incomplete {<br>
+// Opposite of the previous test that avoids a vtable, this one tests that we<br>
+// use the vtable when the ctor is defined inline.<br>
+template <typename T><br>
+struct RefPtr {<br>
+  T *m_ptr;<br>
+  ~RefPtr() { m_ptr->deref(); }  // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}}<br>
+};<br>
+struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}}<br>
+struct Base {<br>
+  virtual ~Base();<br>
+};<br>
+<br>
+struct UsesVTable : Base {<br>
+  RefPtr<DeclaredOnly> m_insertionStyle;<br>
+  virtual void trace();<br>
+  UsesVTable() {} // expected-note {{in instantiation of member function 'vtable_uses_incomplete::RefPtr<vtable_uses_incomplete::DeclaredOnly>::~RefPtr' requested here}}<br>
+};<br>
+}<br>
<br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div>