head	1.1;
branch	1.1.1;
access;
symbols
	netbsd-11-0-RC6:1.1.1.4
	netbsd-11-0-RC5:1.1.1.4
	netbsd-11-0-RC4:1.1.1.4
	netbsd-11-0-RC3:1.1.1.4
	netbsd-11-0-RC2:1.1.1.4
	netbsd-11-0-RC1:1.1.1.4
	perseant-exfatfs-base-20250801:1.1.1.4
	netbsd-11:1.1.1.4.0.10
	netbsd-11-base:1.1.1.4
	netbsd-10-1-RELEASE:1.1.1.4
	perseant-exfatfs-base-20240630:1.1.1.4
	perseant-exfatfs:1.1.1.4.0.8
	perseant-exfatfs-base:1.1.1.4
	netbsd-8-3-RELEASE:1.1.1.3
	netbsd-9-4-RELEASE:1.1.1.3
	netbsd-10-0-RELEASE:1.1.1.4
	netbsd-10-0-RC6:1.1.1.4
	netbsd-10-0-RC5:1.1.1.4
	netbsd-10-0-RC4:1.1.1.4
	netbsd-10-0-RC3:1.1.1.4
	netbsd-10-0-RC2:1.1.1.4
	netbsd-10-0-RC1:1.1.1.4
	netbsd-10:1.1.1.4.0.6
	netbsd-10-base:1.1.1.4
	netbsd-9-3-RELEASE:1.1.1.3
	cjep_sun2x:1.1.1.4.0.4
	cjep_sun2x-base:1.1.1.4
	cjep_staticlib_x-base1:1.1.1.4
	netbsd-9-2-RELEASE:1.1.1.3
	cjep_staticlib_x:1.1.1.4.0.2
	cjep_staticlib_x-base:1.1.1.4
	netbsd-9-1-RELEASE:1.1.1.3
	phil-wifi-20200421:1.1.1.4
	phil-wifi-20200411:1.1.1.4
	phil-wifi-20200406:1.1.1.4
	netbsd-8-2-RELEASE:1.1.1.3
	netbsd-9-0-RELEASE:1.1.1.3
	netbsd-9-0-RC2:1.1.1.3
	netbsd-9-0-RC1:1.1.1.3
	netbsd-9:1.1.1.3.0.18
	netbsd-9-base:1.1.1.3
	phil-wifi-20190609:1.1.1.3
	netbsd-8-1-RELEASE:1.1.1.3
	netbsd-8-1-RC1:1.1.1.3
	pgoyette-compat-merge-20190127:1.1.1.3
	pgoyette-compat-20190127:1.1.1.3
	pgoyette-compat-20190118:1.1.1.3
	pgoyette-compat-1226:1.1.1.3
	pgoyette-compat-1126:1.1.1.3
	pgoyette-compat-1020:1.1.1.3
	pgoyette-compat-0930:1.1.1.3
	pgoyette-compat-0906:1.1.1.3
	netbsd-7-2-RELEASE:1.1.1.2
	pgoyette-compat-0728:1.1.1.3
	clang-337282:1.1.1.3
	netbsd-8-0-RELEASE:1.1.1.3
	phil-wifi:1.1.1.3.0.16
	phil-wifi-base:1.1.1.3
	pgoyette-compat-0625:1.1.1.3
	netbsd-8-0-RC2:1.1.1.3
	pgoyette-compat-0521:1.1.1.3
	pgoyette-compat-0502:1.1.1.3
	pgoyette-compat-0422:1.1.1.3
	netbsd-8-0-RC1:1.1.1.3
	pgoyette-compat-0415:1.1.1.3
	pgoyette-compat-0407:1.1.1.3
	pgoyette-compat-0330:1.1.1.3
	pgoyette-compat-0322:1.1.1.3
	pgoyette-compat-0315:1.1.1.3
	netbsd-7-1-2-RELEASE:1.1.1.2
	pgoyette-compat:1.1.1.3.0.14
	pgoyette-compat-base:1.1.1.3
	netbsd-7-1-1-RELEASE:1.1.1.2
	clang-319952:1.1.1.3
	matt-nb8-mediatek:1.1.1.3.0.12
	matt-nb8-mediatek-base:1.1.1.3
	clang-309604:1.1.1.3
	perseant-stdc-iso10646:1.1.1.3.0.10
	perseant-stdc-iso10646-base:1.1.1.3
	netbsd-8:1.1.1.3.0.8
	netbsd-8-base:1.1.1.3
	prg-localcount2-base3:1.1.1.3
	prg-localcount2-base2:1.1.1.3
	prg-localcount2-base1:1.1.1.3
	prg-localcount2:1.1.1.3.0.6
	prg-localcount2-base:1.1.1.3
	pgoyette-localcount-20170426:1.1.1.3
	bouyer-socketcan-base1:1.1.1.3
	pgoyette-localcount-20170320:1.1.1.3
	netbsd-7-1:1.1.1.2.0.10
	netbsd-7-1-RELEASE:1.1.1.2
	netbsd-7-1-RC2:1.1.1.2
	clang-294123:1.1.1.3
	netbsd-7-nhusb-base-20170116:1.1.1.2
	bouyer-socketcan:1.1.1.3.0.4
	bouyer-socketcan-base:1.1.1.3
	clang-291444:1.1.1.3
	pgoyette-localcount-20170107:1.1.1.3
	netbsd-7-1-RC1:1.1.1.2
	pgoyette-localcount-20161104:1.1.1.3
	netbsd-7-0-2-RELEASE:1.1.1.2
	localcount-20160914:1.1.1.3
	netbsd-7-nhusb:1.1.1.2.0.8
	netbsd-7-nhusb-base:1.1.1.2
	clang-280599:1.1.1.3
	pgoyette-localcount-20160806:1.1.1.3
	pgoyette-localcount-20160726:1.1.1.3
	pgoyette-localcount:1.1.1.3.0.2
	pgoyette-localcount-base:1.1.1.3
	netbsd-7-0-1-RELEASE:1.1.1.2
	clang-261930:1.1.1.3
	netbsd-7-0:1.1.1.2.0.6
	netbsd-7-0-RELEASE:1.1.1.2
	netbsd-7-0-RC3:1.1.1.2
	netbsd-7-0-RC2:1.1.1.2
	netbsd-7-0-RC1:1.1.1.2
	clang-237755:1.1.1.2
	clang-232565:1.1.1.2
	clang-227398:1.1.1.2
	tls-maxphys-base:1.1.1.2
	tls-maxphys:1.1.1.2.0.4
	netbsd-7:1.1.1.2.0.2
	netbsd-7-base:1.1.1.2
	clang-215315:1.1.1.2
	clang-209886:1.1.1.2
	yamt-pagecache:1.1.1.1.0.4
	yamt-pagecache-base9:1.1.1.1
	tls-earlyentropy:1.1.1.1.0.2
	tls-earlyentropy-base:1.1.1.2
	riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.1.1.1
	riastradh-drm2-base3:1.1.1.1
	clang-202566:1.1.1.1
	clang-201163:1.1.1.1
	clang-199312:1.1.1.1
	clang-198450:1.1.1.1
	clang-196603:1.1.1.1
	clang-195771:1.1.1.1
	LLVM:1.1.1;
