1+ #include < cstdint>
2+ #include < memory>
3+ #include < mutex>
4+
5+ std::mutex g1;
6+ std::mutex g2;
7+
8+ void f1 (std::unique_lock<std::mutex> l1) {
9+ // Function parameter for testing compliant cases
10+ }
11+
12+ void test_explicit_type_conversion_expression_statement () {
13+ // Compliant cases - declarations
14+ std::unique_lock<std::mutex>l1 (g1);// COMPLIANT
15+ std::unique_lock<std::mutex> l2{g1};// COMPLIANT
16+ std::unique_lock<std::mutex>(l3);// COMPLIANT - declaration with redundant
17+ // parentheses around variable name
18+
19+ // Non-compliant cases - explicit type conversions as expression statements
20+ std::unique_lock<std::mutex>{g1};// NON_COMPLIANT
21+ std::scoped_lock{g1};// NON_COMPLIANT
22+ std::scoped_lock (g1, g2);// NON_COMPLIANT
23+ std::lock_guard<std::mutex>{g1};// NON_COMPLIANT
24+
25+ // Compliant cases - type conversions not as expression statements
26+ f1 (std::unique_lock<std::mutex>(g1));// COMPLIANT
27+ f1 (std::unique_lock<std::mutex>{g1});// COMPLIANT
28+ auto l4 = std::unique_lock<std::mutex>(g1);// COMPLIANT
29+ auto l5 = std::unique_lock<std::mutex>{g1};// COMPLIANT
30+
31+ // The extractor has a bug as of 2.20.7 which means it does not parse
32+ // these two cases separately. We choose to ignore if statements, which
33+ // can cause false negatives, but will prevent false positives
34+ if (std::unique_lock<std::mutex>(g1);true ) {// COMPLIANT - init-statement
35+ }
36+ if (std::unique_lock<std::mutex>{g1};true ) {// NON_COMPLIANT[FALSE_NEGATIVE]
37+ }
38+
39+ for (std::unique_lock<std::mutex>(g1);;) {// COMPLIANT - init-statement
40+ break ;
41+ }
42+ for (std::unique_lock<std::mutex>{g1};;) {// NON_COMPLIANT - init-statement
43+ break ;
44+ }
45+ }
46+
47+ void test_primitive_type_conversions () {
48+ // Non-compliant cases with primitive types
49+ std::int32_t (42 );// NON_COMPLIANT
50+ float (3.14 );// NON_COMPLIANT
51+ double (2.71 );// NON_COMPLIANT
52+ bool (true );// NON_COMPLIANT
53+
54+ // Compliant cases
55+ auto l1 =std::int32_t (42 );// COMPLIANT
56+ auto l2 =float (3.14 );// COMPLIANT
57+ std::int32_t l3 (42 );// COMPLIANT - declaration
58+ std::int32_t l4{42 };// COMPLIANT - declaration
59+ }
60+
61+ struct CustomType {
62+ CustomType (std::int32_t ) {}
63+ };
64+ void test_custom_types () {
65+ // Non-compliant cases
66+ CustomType (42 );// NON_COMPLIANT
67+ CustomType{42 };// NON_COMPLIANT
68+
69+ // Compliant cases
70+ CustomTypel1 (42 );// COMPLIANT - declaration
71+ CustomType l2{42 };// COMPLIANT - declaration
72+ auto l3 =CustomType (42 );// COMPLIANT
73+ auto l4 = CustomType{42 };// COMPLIANT
74+ }