brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.3 KiB · 8ce4299 Raw
117 lines · cpp
1// RUN: %check_clang_tidy %s cppcoreguidelines-interfaces-global-init %t2 3constexpr int makesInt() { return 3; }4constexpr int takesInt(int i) { return i + 1; }5constexpr int takesIntPtr(int *i) { return *i; }6 7extern int ExternGlobal;8static int GlobalScopeBadInit1 = ExternGlobal;9// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'10static int GlobalScopeBadInit2 = takesInt(ExternGlobal);11// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'12static int GlobalScopeBadInit3 = takesIntPtr(&ExternGlobal);13// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'14static int GlobalScopeBadInit4 = 3 * (ExternGlobal + 2);15// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'16 17#if __cplusplus >= 202002L18extern constinit int ExternConstinitGlobal;19static int GlobalScopeConstinit1 = ExternConstinitGlobal;20static int GlobalScopeConstinit2 = takesInt(ExternConstinitGlobal);21static int GlobalScopeConstinit3 = takesIntPtr(&ExternConstinitGlobal);22static int GlobalScopeConstinit4 = 3 * (ExternConstinitGlobal + 2);23#endif24 25namespace ns {26static int NamespaceScope = makesInt();27static int NamespaceScopeBadInit = takesInt(ExternGlobal);28// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'29 30#if __cplusplus >= 202002L31static int NamespaceScopeConstinit = takesInt(ExternConstinitGlobal);32#endif33 34struct A {35  static int ClassScope;36  static int ClassScopeBadInit;37};38 39int A::ClassScopeBadInit = takesInt(ExternGlobal);40// CHECK-MESSAGES: [[@LINE-1]]:8: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'41 42static int FromClassBadInit = takesInt(A::ClassScope);43// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ClassScope'44 45#if __cplusplus >= 202002L46struct B {47  static constinit int ClassScopeConstinit;48  static int ClassScopeFromConstinit;49};50 51int B::ClassScopeFromConstinit = takesInt(ExternConstinitGlobal);52static int FromClassScopeConstinit = takesInt(B::ClassScopeConstinit);53#endif54 55} // namespace ns56 57// "const int B::I;" is fine, it just ODR-defines B::I. See [9.4.3] Static58// members [class.static]. However the ODR-definitions are not in the right59// order (C::I after C::J, see [3.6.2.3]).60class B1 {61  static const int I = 0;62  static const int J = I;63};64const int B1::J;65// CHECK-MESSAGES: [[@LINE-1]]:15: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'I'66const int B1::I;67 68#if __cplusplus >= 202002L69class D {70  static const constinit int I = 0;71  static const int J = I;72};73 74const int D::J;75const int D::I;76#endif77 78void f() {79  // This is fine, it's executed after dynamic initialization occurs.80  static int G = takesInt(ExternGlobal);81}82 83// Declaration then definition then usage is fine.84extern int ExternGlobal2;85extern int ExternGlobal2;86int ExternGlobal2 = 123;87static int GlobalScopeGoodInit1 = ExternGlobal2;88 89 90// Defined global variables are fine:91static int GlobalScope = makesInt();92static int GlobalScopeGoodInit2 = takesInt(GlobalScope);93static int GlobalScope2 = takesInt(ns::NamespaceScope);94// Enums are fine.95enum Enum { kEnumValue = 1 };96static int GlobalScopeFromEnum = takesInt(kEnumValue);97 98// Leave constexprs alone.99extern constexpr int GlobalScopeConstexpr = makesInt();100static constexpr int GlobalScopeConstexprOk =101    takesInt(GlobalScopeConstexpr);102 103// This is a pretty common instance: People are usually not using constexpr, but104// this is what they should write:105static constexpr const char kValue[] = "value";106constexpr int Fingerprint(const char *value) { return 0; }107static int kFingerprint = Fingerprint(kValue);108 109// This is fine because the ODR-definitions are in the right order (C::J after110// C::I).111class B2 {112  static const int I = 0;113  static const int J = I;114};115const int B2::I;116const int B2::J;117