locks; strict;
comment	@// @;


1.1
date	2013.11.28.14.14.56;	author joerg;	state Exp;
branches
	1.1.1.1;
next	;
commitid	ow8OybrawrB1f3fx;

1.1.1.1
date	2013.11.28.14.14.56;	author joerg;	state Exp;
branches
	1.1.1.1.2.1
	1.1.1.1.4.1;
next	1.1.1.2;
commitid	ow8OybrawrB1f3fx;

1.1.1.2
date	2014.05.30.18.14.49;	author joerg;	state Exp;
branches
	1.1.1.2.4.1;
next	1.1.1.3;
commitid	8q0kdlBlCn09GACx;

1.1.1.3
date	2016.02.27.22.10.13;	author joerg;	state Exp;
branches
	1.1.1.3.16.1;
next	1.1.1.4;
commitid	tIimz3oDlh1NpBWy;

1.1.1.4
date	2019.11.13.22.22.53;	author joerg;	state dead;
branches;
next	;
commitid	QD8YATxuNG34YJKB;

1.1.1.1.2.1
date	2014.08.10.07.08.23;	author tls;	state Exp;
branches;
next	;
commitid	t01A1TLTYxkpGMLx;

1.1.1.1.4.1
date	2013.11.28.14.14.56;	author yamt;	state dead;
branches;
next	1.1.1.1.4.2;
commitid	WSrDtL5nYAUyiyBx;

