michael@0: #define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) michael@0: // Ignore warnings not related to static analysis here michael@0: #pragma GCC diagnostic ignored "-Woverloaded-virtual" michael@0: michael@0: struct S { michael@0: virtual void f() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: virtual void g() MOZ_MUST_OVERRIDE; michael@0: virtual void h() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: }; michael@0: struct C : S { // expected-error {{'C' must override 'f'}} expected-error {{'C' must override 'h'}} michael@0: virtual void g() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: virtual void h(int); michael@0: void q() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: }; michael@0: struct D : C { // expected-error {{'D' must override 'g'}} expected-error {{'D' must override 'q'}} michael@0: virtual void f(); michael@0: }; michael@0: michael@0: struct Base { michael@0: virtual void VirtMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: void NonVirtMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: static void StaticMethod() MOZ_MUST_OVERRIDE; michael@0: }; michael@0: michael@0: struct DoesNotPropagate : Base { michael@0: virtual void VirtMethod(); michael@0: void NonVirtMethod(); michael@0: static void StaticMethod(); michael@0: }; michael@0: michael@0: struct Final : DoesNotPropagate { }; michael@0: michael@0: struct Propagates : Base { michael@0: virtual void VirtMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: void NonVirtMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: static void StaticMethod() MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: }; michael@0: michael@0: struct FailsFinal : Propagates { }; // expected-error {{'FailsFinal' must override 'VirtMethod'}} expected-error {{'FailsFinal' must override 'NonVirtMethod'}} expected-error {{'FailsFinal' must override 'StaticMethod'}} michael@0: michael@0: struct WrongOverload : Base { // expected-error {{'WrongOverload' must override 'VirtMethod'}} expected-error {{'WrongOverload' must override 'NonVirtMethod'}} michael@0: virtual void VirtMethod() const; michael@0: void NonVirtMethod(int param); michael@0: static void StaticMethod(); michael@0: }; michael@0: michael@0: namespace A { namespace B { namespace C { michael@0: struct Param {}; michael@0: struct Base { michael@0: void f(Param p) MOZ_MUST_OVERRIDE; // expected-note {{function to override is here}} michael@0: }; michael@0: }}} michael@0: michael@0: struct Param {}; michael@0: michael@0: struct Derived : A::B::C::Base { michael@0: typedef A::B::C::Param Typedef; michael@0: void f(Typedef t); michael@0: }; michael@0: michael@0: struct BadDerived : A::B::C::Base { // expected-error {{'BadDerived' must override 'f'}} michael@0: void f(Param p); michael@0: };