Files
TheRock/compiler/amd-llvm/clang-tools-extra/test/clang-tidy/checkers/misc/static-initialization-cycle.cpp
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

286 lines
9.3 KiB
C++

// RUN: %check_clang_tidy %s misc-static-initialization-cycle %t -- -- -fno-delayed-template-parsing -fexceptions
namespace simple_cycle {
struct S { static int A; };
int B = S::A;
int S::A = B;
}
// CHECK-NOTES: :[[@LINE-3]]:5: warning: static variable initialization cycle detected involving 'B'
// CHECK-NOTES: :[[@LINE-4]]:9: note: value of 'A' may be used to initialize variable 'B' here
// CHECK-NOTES: :[[@LINE-4]]:12: note: value of 'B' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-6]]:5: note: possible cyclical initialization: B -> A -> B
namespace self_init {
struct S { static int A; };
int S::A = S::A;
}
// CHECK-NOTES: :[[@LINE-3]]:23: warning: static variable initialization cycle detected involving 'A'
// CHECK-NOTES: :[[@LINE-3]]:12: note: value of 'A' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-5]]:23: note: possible cyclical initialization: A -> A
namespace cycle_at_end {
struct S { static int A; };
int B = 1;
int C = B + S::A;
int S::A = C;
}
// CHECK-NOTES: :[[@LINE-3]]:5: warning: static variable initialization cycle detected involving 'C'
// CHECK-NOTES: :[[@LINE-4]]:13: note: value of 'A' may be used to initialize variable 'C' here
// CHECK-NOTES: :[[@LINE-4]]:12: note: value of 'C' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-6]]:5: note: possible cyclical initialization: C -> A -> C
namespace cycle_at_start {
struct S { static int A; };
int B = S::A;
int S::A = B;
int C = B + 1;
}
// CHECK-NOTES: :[[@LINE-4]]:5: warning: static variable initialization cycle detected involving 'B'
// CHECK-NOTES: :[[@LINE-5]]:9: note: value of 'A' may be used to initialize variable 'B' here
// CHECK-NOTES: :[[@LINE-5]]:12: note: value of 'B' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-7]]:5: note: possible cyclical initialization: B -> A -> B
namespace multiple_cycle {
struct S { static int A; };
int B = S::A;
int C = S::A;
int S::A = B + C;
}
// CHECK-NOTES: :[[@LINE-3]]:5: warning: static variable initialization cycle detected involving 'C'
// CHECK-NOTES: :[[@LINE-4]]:9: note: value of 'A' may be used to initialize variable 'C' here
// CHECK-NOTES: :[[@LINE-4]]:16: note: value of 'C' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-6]]:5: note: possible cyclical initialization: C -> A -> C
namespace long_cycle {
struct S { static int A; };
int B = S::A;
int C = B + 1;
int S::A = C;
}
// CHECK-NOTES: :[[@LINE-4]]:5: warning: static variable initialization cycle detected involving 'B'
// CHECK-NOTES: :[[@LINE-5]]:9: note: value of 'A' may be used to initialize variable 'B' here
// CHECK-NOTES: :[[@LINE-4]]:12: note: value of 'C' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-6]]:9: note: value of 'B' may be used to initialize variable 'C' here
// CHECK-NOTES: :[[@LINE-8]]:5: note: possible cyclical initialization: B -> A -> C -> B
namespace no_cycle {
int A = 2;
int B = A;
int C = B + A;
}
namespace init_expr {
struct S { static int A; };
int f1(int X, int Y);
int B = S::A + 1;
int S::A = f1(B, 2);
}
// CHECK-NOTES: :[[@LINE-3]]:5: warning: static variable initialization cycle detected involving 'B'
// CHECK-NOTES: :[[@LINE-4]]:9: note: value of 'A' may be used to initialize variable 'B' here
// CHECK-NOTES: :[[@LINE-4]]:15: note: value of 'B' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-6]]:5: note: possible cyclical initialization: B -> A -> B
namespace func_static_ref_1 {
struct S { static int A; };
int f1() {
return S::A;
}
int S::A = f1();
}
// CHECK-NOTES: :[[@LINE-6]]:23: warning: static variable initialization cycle detected involving 'A'
// CHECK-NOTES: :[[@LINE-5]]:10: note: value of 'A' may be used to compute result of 'f1'
// CHECK-NOTES: :[[@LINE-4]]:12: note: result of 'f1' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-9]]:23: note: possible cyclical initialization: f1 -> A -> f1
namespace func_static_ref_2 {
struct S { static int A; };
int f1() {
static int X = S::A;
return 1;
}
int S::A = f1();
}
// CHECK-NOTES: :[[@LINE-7]]:23: warning: static variable initialization cycle detected involving 'A'
// CHECK-NOTES: :[[@LINE-6]]:18: note: value of 'A' may be used to compute result of 'f1'
// CHECK-NOTES: :[[@LINE-4]]:12: note: result of 'f1' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-10]]:23: note: possible cyclical initialization: f1 -> A -> f1
namespace func_static_ref_3 {
struct S { static int A; };
int f1() {
S::A = 3;
return 34;
}
int S::A = f1();
}
namespace catch_all_handler {
void f() {
try {
} catch (...) {
}
}
} // catch_all_handler
namespace recursive_calls {
int f2();
int f1() {
return f2();
}
int f2() {
return f1();
}
int A = f1();
}
namespace use_static_compile_time {
int f() {
static int A = f();
static decltype(A) B = 2;
return sizeof(A) + B;
}
}
namespace static_var_recursive_init {
int f(int i) {
static int A = f(1);
if (i == 1)
return 1;
return A + i;
}
}
// CHECK-NOTES: :[[@LINE-6]]:14: warning: static variable initialization cycle detected involving 'A'
// CHECK-NOTES: :[[@LINE-7]]:18: note: result of 'f' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-5]]:10: note: value of 'A' may be used to compute result of 'f'
// CHECK-NOTES: :[[@LINE-9]]:14: note: possible cyclical initialization: A -> f -> A
namespace singleton {
struct S { int X; };
S *get_S() {
static S *TheS;
if (!TheS) {
TheS = new S;
}
return TheS;
}
}
namespace compound_assign_in_func {
struct S { static int A; };
int f() {
int local = 0;
local += S::A;
return local;
}
int S::A = f();
}
// CHECK-NOTES: :[[@LINE-8]]:23: warning: static variable initialization cycle detected involving 'A'
// CHECK-NOTES: :[[@LINE-6]]:12: note: value of 'A' may be used to compute result of 'f'
// CHECK-NOTES: :[[@LINE-4]]:12: note: result of 'f' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-11]]:23: note: possible cyclical initialization: f -> A -> f
namespace compound_assign_lhs {
struct S { static int A; };
int f();
int B = S::A + f();
int f() {
S::A -= B;
return 1;
}
}
// CHECK-NOTES: :[[@LINE-6]]:5: warning: static variable initialization cycle detected involving 'B'
// CHECK-NOTES: :[[@LINE-5]]:11: note: value of 'B' may be used to compute result of 'f'
// CHECK-NOTES: :[[@LINE-8]]:16: note: result of 'f' may be used to initialize variable 'B' here
// CHECK-NOTES: :[[@LINE-9]]:5: note: possible cyclical initialization: f -> B -> f
namespace template_test {
template <class T>
struct S {
static T f1();
static T A;
};
template <class T>
T S<T>::A = f1();
template <class T>
T S<T>::f1() {
return A;
}
S<int> X;
}
// CHECK-NOTES: :[[@LINE-11]]:12: warning: static variable initialization cycle detected involving 'A'
// CHECK-NOTES: :[[@LINE-6]]:10: note: value of 'A' may be used to compute result of 'f1'
// CHECK-NOTES: :[[@LINE-10]]:13: note: result of 'f1' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-14]]:12: note: possible cyclical initialization: f1 -> A -> f1
namespace test_lambda_1 {
struct S { static int A; };
int B = []() { return S::A; }();
int S::A = B;
}
// CHECK-NOTES: :[[@LINE-3]]:5: warning: static variable initialization cycle detected involving 'B'
// CHECK-NOTES: :[[@LINE-4]]:23: note: value of 'A' may be used to initialize variable 'B' here
// CHECK-NOTES: :[[@LINE-4]]:12: note: value of 'B' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-6]]:5: note: possible cyclical initialization: B -> A -> B
namespace test_lambda_2 {
struct S { static int A; };
auto B = []() { return S::A; };
int S::A = B();
}
// this is not found by the check
// value of 'A' is not needed to initialize 'B'
// the check does not maintain values of variables (to find the stored
// lambda and relation to 'A')
namespace test_lambda_3 {
struct S { static int A; };
int f() {
return []() { return 2 * S::A; }() + 3;
}
int B = f();
int S::A = B;
}
// CHECK-NOTES: :[[@LINE-3]]:5: warning: static variable initialization cycle detected involving 'B'
// CHECK-NOTES: :[[@LINE-6]]:28: note: value of 'A' may be used to compute result of 'f'
// CHECK-NOTES: :[[@LINE-4]]:12: note: value of 'B' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-6]]:9: note: result of 'f' may be used to initialize variable 'B' here
// CHECK-NOTES: :[[@LINE-7]]:5: note: possible cyclical initialization: f -> A -> B -> f
namespace test_lambda_4 {
template <class L>
void f1(L) {};
struct S { static int A; };
int f() {
f1([]() { return 2 * S::A; });
return 1;
}
int B = f();
int S::A = B;
}
namespace mixed_cycle {
struct S { static int A; };
int B = S::A;
int f_b() { return B + 1; }
int C = f_b();
int D = C + 1;
int S::A = []() { return D + 1; }();
}
// CHECK-NOTES: :[[@LINE-6]]:5: warning: static variable initialization cycle detected involving 'B'
// CHECK-NOTES: :[[@LINE-7]]:9: note: value of 'A' may be used to initialize variable 'B' here
// CHECK-NOTES: :[[@LINE-4]]:26: note: value of 'D' may be used to initialize variable 'A' here
// CHECK-NOTES: :[[@LINE-6]]:9: note: value of 'C' may be used to initialize variable 'D' here
// CHECK-NOTES: :[[@LINE-8]]:9: note: result of 'f_b' may be used to initialize variable 'C' here
// CHECK-NOTES: :[[@LINE-10]]:20: note: value of 'B' may be used to compute result of 'f_b'
// CHECK-NOTES: :[[@LINE-12]]:5: note: possible cyclical initialization: B -> A -> D -> C -> f_b -> B