-
Notifications
You must be signed in to change notification settings - Fork 77
Expand file tree
/
Copy pathtest.cpp
More file actions
160 lines (131 loc) · 3.58 KB
/
test.cpp
File metadata and controls
160 lines (131 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include <cstdint>
#include <string>
#include <utility>
int foo() { return 1; }
// A copy of 8.2,2 test.cpp, but with different cases compliant/non-compliant
void test_c_style_cast() {
double f = 3.14;
std::uint32_t n1 = (std::uint32_t)f; // NON_COMPLIANT - C-style cast
std::uint32_t n2 = unsigned(f); // COMPLIANT[FALSE_POSITIVE]
std::uint8_t n3 = 1;
std::uint8_t n4 = 1;
std::uint8_t n5 = n3 + n4; // ignored, implicit casts
(void)foo(); // NON_COMPLIANT
}
class A {
public:
virtual void f1() {}
};
class B : A {
public:
virtual void f1() {}
};
class C {
void f1() {}
};
void test_cpp_style_cast() {
// These cases may contravene other rules, but are marked as COMPLIANT for
// this rule
A a1;
const A *a2 = &a1;
A *a3 = const_cast<A *>(a2); // COMPLIANT
B *b = dynamic_cast<B *>(a3); // COMPLIANT
C *c = reinterpret_cast<C *>(a3); // COMPLIANT
std::int16_t n8 = 0;
std::int32_t n9 = static_cast<std::int32_t>(n8); // COMPLIANT
static_cast<void>(foo()); // COMPLIANT
}
class A5_2_2a {
public:
template <typename... As>
static void Foo(const std::string &name, As &&...rest) {
Fun(Log(
std::forward<As>(rest)...)); // COMPLIANT - reported as a false positive
}
template <typename... As> static std::string Log(As &&...tail) {
return std::string();
}
static void Fun(const std::string &message) {}
};
class A5_2_2 final {
public:
void f(const std::string &s) const { A5_2_2a::Foo("name", "x", "y", "z"); }
};
void a5_2_2_test() {
A5_2_2 a;
a.f("");
}
#define ADD_ONE(x) ((int)x) + 1
#define NESTED_ADD_ONE(x) ADD_ONE(x)
#define NO_CAST_ADD_ONE(x) x + 1
#include "macro_c_style_casts.h"
void test_macro_cast() {
ADD_ONE(1); // NON_COMPLIANT - expansion of user-defined macro creates
// c-style cast
NESTED_ADD_ONE(1); // NON_COMPLIANT - expansion of user-defined macro creates
// c-style cast
LIBRARY_ADD_TWO(1); // COMPLIANT - macro generating the cast is defined in a
// library, and is not modifiable by the user
LIBRARY_NESTED_ADD_TWO(1); // COMPLIANT - macro generating the cast is defined
// in a library, and is not modifiable by the user
NO_CAST_ADD_ONE((int)1.0); // NON_COMPLIANT - cast in argument to macro
LIBRARY_NO_CAST_ADD_TWO((int)1.0); // NON_COMPLIANT - library macro with
// c-style cast in argument, written by
// user so should be reported
}
class D {
public:
D(int x) : fx(x), fy(0) {}
D(int x, int y) : fx(x), fy(y) {}
private:
int fx;
int fy;
};
D testNonFunctionalCast() {
return (D)1; // NON_COMPLIANT[FALSE_NEGATIVE]
}
D testFunctionalCast() {
return D(1); // COMPLIANT
}
D testFunctionalCastMulti() {
return D(1, 2); // COMPLIANT
}
template <typename T> T testFunctionalCastTemplate() {
return T(1); // COMPLIANT[FALSE_POSITIVE]
}
template <typename T> T testFunctionalCastTemplateMulti() {
return T(1, 2); // COMPLIANT
}
void testFunctionalCastTemplateUse() {
testFunctionalCastTemplate<D>();
testFunctionalCastTemplate<int>();
testFunctionalCastTemplateMulti<D>();
}
template <typename T> class E {
public:
class F {
public:
F(int x) : fx(x), fy(0) {}
F(int x, int y) : fx(x), fy(y) {}
private:
int fx;
int fy;
};
F f() {
return F(1); // COMPLIANT
}
D d() {
return D(1); // COMPLIANT
}
int i() {
double f = 3.14;
return (unsigned int)f; // NON_COMPLIANT
}
};
class G {};
void testE() {
E<G> e;
e.f();
e.d();
e.i();
}