326 lines · cpp
1// RUN: %check_clang_tidy %s modernize-use-override,cppcoreguidelines-explicit-virtual-functions %t -- -- -fexceptions2 3#define ABSTRACT = 04 5#define OVERRIDE override6#define VIRTUAL virtual7#define NOT_VIRTUAL8#define NOT_OVERRIDE9 10#define MUST_USE_RESULT __attribute__((warn_unused_result))11#define UNUSED __attribute__((unused))12 13struct MUST_USE_RESULT MustUseResultObject {};14 15struct IntPair {16 int First, Second;17};18 19struct Base {20 virtual ~Base() {}21 virtual void a();22 virtual void b();23 virtual void c();24 virtual void d();25 virtual void d2();26 virtual void e() = 0;27 virtual void f() = 0;28 virtual void f2() const = 0;29 virtual void g() = 0;30 virtual void g2() = 0;31 32 virtual void j() const;33 virtual MustUseResultObject k();34 virtual bool l() MUST_USE_RESULT UNUSED;35 virtual bool n() MUST_USE_RESULT UNUSED;36 37 virtual void m();38 virtual void m2();39 virtual void o() __attribute__((unused));40 41 virtual void r() &;42 virtual void rr() &&;43 44 virtual void cv() const volatile;45 virtual void cv2() const volatile;46 47 virtual void ne() noexcept(false);48 virtual void t() throw();49 50 virtual void il(IntPair);51};52 53struct SimpleCases : public Base {54public:55 virtual ~SimpleCases();56 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual'57 // CHECK-FIXES: ~SimpleCases() override;58 59 void a();60 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this61 // CHECK-FIXES: void a() override;62 63 void b() override;64 // CHECK-MESSAGES-NOT: warning:65 // CHECK-FIXES: void b() override;66 67 virtual void c();68 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using69 // CHECK-FIXES: void c() override;70 71 virtual void d() override;72 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'override'73 // CHECK-FIXES: void d() override;74 75 virtual void d2() final;76 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'final'77 // CHECK-FIXES: void d2() final;78 79 virtual void e() = 0;80 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using81 // CHECK-FIXES: void e() override = 0;82 83 virtual void f()=0;84 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using85 // CHECK-FIXES: void f() override =0;86 87 virtual void f2() const=0;88 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using89 // CHECK-FIXES: void f2() const override =0;90 91 virtual void g() ABSTRACT;92 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using93 // CHECK-FIXES: void g() override ABSTRACT;94 95 virtual void j() const;96 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using97 // CHECK-FIXES: void j() const override;98 99 // Has an implicit attribute.100 virtual MustUseResultObject k();101 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using102 // CHECK-FIXES: MustUseResultObject k() override;103 104 virtual bool l() MUST_USE_RESULT UNUSED;105 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using106 // CHECK-FIXES: bool l() override MUST_USE_RESULT UNUSED;107 108 virtual bool n() UNUSED MUST_USE_RESULT;109 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using110 // CHECK-FIXES: bool n() override UNUSED MUST_USE_RESULT;111 112 void m() override final;113 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'override' is redundant since the function is already declared 'final'114 // CHECK-FIXES: void m() final;115 116 virtual void m2() override final;117 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant since the function is already declared 'final'118 // CHECK-FIXES: void m2() final;119 120 virtual void o() __attribute__((unused));121 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using122 // CHECK-FIXES: void o() override __attribute__((unused));123 124 virtual void ne() noexcept(false);125 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using126 // CHECK-FIXES: void ne() noexcept(false) override;127 128 virtual void t() throw();129 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using130 // CHECK-FIXES: void t() throw() override;131 132 virtual /* */ void g2();133 // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual'134 // CHECK-FIXES: /* */ void g2() override;135};136 137// CHECK-MESSAGES-NOT: warning:138 139void SimpleCases::c() {}140// CHECK-FIXES: void SimpleCases::c() {}141 142SimpleCases::~SimpleCases() {}143// CHECK-FIXES: SimpleCases::~SimpleCases() {}144 145struct DefaultedDestructor : public Base {146 DefaultedDestructor() {}147 virtual ~DefaultedDestructor() = default;148 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using149 // CHECK-FIXES: ~DefaultedDestructor() override = default;150};151 152struct FinalSpecified : public Base {153public:154 virtual ~FinalSpecified() final;155 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'virtual' is redundant since the function is already declared 'final'156 // CHECK-FIXES: ~FinalSpecified() final;157 158 void b() final;159 // CHECK-MESSAGES-NOT: warning:160 // CHECK-FIXES: void b() final;161 162 virtual void d() final;163 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant164 // CHECK-FIXES: void d() final;165 166 virtual void e() final = 0;167 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant168 // CHECK-FIXES: void e() final = 0;169 170 virtual void j() const final;171 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant172 // CHECK-FIXES: void j() const final;173 174 virtual bool l() final MUST_USE_RESULT UNUSED;175 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant176 // CHECK-FIXES: bool l() final MUST_USE_RESULT UNUSED;177};178 179struct InlineDefinitions : public Base {180public:181 virtual ~InlineDefinitions() {}182 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using183 // CHECK-FIXES: ~InlineDefinitions() override {}184 185 void a() {}186 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this187 // CHECK-FIXES: void a() override {}188 189 void b() override {}190 // CHECK-MESSAGES-NOT: warning:191 // CHECK-FIXES: void b() override {}192 193 virtual void c()194 {}195 // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using196 // CHECK-FIXES: void c() override197 198 virtual void d() override {}199 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant200 // CHECK-FIXES: void d() override {}201 202 virtual void j() const203 {}204 // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using205 // CHECK-FIXES: void j() const override206 207 // Has an implicit attribute.208 virtual MustUseResultObject k();209 // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using210 // CHECK-FIXES: MustUseResultObject k() override;211 212 virtual bool l() MUST_USE_RESULT UNUSED;213 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using214 // CHECK-FIXES: bool l() override MUST_USE_RESULT UNUSED;215 216 virtual void r() &217 {}218 // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using219 // CHECK-FIXES: void r() & override220 221 virtual void rr() &&222 {}223 // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using224 // CHECK-FIXES: void rr() && override225 226 virtual void cv() const volatile227 {}228 // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using229 // CHECK-FIXES: void cv() const volatile override230 231 virtual void cv2() const volatile // some comment232 {}233 // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: prefer using234 // CHECK-FIXES: void cv2() const volatile override // some comment235};236 237struct DefaultArguments : public Base {238 // Tests for default arguments (with initializer lists).239 // Make sure the override fix is placed after the argument list.240 void il(IntPair p = {1, (2 + (3))}) {}241 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this242 // CHECK-FIXES: void il(IntPair p = {1, (2 + (3))}) override {}243};244 245struct Macros : public Base {246 // Tests for 'virtual' and 'override' being defined through macros. Basically247 // give up for now.248 NOT_VIRTUAL void a() NOT_OVERRIDE;249 // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: annotate this250 // CHECK-FIXES: NOT_VIRTUAL void a() override NOT_OVERRIDE;251 252 VIRTUAL void b() NOT_OVERRIDE;253 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using254 // CHECK-FIXES: VIRTUAL void b() override NOT_OVERRIDE;255 256 NOT_VIRTUAL void c() OVERRIDE;257 // CHECK-MESSAGES-NOT: warning:258 // CHECK-FIXES: NOT_VIRTUAL void c() OVERRIDE;259 260 VIRTUAL void d() OVERRIDE;261 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant262 // CHECK-FIXES: VIRTUAL void d() OVERRIDE;263 264#define FUNC(return_type, name) return_type name()265 FUNC(void, e);266 // CHECK-FIXES: FUNC(void, e);267 268#define F virtual void f();269 F270 // CHECK-FIXES: F271 272 VIRTUAL void g() OVERRIDE final;273 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant274 // CHECK-FIXES: VIRTUAL void g() final;275};276 277// Tests for templates.278template <typename T> struct TemplateBase {279 virtual void f(T t);280};281 282template <typename T> struct DerivedFromTemplate : public TemplateBase<T> {283 virtual void f(T t);284 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using285 // CHECK-FIXES: void f(T t) override;286};287void f() { DerivedFromTemplate<int>().f(2); }288 289template <class C>290struct UnusedMemberInstantiation : public C {291 virtual ~UnusedMemberInstantiation() {}292 // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using293 // CHECK-FIXES: ~UnusedMemberInstantiation() override {}294};295struct IntantiateWithoutUse : public UnusedMemberInstantiation<Base> {};296 297struct Base2 {298 virtual ~Base2() {}299 virtual void a();300};301 302// The OverrideAttr isn't propagated to specializations in all cases. Make sure303// we don't add "override" a second time.304template <int I>305struct MembersOfSpecializations : public Base2 {306 void a() override;307 // CHECK-MESSAGES-NOT: warning:308 // CHECK-FIXES: void a() override;309};310template <> void MembersOfSpecializations<3>::a() {}311void ff() { MembersOfSpecializations<3>().a(); };312 313// In case try statement is used as a method body,314// make sure that override fix is placed before try keyword.315struct TryStmtAsBody : public Base {316 void a() try317 // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this318 // CHECK-FIXES: void a() override try319 { b(); } catch(...) { c(); }320 321 virtual void d() try322 // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using323 // CHECK-FIXES: void d() override try324 { e(); } catch(...) { f(); }325};326