1.1.1.1.4.2
date	2014.05.22.16.19.39;	author yamt;	state Exp;
branches;
next	;
commitid	WSrDtL5nYAUyiyBx;

1.1.1.2.4.1
date	2014.05.30.18.14.49;	author tls;	state dead;
branches;
next	1.1.1.2.4.2;
commitid	jTnpym9Qu0o4R1Nx;

1.1.1.2.4.2
date	2014.08.19.23.49.17;	author tls;	state Exp;
branches;
next	;
commitid	jTnpym9Qu0o4R1Nx;

1.1.1.3.16.1
date	2020.04.13.07.50.22;	author martin;	state dead;
branches;
next	;
commitid	X01YhRUPVUDaec4C;


desc
@@


1.1
log
@Initial revision
@
text
@// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init

#ifndef __GXX_EXPERIMENTAL_CXX0X__
#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
#define __CONCAT1(__X, __Y) __X ## __Y

#define static_assert(__b, __m) \
  typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
#endif

class C {
  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
};

static_assert(__is_abstract(C), "C has a pure virtual function");

class D : C {
};

static_assert(__is_abstract(D), "D inherits from an abstract class");

class E : D {
  virtual void f();
};

static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");

C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}}

C c; // expected-error {{variable type 'C' is an abstract class}}
void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
void t2(C); // expected-error {{parameter type 'C' is an abstract class}}

struct S {
  C c; // expected-error {{field type 'C' is an abstract class}}
};

void t3(const C&);

void f() {
  C(); // expected-error {{allocating an object of abstract class type 'C'}}
  t3(C()); // expected-error {{allocating an object of abstract class type 'C'}}
}

C e1[2]; // expected-error {{array of abstract class type 'C'}}
C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}

void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}

void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}

typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
void t6(Func);

class F {
  F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
    
  class D {
    void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
  };

  union U {
    void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
  };
    
  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
};

// Diagnosing in these cases is prohibitively expensive.  We still
// diagnose at the function definition, of course.

class Abstract;

void t7(Abstract a);

void t8() {
  void h(Abstract a);
}

namespace N {
void h(Abstract a);
}

class Abstract {
  virtual void f() = 0;
};

// <rdar://problem/6854087>
class foo {
public:
  virtual foo *getFoo() = 0;
};

class bar : public foo {
public:
  virtual bar *getFoo();
};

bar x;

// <rdar://problem/6902298>
class A {
public:
  virtual void release() = 0;
  virtual void release(int count) = 0;
  virtual void retain() = 0;
};

class B : public A {
public:
  virtual void release();
  virtual void release(int count);
  virtual void retain();
};

void foo(void) {
  B b;
}

struct K {
 int f;
 virtual ~K();
};

struct L : public K {
 void f();
};

// PR5222
namespace PR5222 {
  struct A {
    virtual A *clone() = 0;
  };
  struct B : public A {
    virtual B *clone() = 0;
  };
  struct C : public B {
    virtual C *clone();
  };

  C c;  
}

// PR5550 - instantiating template didn't track overridden methods
namespace PR5550 {
  struct A {
    virtual void a() = 0;
    virtual void b() = 0;
  };
  template<typename T> struct B : public A {
    virtual void b();
    virtual void c() = 0;
  };
  struct C : public B<int> {
    virtual void a();
    virtual void c();
  }; 
  C x;
}

namespace PureImplicit {
  // A pure virtual destructor should be implicitly overridden.
  struct A { virtual ~A() = 0; };
  struct B : A {};
  B x;

  // A pure virtual assignment operator should be implicitly overridden.
  struct D;
  struct C { virtual D& operator=(const D&) = 0; };
  struct D : C {};
  D y;
}

