forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			51 lines
		
	
	
		
			994 B
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			51 lines
		
	
	
		
			994 B
		
	
	
	
		
			C++
		
	
	
	
// RUN: %clang_cc1 -verify -std=c++11 %s
 | 
						|
// expected-no-diagnostics
 | 
						|
template <typename T> struct OwnPtr {
 | 
						|
  T *p;
 | 
						|
  ~OwnPtr() {
 | 
						|
    static_assert(sizeof(T) > 0, "incomplete T");
 | 
						|
    delete p;
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
namespace use_vtable_for_vcall {
 | 
						|
struct Incomplete;
 | 
						|
struct A {
 | 
						|
  virtual ~A() {}
 | 
						|
  virtual void m() {}
 | 
						|
};
 | 
						|
struct B : A {
 | 
						|
  B();
 | 
						|
  virtual void m() { }
 | 
						|
  virtual void m2() { static_cast<A *>(this)->m(); }
 | 
						|
  OwnPtr<Incomplete> m_sqlError;
 | 
						|
};
 | 
						|
 | 
						|
void f() {
 | 
						|
  // Since B's constructor is declared out of line, nothing in this file
 | 
						|
  // references a vtable, so the destructor doesn't get built.
 | 
						|
  A *b = new B();
 | 
						|
  b->m();
 | 
						|
  delete b;
 | 
						|
}
 | 
						|
}
 | 
						|
 | 
						|
namespace dont_mark_qualified_vcall {
 | 
						|
struct Incomplete;
 | 
						|
struct A {
 | 
						|
  virtual ~A() {}
 | 
						|
  virtual void m() {}
 | 
						|
};
 | 
						|
struct B : A {
 | 
						|
  B();
 | 
						|
  // Previously we would mark B's vtable referenced to devirtualize this call to
 | 
						|
  // A::m, even though it's not a virtual call.
 | 
						|
  virtual void m() { A::m(); }
 | 
						|
  OwnPtr<Incomplete> m_sqlError;
 | 
						|
};
 | 
						|
 | 
						|
B *f() {
 | 
						|
  return new B();
 | 
						|
}
 | 
						|
}
 |