19ca5c425SRichard Smith // RUN: %clang_cc1 -fsyntax-only -fcxx-exceptions -verify -std=c++11 %s
260795255SSebastian Redl 
360795255SSebastian Redl class A {
460795255SSebastian Redl   virtual void f();
5c15b0cfcSDouglas Gregor   virtual void g() = 0; // expected-note{{unimplemented pure virtual method 'g' in 'A'}}
660795255SSebastian Redl 
760795255SSebastian Redl   void h() = 0; // expected-error {{'h' is not virtual and cannot be declared pure}}
860795255SSebastian Redl   void i() = 1; // expected-error {{initializer on function does not look like a pure-specifier}}
960795255SSebastian Redl   void j() = 0u; // expected-error {{initializer on function does not look like a pure-specifier}}
1060795255SSebastian Redl 
110c88030aSDouglas Gregor 
120c88030aSDouglas Gregor   void k();
130c88030aSDouglas Gregor 
1460795255SSebastian Redl public:
1560795255SSebastian Redl   A(int);
1660795255SSebastian Redl };
1760795255SSebastian Redl 
k()180c88030aSDouglas Gregor virtual void A::k() { } // expected-error{{'virtual' can only be specified inside the class definition}}
190c88030aSDouglas Gregor 
2060795255SSebastian Redl class B : public A {
2160795255SSebastian Redl   // Needs to recognize that overridden function is virtual.
22c15b0cfcSDouglas Gregor   void g() = 0;
2360795255SSebastian Redl 
2460795255SSebastian Redl   // Needs to recognize that function does not override.
25c15b0cfcSDouglas Gregor   void g(int) = 0; // expected-error{{'g' is not virtual and cannot be declared pure}}
2660795255SSebastian Redl };
2760795255SSebastian Redl 
2860795255SSebastian Redl // Needs to recognize invalid uses of abstract classes.
fn(A)29c15b0cfcSDouglas Gregor A fn(A) // expected-error{{parameter type 'A' is an abstract class}} \
30c15b0cfcSDouglas Gregor         // expected-error{{return type 'A' is an abstract class}}
3160795255SSebastian Redl {
32c15b0cfcSDouglas Gregor   A a; // expected-error{{variable type 'A' is an abstract class}}
335f299dd8SAaron Ballman   (void)static_cast<A>(0); // expected-error{{allocating an object of abstract class type 'A'}}
3460795255SSebastian Redl   try {
35c15b0cfcSDouglas Gregor   } catch(A) { // expected-error{{variable type 'A' is an abstract class}}
3660795255SSebastian Redl   }
3760795255SSebastian Redl }
38c15b0cfcSDouglas Gregor 
39c15b0cfcSDouglas Gregor namespace rdar9670557 {
40c15b0cfcSDouglas Gregor   typedef int func(int);
41cfcdf3a6SRichard Smith   func *a();
42c15b0cfcSDouglas Gregor   struct X {
43c15b0cfcSDouglas Gregor     virtual func f = 0;
44cfcdf3a6SRichard Smith     virtual func (g) = 0;
45cfcdf3a6SRichard Smith     func *h = 0;
46c15b0cfcSDouglas Gregor   };
47c15b0cfcSDouglas Gregor }
48750db65bSSerge Pavlov 
49750db65bSSerge Pavlov namespace pr8264 {
50750db65bSSerge Pavlov   struct Test {
51750db65bSSerge Pavlov     virtual virtual void func();  // expected-warning {{duplicate 'virtual' declaration specifier}}
52750db65bSSerge Pavlov   };
53750db65bSSerge Pavlov }
54*9ba0fec8SRichard Smith 
55*9ba0fec8SRichard Smith namespace VirtualFriend {
56*9ba0fec8SRichard Smith   // DR (filed but no number yet): reject meaningless pure-specifier on a friend declaration.
57*9ba0fec8SRichard Smith   struct A { virtual int f(); };
58*9ba0fec8SRichard Smith   struct B { friend int A::f() = 0; }; // expected-error {{friend declaration cannot have a pure-specifier}}
59*9ba0fec8SRichard Smith   struct C {
60*9ba0fec8SRichard Smith     virtual int f();
61*9ba0fec8SRichard Smith     friend int C::f() = 0; // expected-error {{friend declaration cannot have a pure-specifier}}
62*9ba0fec8SRichard Smith   };
63*9ba0fec8SRichard Smith }
64