llvm-project/clang/test/SemaTemplate/virtual-member-functions.cpp

217 lines
6.4 KiB
C++
Raw Normal View History

// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify %s
// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -verify %s
// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -std=c++98 -verify %s
// RUN: %clang_cc1 -triple %ms_abi_triple -DMSABI -fsyntax-only -std=c++11 -verify %s
namespace PR5557 {
template <class T> struct A {
A(); // expected-note{{instantiation}}
virtual int a(T x);
};
template<class T> A<T>::A() {}
template<class T> int A<T>::a(T x) {
return *x; // expected-error{{requires pointer operand}}
}
void f() {
A<int> x; // expected-note{{instantiation}}
}
template<typename T>
struct X {
virtual void f();
};
template<>
void X<int>::f() { }
}
Mark vtable used on explicit destructor definitions. There are two things in a C++ program that need to read the vtable pointer: Constructors and destructors. (A few other operations -- virtual calls, dynamic cast, rtti -- read the vtable pointer off a this pointer, but for this they don't need the vtable symbol.) Implicit constructors and destructors and explicit constructors already marked the vtable as used, but explicit destructors didn't. Note that the only thing sema's "mark a class's vtable used" does is to mark all final overriders of the class as referenced, it does _not_ cause emission of the vtable itself. This is done on demand by codegen, independent of sema, since sema might emit functions that are not referenced. (The exception are vtables that are forced via key functions -- these are forced onto codegen by sema.) This bug went unnoticed for years because it doesn't have observable effects (yet -- I want to change this in PR20337, which is why I noticed this). r213109 made it so that _calls_ to constructors don't mark the vtable used. Currently, _calls_ to destructors still mark the vtable used. If that wasn't the case, this program would tickle the problem: test.h: template <typename T> struct B { int* p; virtual ~B() { delete p; } virtual void f() {} }; struct __attribute__((visibility("default"))) C { C(); B<int> m; }; test2.cc: #include "test.h" int main() { C* c = new C; delete c; } test3.cc: #include "test.h" C::C() {} # This bin/clang++ binary doesn't MarkVTableUsed() for virtual dtor calls: $ bin/clang++ -shared test3.cc -std=c++11 -O2 -fvisibility=hidden \ -fvisibility-inlines-hidden -o libtest3.dylib $ bin/clang++ test2.cc -std=c++11 -O2 -fvisibility=hidden \ -fvisibility-inlines-hidden libtest3.dylib Undefined symbols for architecture x86_64: "B<int>::f()", referenced from: vtable for B<int> in test2-af8f4f.o ld: symbol(s) not found for architecture x86_64 What's happening here is that there's a copy of B's vtable hidden in libtest3.dylib, because C's constructor caused an implicit instantiation of that (and implicit constructors generate vtables). test2.cc calls C's destructDr, which destroys the B<int> member, which wants to overwrite the vtable back to B (think of B as the base of a class hierarchy, and of hierarchical destruction -- maybe we shouldn't do the vtable writing in destructors of final classes), but there's nothing in test2.cc that marks B's vtable used. So codegen writes out the vtable, but since it wasn't marked used, sema didn't mark all the virtual functions (in particular f()) as used. Note that this change makes us reject programs we didn't reject before (see the included Sema test case), but both gcc and cl also reject this code, and clang used to reject it before r213109. llvm-svn: 225761
2015-01-13 11:52:11 +08:00
// Like PR5557, but with a defined destructor instead of a defined constructor.
namespace PR5557_dtor {
template <class T> struct A {
A(); // Don't have an implicit constructor.
~A(); // expected-note{{instantiation}}
virtual int a(T x);
};
template<class T> A<T>::~A() {}
template<class T> int A<T>::a(T x) {
return *x; // expected-error{{requires pointer operand}}
}
void f() {
A<int> x; // expected-note{{instantiation}}
}
}
template<typename T>
struct Base {
virtual ~Base() {
int *ptr = 0;
T t = ptr; // expected-error{{cannot initialize}}
}
};
template<typename T>
struct Derived : Base<T> {
virtual void foo() { }
};
template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
template<typename T>
struct HasOutOfLineKey {
HasOutOfLineKey() { } // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
virtual T *f(float *fp);
};
template<typename T>
T *HasOutOfLineKey<T>::f(float *fp) {
return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
}
HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::HasOutOfLineKey' requested here}}
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
namespace std {
class type_info;
}
namespace PR7114 {
class A { virtual ~A(); };
#if __cplusplus <= 199711L
// expected-note@-2{{declared private here}}
#else
// expected-note@-4 3 {{overridden virtual function is here}}
#endif
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
template<typename T>
class B {
public:
class Inner : public A { };
#if __cplusplus <= 199711L
// expected-error@-2{{base class 'PR7114::A' has private destructor}}
#else
// expected-error@-4 2 {{deleted function '~Inner' cannot override a non-deleted function}}
// expected-note@-5 2 {{destructor of 'Inner' is implicitly deleted because base class 'PR7114::A' has an inaccessible destructor}}
#ifdef MSABI
// expected-note@-7 1 {{destructor of 'Inner' is implicitly deleted because base class 'PR7114::A' has an inaccessible destructor}}
#endif
#endif
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
static Inner i;
static const unsigned value = sizeof(i) == 4;
#if __cplusplus >= 201103L
// expected-note@-2 {{in instantiation of member class 'PR7114::B<int>::Inner' requested here}}
// expected-note@-3 {{in instantiation of member class 'PR7114::B<float>::Inner' requested here}}
#endif
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
};
int f() { return B<int>::value; }
#if __cplusplus >= 201103L
// expected-note@-2 {{in instantiation of template class 'PR7114::B<int>' requested here}}
#endif
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
#ifdef MSABI
void test_typeid(B<float>::Inner bfi) {
#if __cplusplus <= 199711L
// expected-note@-2 {{implicit destructor}}
#else
// expected-error@-4 {{attempt to use a deleted function}}
// expected-note@-5 {{in instantiation of template class 'PR7114::B<float>' requested here}}
#endif
(void)typeid(bfi);
#else
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
void test_typeid(B<float>::Inner bfi) {
#if __cplusplus >= 201103L
// expected-note@-2 {{in instantiation of template class 'PR7114::B<float>' requested here}}
#endif
(void)typeid(bfi);
#if __cplusplus <= 199711L
// expected-note@-2 {{implicit destructor}}
#endif
#endif
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
}
template<typename T>
struct X : A {
#if __cplusplus >= 201103L
// expected-error@-2 {{deleted function '~X' cannot override a non-deleted function}}
// expected-note@-3 {{destructor of 'X<int>' is implicitly deleted because base class 'PR7114::A' has an inaccessible destructor}}
#endif
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
void f() { }
};
void test_X(X<int> &xi, X<float> &xf) {
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
xi.f();
#if __cplusplus >= 201103L
// expected-note@-2 {{in instantiation of template class 'PR7114::X<int>' requested here}}
#endif
Rework when and how vtables are emitted, by tracking where vtables are "used" (e.g., we will refer to the vtable in the generated code) and when they are defined (i.e., because we've seen the key function definition). Previously, we were effectively tracking "potential definitions" rather than uses, so we were a bit too eager about emitting vtables for classes without key functions. The new scheme: - For every use of a vtable, Sema calls MarkVTableUsed() to indicate the use. For example, this occurs when calling a virtual member function of the class, defining a constructor of that class type, dynamic_cast'ing from that type to a derived class, casting to/through a virtual base class, etc. - For every definition of a vtable, Sema calls MarkVTableUsed() to indicate the definition. This happens at the end of the translation unit for classes whose key function has been defined (so we can delay computation of the key function; see PR6564), and will also occur with explicit template instantiation definitions. - For every vtable defined/used, we mark all of the virtual member functions of that vtable as defined/used, unless we know that the key function is in another translation unit. This instantiates virtual member functions when needed. - At the end of the translation unit, Sema tells CodeGen (via the ASTConsumer) which vtables must be defined (CodeGen will define them) and which may be used (for which CodeGen will define the vtables lazily). From a language perspective, both the old and the new schemes are permissible: we're allowed to instantiate virtual member functions whenever we want per the standard. However, all other C++ compilers were more lazy than we were, and our eagerness was both a performance issue (we instantiated too much) and a portability problem (we broke Boost test cases, which now pass). Notes: (1) There's a ton of churn in the tests, because the order in which vtables get emitted to IR has changed. I've tried to isolate some of the larger tests from these issues. (2) Some diagnostics related to implicitly-instantiated/implicitly-defined virtual member functions have moved to the point of first use/definition. It's better this way. (3) I could use a review of the places where we MarkVTableUsed, to see if I missed any place where the language effectively requires a vtable. Fixes PR7114 and PR6564. llvm-svn: 103718
2010-05-14 00:44:06 +08:00
}
}
2013-06-20 09:47:05 +08:00
namespace DynamicCast {
struct Y {};
template<typename T> struct X : virtual Y {
Don't let virtual calls and dynamic casts call Sema::MarkVTableUsed(). clang currently calls MarkVTableUsed() for classes that get their virtual methods called or that participate in a dynamic_cast. This is unnecessary, since CodeGen only emits vtables when it generates constructor, destructor, and vtt code. (*) Note that Sema::MarkVTableUsed() doesn't cause the emission of a vtable. Its main user-visible effect is that it instantiates virtual member functions of template classes, to make sure that if codegen decides to write a vtable all the entries in the vtable are defined. While this shouldn't change the behavior of codegen (other than being faster), it does make clang more permissive: virtual methods of templates (in particular destructors) end up being instantiated less often. In particular, classes that have members that are smart pointers to incomplete types will now get their implicit virtual destructor instantiated less frequently. For example, this used to not compile but does now compile: template <typename T> struct OwnPtr { ~OwnPtr() { static_assert((sizeof(T) > 0), "TypeMustBeComplete"); } }; class ScriptLoader; struct Base { virtual ~Base(); }; struct Sub : public Base { virtual void someFun() const {} OwnPtr<ScriptLoader> m_loader; }; void f(Sub *s) { s->someFun(); } The more permissive behavior matches both gcc (where this is not often observable, since in practice most things with virtual methods have a key function, and Sema::DefineUsedVTables() skips vtables for classes with key functions) and cl (which is my motivation for this change) – this fixes PR20337. See this issue and the review thread for some discussions about optimizations. This is similar to r213109 in spirit. r225761 was a prerequisite for this change. Various tests relied on "a->f()" marking a's vtable as used (in the sema sense), switch these to just construct a on the stack. This forces instantiation of the implicit constructor, which will mark the vtable as used. (*) The exception is -fapple-kext mode: In this mode, qualified calls to virtual functions (`a->Base::f()`) still go through the vtable, and since the vtable pointer off this doesn't point to Base's vtable, this needs to reference Base's vtable directly. To keep this working, keep referencing the vtable for virtual calls in apple kext mode. llvm-svn: 227073
2015-01-26 14:23:36 +08:00
virtual void foo() { T x; }
2013-06-20 09:47:05 +08:00
};
template<typename T> struct X2 : virtual Y {
virtual void foo() { T x; }
};
Don't let virtual calls and dynamic casts call Sema::MarkVTableUsed(). clang currently calls MarkVTableUsed() for classes that get their virtual methods called or that participate in a dynamic_cast. This is unnecessary, since CodeGen only emits vtables when it generates constructor, destructor, and vtt code. (*) Note that Sema::MarkVTableUsed() doesn't cause the emission of a vtable. Its main user-visible effect is that it instantiates virtual member functions of template classes, to make sure that if codegen decides to write a vtable all the entries in the vtable are defined. While this shouldn't change the behavior of codegen (other than being faster), it does make clang more permissive: virtual methods of templates (in particular destructors) end up being instantiated less often. In particular, classes that have members that are smart pointers to incomplete types will now get their implicit virtual destructor instantiated less frequently. For example, this used to not compile but does now compile: template <typename T> struct OwnPtr { ~OwnPtr() { static_assert((sizeof(T) > 0), "TypeMustBeComplete"); } }; class ScriptLoader; struct Base { virtual ~Base(); }; struct Sub : public Base { virtual void someFun() const {} OwnPtr<ScriptLoader> m_loader; }; void f(Sub *s) { s->someFun(); } The more permissive behavior matches both gcc (where this is not often observable, since in practice most things with virtual methods have a key function, and Sema::DefineUsedVTables() skips vtables for classes with key functions) and cl (which is my motivation for this change) – this fixes PR20337. See this issue and the review thread for some discussions about optimizations. This is similar to r213109 in spirit. r225761 was a prerequisite for this change. Various tests relied on "a->f()" marking a's vtable as used (in the sema sense), switch these to just construct a on the stack. This forces instantiation of the implicit constructor, which will mark the vtable as used. (*) The exception is -fapple-kext mode: In this mode, qualified calls to virtual functions (`a->Base::f()`) still go through the vtable, and since the vtable pointer off this doesn't point to Base's vtable, this needs to reference Base's vtable directly. To keep this working, keep referencing the vtable for virtual calls in apple kext mode. llvm-svn: 227073
2015-01-26 14:23:36 +08:00
Y* f(X<void>* x) { return dynamic_cast<Y*>(x); }
2013-06-20 09:47:05 +08:00
Y* f2(X<void>* x) { return dynamic_cast<Y*>(x); }
}
namespace avoid_using_vtable {
// We shouldn't emit the vtable for this code, in any ABI. If we emit the
// vtable, we emit an implicit virtual dtor, which calls ~RefPtr, which requires
// a complete type for DeclaredOnly.
//
// Previously we would reference the vtable in the MS C++ ABI, even though we
// don't need to emit either the ctor or the dtor. In the Itanium C++ ABI, the
// 'trace' method is the key function, so even though we use the vtable, we
// don't emit it.
template <typename T>
struct RefPtr {
T *m_ptr;
~RefPtr() { m_ptr->deref(); }
};
struct DeclaredOnly;
struct Base {
virtual ~Base();
};
struct AvoidVTable : Base {
RefPtr<DeclaredOnly> m_insertionStyle;
virtual void trace();
AvoidVTable();
};
// Don't call the dtor, because that will emit an implicit dtor, and require a
// complete type for DeclaredOnly.
void foo() { new AvoidVTable; }
}
namespace vtable_uses_incomplete {
// Opposite of the previous test that avoids a vtable, this one tests that we
// use the vtable when the ctor is defined inline.
template <typename T>
struct RefPtr {
T *m_ptr;
~RefPtr() { m_ptr->deref(); } // expected-error {{member access into incomplete type 'vtable_uses_incomplete::DeclaredOnly'}}
};
struct DeclaredOnly; // expected-note {{forward declaration of 'vtable_uses_incomplete::DeclaredOnly'}}
struct Base {
virtual ~Base();
};
struct UsesVTable : Base {
RefPtr<DeclaredOnly> m_insertionStyle;
virtual void trace();
UsesVTable() {} // expected-note {{in instantiation of member function 'vtable_uses_incomplete::RefPtr<vtable_uses_incomplete::DeclaredOnly>::~RefPtr' requested here}}
};
}