namespace test1 {
  struct A {
    virtual void foo() = 0;
  };

  struct B : A {
    using A::foo;
  };

  struct C : B {
    void foo();
  };

  void test() {
    C c;
  }
}

// rdar://problem/8302168
namespace test2 {
  struct X1 {
    virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
    void g(X1 parm7);        // expected-error {{parameter type 'test2::X1' is an abstract class}}
    void g(X1 parm8[2]);     // expected-error {{array of abstract class type 'test2::X1'}}
  };

  template <int N>
  struct X2 {
    virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
    void g(X2 parm10);        // expected-error {{parameter type 'X2<N>' is an abstract class}}
    void g(X2 parm11[2]);     // expected-error {{array of abstract class type 'X2<N>'}}
  };
}

namespace test3 {
  struct A { // expected-note {{not complete until}}
    A x; // expected-error {{field has incomplete type}}
    virtual void abstract() = 0;
  };

  struct B { // expected-note {{not complete until}}
    virtual void abstract() = 0;
    B x; // expected-error {{field has incomplete type}}
  };

  struct C {
    static C x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  struct D {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    static D x; // expected-error {{abstract class}}
  };
}

namespace test4 {
  template <class T> struct A {
    A x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  template <class T> struct B {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    B x; // expected-error {{abstract class}}
  };

  template <class T> struct C {
    static C x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  template <class T> struct D {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    static D x; // expected-error {{abstract class}}
  };
}

namespace test5 {
  struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}
  const A &a = 0; // expected-error {{abstract class}}
  void f(const A &a = 0); // expected-error {{abstract class}}
  void g() { f(0); } // expected-error {{abstract class}}
}

// PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
namespace pr9247 {
  struct A {
    virtual void g(const A& input) = 0;
    struct B {
      C* f(int foo);
    };
  };
}

namespace pr12658 {
  class C {
    public:
      C(int v){}
      virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
  };

  void foo( C& c ) {}

  void bar( void ) {
    foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
  }
}

namespace pr16659 {
  struct A {
    A(int);
    virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
  };
  struct B : virtual A {};
  struct C : B {
    C() : A(37) {}
    void x() override {}
  };

  struct X {
    friend class Z;
  private:
    X &operator=(const X&);
  };
  struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
    virtual ~Y() = 0;
  };
  struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
  void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}

  struct RedundantInit : virtual A {
    RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
  };
}
@


1.1.1.1
log
@Import Clang 3.4rc1 r195771.
@
text
@@


1.1.1.1.2.1
log
@Rebase.
@
text
@d271 10
a280 10
  class C {
    public:
      C(int v){}
      virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
  };

  void foo( C& c ) {}

  void bar( void ) {
    foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
@


1.1.1.2
log
@Import Clang 3.5svn r209886.
@
text
@d271 10
a280 10
  class C {
    public:
      C(int v){}
      virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
  };

  void foo( C& c ) {}

  void bar( void ) {
    foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
@


1.1.1.3
log
@Import Clang 3.8.0rc3 r261930.
@
text
@a10 4
union IncompleteUnion;

static_assert(!__is_abstract(IncompleteUnion), "unions are never abstract");

@


1.1.1.3.16.1
log
@Mostly merge changes from HEAD upto 20200411
@
text
@@


1.1.1.4
log
@Mark old LLVM instance as dead.
@
text
@@


1.1.1.2.4.1
log
@file abstract.cpp was added on branch tls-maxphys on 2014-08-19 23:49:17 +0000
@
text
@d1 309
@


1.1.1.2.4.2
log
@Rebase to HEAD as of a few days ago.
@
text
@a0 309
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init

#ifndef __GXX_EXPERIMENTAL_CXX0X__
#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
#define __CONCAT1(__X, __Y) __X ## __Y

#define static_assert(__b, __m) \
  typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
#endif

class C {
  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
};

static_assert(__is_abstract(C), "C has a pure virtual function");

class D : C {
};

static_assert(__is_abstract(D), "D inherits from an abstract class");

class E : D {
  virtual void f();
};

static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");

C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}}

