brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.3 KiB · 4b2d89b Raw
276 lines · cpp
1// RUN: clang-tidy %s -checks="-*,bugprone-throwing-static-initialization" -- -std=c++17 -target x86_64-pc-linux-gnu \2// RUN:   | FileCheck %s -check-prefix=CHECK-EXCEPTIONS \3// RUN:   -implicit-check-not="{{warning|error}}:"4// RUN: clang-tidy %s -checks="-*,bugprone-throwing-static-initialization" -- -DNONEXCEPTIONS -fno-exceptions -std=c++17 -target x86_64-pc-linux-gnu \5// RUN:   | FileCheck %s -allow-empty -check-prefix=CHECK-NONEXCEPTIONS \6// RUN:   -implicit-check-not="{{warning|error}}:"7 8struct S {9  S() noexcept(false);10};11 12struct T {13  T() noexcept;14};15 16struct U {17  U() {}18};19 20struct V {21  explicit V(const char *) {} // Can throw22};23 24struct Cleanup {25  ~Cleanup() {}26};27 28struct W {29  W(Cleanup c = {}) noexcept(false);30};31 32struct X {33  X(S = {}) noexcept;34};35 36struct Y {37  S s;38};39 40struct Z {41  T t;42};43 44int f();45int g() noexcept(false);46int h() noexcept(true);47 48struct UserConv_Bad {49  operator int() noexcept(false);50};51 52struct UserConv_Good {53  operator int() noexcept;54};55 56UserConv_Bad some_bad_func() noexcept;57UserConv_Good some_good_func() noexcept;58 59S s;60// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]61// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here62// CHECK-NONEXCEPTIONS-NOT: warning:63T t; // ok64U u;65// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught66// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here67// CHECK-NONEXCEPTIONS-NOT: warning:68V v("v");69// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught70// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here71// CHECK-NONEXCEPTIONS-NOT: warning:72W w;73// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught74// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here75// CHECK-NONEXCEPTIONS-NOT: warning:76X x1(S{});77// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'x1' with static storage duration may throw an exception that cannot be caught78// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here79// CHECK-NONEXCEPTIONS-NOT: warning:80X x2;81// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'x2' with static storage duration may throw an exception that cannot be caught82// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here83// CHECK-NONEXCEPTIONS-NOT: warning:84Y y;85// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'y' with static storage duration may throw an exception that cannot be caught86// CHECK-EXCEPTIONS: 36:8: note: possibly throwing constructor declared here87// CHECK-NONEXCEPTIONS-NOT: warning:88Z z;89 90int i = f();91// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'i' with static storage duration may throw an exception that cannot be caught92// CHECK-EXCEPTIONS: 44:5: note: possibly throwing function declared here93// CHECK-NONEXCEPTIONS-NOT: warning:94int j = g();95// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'j' with static storage duration may throw an exception that cannot be caught96// CHECK-EXCEPTIONS: 45:5: note: possibly throwing function declared here97// CHECK-NONEXCEPTIONS-NOT: warning:98int k = h();99int l = some_bad_func();100// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'l' with static storage duration may throw an exception that cannot be caught101// CHECK-EXCEPTIONS: 49:3: note: possibly throwing function declared here102// CHECK-NONEXCEPTIONS-NOT: warning:103int m = some_good_func();104 105typedef decltype(sizeof(int)) size_t;106inline void *operator new(size_t sz, void *here) noexcept { return here; }107char n[sizeof(int)];108int *o = new (n) int();109int *p = new int();110// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'p' with static storage duration may throw an exception that cannot be caught111// CHECK-NONEXCEPTIONS-NOT: warning:112 113thread_local S s3;114// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 's3' with thread_local storage duration may throw an exception that cannot be caught115// CHECK-NONEXCEPTIONS-NOT: warning:116thread_local T t3; // ok117thread_local U u3;118// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'u3' with thread_local storage duration may throw an exception that cannot be caught119// CHECK-NONEXCEPTIONS-NOT: warning:120thread_local V v3("v");121// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'v3' with thread_local storage duration may throw an exception that cannot be caught122// CHECK-NONEXCEPTIONS-NOT: warning:123thread_local W w3;124// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'w3' with thread_local storage duration may throw an exception that cannot be caught125// CHECK-NONEXCEPTIONS-NOT: warning:126 127void f(S s1, T t1, U u1, V v1, W w1) { // ok, ok, ok, ok, ok128  S s2; // ok129  T t2; // ok130  U u2; // ok131  V v2("v"); // ok132  W w2; // ok133 134  thread_local S s3; // ok135  thread_local T t3; // ok136  thread_local U u3; // ok137  thread_local V v3("v"); // ok138  thread_local W w3; // ok139 140  static S s4; // ok141  static T t4; // ok142  static U u4; // ok143  static V v4("v"); // ok144  static W w4; // ok145}146 147namespace {148S s;149// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]150// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here151// CHECK-NONEXCEPTIONS-NOT: warning:152T t; // ok153U u;154// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught155// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here156// CHECK-NONEXCEPTIONS-NOT: warning:157V v("v");158// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught159// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here160// CHECK-NONEXCEPTIONS-NOT: warning:161W w;162// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught163// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here164// CHECK-NONEXCEPTIONS-NOT: warning:165 166thread_local S s3;167// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 's3' with thread_local storage duration may throw an exception that cannot be caught168// CHECK-NONEXCEPTIONS-NOT: warning:169thread_local T t3; // ok170thread_local U u3;171// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'u3' with thread_local storage duration may throw an exception that cannot be caught172// CHECK-NONEXCEPTIONS-NOT: warning:173thread_local V v3("v");174// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'v3' with thread_local storage duration may throw an exception that cannot be caught175// CHECK-NONEXCEPTIONS-NOT: warning:176thread_local W w3;177// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'w3' with thread_local storage duration may throw an exception that cannot be caught178// CHECK-NONEXCEPTIONS-NOT: warning:179}; // namespace180 181class Statics {182  static S s; // warn when initialized183  static T t; // ok184  static U u; // warn when initialized185  static V v; // warn when initialized186  static W w; // warn when initialized187 188  void f(S s, T t, U u, V v) {189    S s2;      // ok190    T t2;      // ok191    U u2;      // ok192    V v2("v"); // ok193    W w2;      // ok194 195    thread_local S s3;      // ok196    thread_local T t3;      // ok197    thread_local U u3;      // ok198    thread_local V v3("v"); // ok199    thread_local W w3;      // ok200 201    static S s4;      // ok202    static T t4;      // ok203    static U u4;      // ok204    static V v4("v"); // ok205    static W w4;      // ok206  }207};208 209S Statics::s;210// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]211// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here212// CHECK-NONEXCEPTIONS-NOT: warning:213T Statics::t;214U Statics::u;215// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught216// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here217// CHECK-NONEXCEPTIONS-NOT: warning:218V Statics::v("v");219// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught220// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here221// CHECK-NONEXCEPTIONS-NOT: warning:222W Statics::w;223// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught224// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here225// CHECK-NONEXCEPTIONS-NOT: warning:226 227#ifndef NONEXCEPTIONS228namespace pr35457 {229constexpr int foo(int x) { if (x <= 0) throw 12; return x; }230 231constexpr int bar = foo(1); // OK232// CHECK-EXCEPTIONS-NOT: warning: initialization of 'bar' with static storage233int baz = foo(0); // Not OK; throws at runtime when exceptions are enabled.234// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'baz' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]235// CHECK-EXCEPTIONS: :[[@LINE-6]]:15: note: possibly throwing function declared here236} // namespace pr35457237#endif // NONEXCEPTIONS238 239namespace pr39777 {240struct S { S(); };241struct T { T() noexcept; };242 243auto Okay1 = []{ S s; };244auto Okay2 = []{ (void)new int; };245auto NotOkay1 = []{ S s; return 12; }(); // Because the lambda call is not noexcept246// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay1' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]247// CHECK-EXCEPTIONS: :[[@LINE-7]]:12: note: possibly throwing constructor declared here248auto NotOkay2 = []() noexcept { S s; return 12; }(); // Because S::S() is not noexcept249// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay2' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]250// CHECK-EXCEPTIONS: :[[@LINE-10]]:12: note: possibly throwing constructor declared here251auto Okay3 = []() noexcept { T t; return t; }();252 253struct U {254  U() noexcept;255  auto getBadLambda() const noexcept {256    return []{ S s; return s; };257  }258};259auto Okay4 = []{ U u; return u.getBadLambda(); }();260auto NotOkay3 = []() noexcept { U u; return u.getBadLambda(); }()(); // Because the lambda returned and called is not noexcept261// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay3' with static storage duration may throw an exception that cannot be caught [bugprone-throwing-static-initialization]262// CHECK-EXCEPTIONS: :[[@LINE-6]]:12: note: possibly throwing function declared here263 264#ifndef NONEXCEPTIONS265struct Bad {266  Bad() {267    throw 12;268  }269};270 271static auto NotOkay4 = [bad = Bad{}](){};272// FIXME: the above should be diagnosed because the capture init can trigger273// an exception when constructing the Bad object.274#endif // NONEXCEPTIONS275}276