C c; // expected-error {{variable type 'C' is an abstract class}}
void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
void t2(C); // expected-error {{parameter type 'C' is an abstract class}}

struct S {
  C c; // expected-error {{field type 'C' is an abstract class}}
};

void t3(const C&);

void f() {
  C(); // expected-error {{allocating an object of abstract class type 'C'}}
  t3(C()); // expected-error {{allocating an object of abstract class type 'C'}}
}

C e1[2]; // expected-error {{array of abstract class type 'C'}}
C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}

void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}

void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}

typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
void t6(Func);

class F {
  F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
    
  class D {
    void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
  };

  union U {
    void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
  };
    
  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
};

// Diagnosing in these cases is prohibitively expensive.  We still
// diagnose at the function definition, of course.

class Abstract;

void t7(Abstract a);

void t8() {
  void h(Abstract a);
}

namespace N {
void h(Abstract a);
}

class Abstract {
  virtual void f() = 0;
};

// <rdar://problem/6854087>
class foo {
public:
  virtual foo *getFoo() = 0;
};

class bar : public foo {
public:
  virtual bar *getFoo();
};

bar x;

// <rdar://problem/6902298>
class A {
public:
  virtual void release() = 0;
  virtual void release(int count) = 0;
  virtual void retain() = 0;
};

class B : public A {
public:
  virtual void release();
  virtual void release(int count);
  virtual void retain();
};

void foo(void) {
  B b;
}

struct K {
 int f;
 virtual ~K();
};

struct L : public K {
 void f();
};

// PR5222
namespace PR5222 {
  struct A {
    virtual A *clone() = 0;
  };
  struct B : public A {
    virtual B *clone() = 0;
  };
  struct C : public B {
    virtual C *clone();
  };

  C c;  
}

// PR5550 - instantiating template didn't track overridden methods
namespace PR5550 {
  struct A {
    virtual void a() = 0;
    virtual void b() = 0;
  };
  template<typename T> struct B : public A {
    virtual void b();
    virtual void c() = 0;
  };
  struct C : public B<int> {
    virtual void a();
    virtual void c();
  }; 
  C x;
}

namespace PureImplicit {
  // A pure virtual destructor should be implicitly overridden.
  struct A { virtual ~A() = 0; };
  struct B : A {};
  B x;

  // A pure virtual assignment operator should be implicitly overridden.
  struct D;
  struct C { virtual D& operator=(const D&) = 0; };
  struct D : C {};
  D y;
}

namespace test1 {
  struct A {
    virtual void foo() = 0;
  };

  struct B : A {
    using A::foo;
  };

  struct C : B {
    void foo();
  };

  void test() {
    C c;
  }
}

// rdar://problem/8302168
namespace test2 {
  struct X1 {
    virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
    void g(X1 parm7);        // expected-error {{parameter type 'test2::X1' is an abstract class}}
    void g(X1 parm8[2]);     // expected-error {{array of abstract class type 'test2::X1'}}
  };

  template <int N>
  struct X2 {
    virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
    void g(X2 parm10);        // expected-error {{parameter type 'X2<N>' is an abstract class}}
    void g(X2 parm11[2]);     // expected-error {{array of abstract class type 'X2<N>'}}
  };
}

namespace test3 {
  struct A { // expected-note {{not complete until}}
    A x; // expected-error {{field has incomplete type}}
    virtual void abstract() = 0;
  };

  struct B { // expected-note {{not complete until}}
    virtual void abstract() = 0;
    B x; // expected-error {{field has incomplete type}}
  };

  struct C {
    static C x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  struct D {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    static D x; // expected-error {{abstract class}}
  };
}

namespace test4 {
  template <class T> struct A {
    A x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  template <class T> struct B {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    B x; // expected-error {{abstract class}}
  };

  template <class T> struct C {
    static C x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  template <class T> struct D {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    static D x; // expected-error {{abstract class}}
  };
}

namespace test5 {
  struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}
  const A &a = 0; // expected-error {{abstract class}}
  void f(const A &a = 0); // expected-error {{abstract class}}
  void g() { f(0); } // expected-error {{abstract class}}
}

// PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
namespace pr9247 {
  struct A {
    virtual void g(const A& input) = 0;
    struct B {
      C* f(int foo);
    };
  };
}

namespace pr12658 {
  class C {
    public:
      C(int v){}
      virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
  };

  void foo( C& c ) {}

  void bar( void ) {
    foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
  }
}

namespace pr16659 {
  struct A {
    A(int);
    virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
  };
  struct B : virtual A {};
  struct C : B {
    C() : A(37) {}
    void x() override {}
  };

  struct X {
    friend class Z;
  private:
    X &operator=(const X&);
  };
  struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
    virtual ~Y() = 0;
  };
  struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
  void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}

  struct RedundantInit : virtual A {
    RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
  };
}
@


1.1.1.1.4.1
log
@file abstract.cpp was added on branch yamt-pagecache on 2014-05-22 16:19:39 +0000
@
text
@d1 309
@


1.1.1.1.4.2
log
@sync with head.

for a reference, the tree before this commit was tagged
as yamt-pagecache-tag8.

this commit was splitted into small chunks to avoid
a limitation of cvs.  ("Protocol error: too many arguments")
@
text
@a0 309
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11 -Wabstract-vbase-init

#ifndef __GXX_EXPERIMENTAL_CXX0X__
#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
#define __CONCAT1(__X, __Y) __X ## __Y

#define static_assert(__b, __m) \
  typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
#endif

class C {
  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
};

static_assert(__is_abstract(C), "C has a pure virtual function");

class D : C {
};

static_assert(__is_abstract(D), "D inherits from an abstract class");

class E : D {
  virtual void f();
};

static_assert(!__is_abstract(E), "E inherits from an abstract class but implements f");

C *d = new C; // expected-error {{allocating an object of abstract class type 'C'}}

C c; // expected-error {{variable type 'C' is an abstract class}}
void t1(C c); // expected-error {{parameter type 'C' is an abstract class}}
void t2(C); // expected-error {{parameter type 'C' is an abstract class}}

struct S {
  C c; // expected-error {{field type 'C' is an abstract class}}
};

void t3(const C&);

void f() {
  C(); // expected-error {{allocating an object of abstract class type 'C'}}
  t3(C()); // expected-error {{allocating an object of abstract class type 'C'}}
}

C e1[2]; // expected-error {{array of abstract class type 'C'}}
C (*e2)[2]; // expected-error {{array of abstract class type 'C'}}
C (**e3)[2]; // expected-error {{array of abstract class type 'C'}}

void t4(C c[2]); // expected-error {{array of abstract class type 'C'}}

void t5(void (*)(C)); // expected-error {{parameter type 'C' is an abstract class}}

typedef void (*Func)(C); // expected-error {{parameter type 'C' is an abstract class}}
void t6(Func);

class F {
  F a() { while (1) {} } // expected-error {{return type 'F' is an abstract class}}
    
  class D {
    void f(F c); // expected-error {{parameter type 'F' is an abstract class}}
  };

  union U {
    void u(F c); // expected-error {{parameter type 'F' is an abstract class}}
  };
    
  virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f'}}
};

// Diagnosing in these cases is prohibitively expensive.  We still
// diagnose at the function definition, of course.

class Abstract;

void t7(Abstract a);

void t8() {
  void h(Abstract a);
}

namespace N {
void h(Abstract a);
}

class Abstract {
  virtual void f() = 0;
};

// <rdar://problem/6854087>
class foo {
public:
  virtual foo *getFoo() = 0;
};

class bar : public foo {
public:
  virtual bar *getFoo();
};

bar x;

// <rdar://problem/6902298>
class A {
public:
  virtual void release() = 0;
  virtual void release(int count) = 0;
  virtual void retain() = 0;
};

class B : public A {
public:
  virtual void release();
  virtual void release(int count);
  virtual void retain();
};

void foo(void) {
  B b;
}

struct K {
 int f;
 virtual ~K();
};

struct L : public K {
 void f();
};

// PR5222
namespace PR5222 {
  struct A {
    virtual A *clone() = 0;
  };
  struct B : public A {
    virtual B *clone() = 0;
  };
  struct C : public B {
    virtual C *clone();
  };

  C c;  
}

// PR5550 - instantiating template didn't track overridden methods
namespace PR5550 {
  struct A {
    virtual void a() = 0;
    virtual void b() = 0;
  };
  template<typename T> struct B : public A {
    virtual void b();
    virtual void c() = 0;
  };
  struct C : public B<int> {
    virtual void a();
    virtual void c();
  }; 
  C x;
}

namespace PureImplicit {
  // A pure virtual destructor should be implicitly overridden.
  struct A { virtual ~A() = 0; };
  struct B : A {};
  B x;

  // A pure virtual assignment operator should be implicitly overridden.
  struct D;
  struct C { virtual D& operator=(const D&) = 0; };
  struct D : C {};
  D y;
}

namespace test1 {
  struct A {
    virtual void foo() = 0;
  };

  struct B : A {
    using A::foo;
  };

  struct C : B {
    void foo();
  };

  void test() {
    C c;
  }
}

// rdar://problem/8302168
namespace test2 {
  struct X1 {
    virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
    void g(X1 parm7);        // expected-error {{parameter type 'test2::X1' is an abstract class}}
    void g(X1 parm8[2]);     // expected-error {{array of abstract class type 'test2::X1'}}
  };

  template <int N>
  struct X2 {
    virtual void xfunc(void) = 0;  // expected-note {{unimplemented pure virtual method}}
    void g(X2 parm10);        // expected-error {{parameter type 'X2<N>' is an abstract class}}
    void g(X2 parm11[2]);     // expected-error {{array of abstract class type 'X2<N>'}}
  };
}

namespace test3 {
  struct A { // expected-note {{not complete until}}
    A x; // expected-error {{field has incomplete type}}
    virtual void abstract() = 0;
  };

  struct B { // expected-note {{not complete until}}
    virtual void abstract() = 0;
    B x; // expected-error {{field has incomplete type}}
  };

  struct C {
    static C x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  struct D {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    static D x; // expected-error {{abstract class}}
  };
}

namespace test4 {
  template <class T> struct A {
    A x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  template <class T> struct B {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    B x; // expected-error {{abstract class}}
  };

  template <class T> struct C {
    static C x; // expected-error {{abstract class}}
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
  };

  template <class T> struct D {
    virtual void abstract() = 0; // expected-note {{unimplemented pure virtual method}}
    static D x; // expected-error {{abstract class}}
  };
}

namespace test5 {
  struct A { A(int); virtual ~A() = 0; }; // expected-note {{pure virtual method}}
  const A &a = 0; // expected-error {{abstract class}}
  void f(const A &a = 0); // expected-error {{abstract class}}
  void g() { f(0); } // expected-error {{abstract class}}
}

// PR9247: Crash on invalid in clang::Sema::ActOnFinishCXXMemberSpecification
namespace pr9247 {
  struct A {
    virtual void g(const A& input) = 0;
    struct B {
      C* f(int foo);
    };
  };
}

namespace pr12658 {
  class C {
    public:
      C(int v){}
      virtual void f() = 0; // expected-note {{unimplemented pure virtual method 'f' in 'C'}}
  };

  void foo( C& c ) {}

  void bar( void ) {
    foo(C(99)); // expected-error {{allocating an object of abstract class type 'pr12658::C'}}
  }
}

namespace pr16659 {
  struct A {
    A(int);
    virtual void x() = 0; // expected-note {{unimplemented pure virtual method 'x' in 'RedundantInit'}}
  };
  struct B : virtual A {};
  struct C : B {
    C() : A(37) {}
    void x() override {}
  };

  struct X {
    friend class Z;
  private:
    X &operator=(const X&);
  };
  struct Y : virtual X { // expected-note {{::X' has an inaccessible copy assignment}}
    virtual ~Y() = 0;
  };
  struct Z : Y {}; // expected-note {{::Y' has a deleted copy assignment}}
  void f(Z &a, const Z &b) { a = b; } // expected-error {{copy assignment operator is implicitly deleted}}

  struct RedundantInit : virtual A {
    RedundantInit() : A(0) {} // expected-warning {{initializer for virtual base class 'pr16659::A' of abstract class 'RedundantInit' will never be used}}
  };
}
@


