adlint 1.8.10 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. data/ChangeLog +261 -3
  2. data/MANIFEST +25 -1
  3. data/NEWS +25 -5
  4. data/Rakefile +11 -0
  5. data/TODO +0 -1
  6. data/etc/mesg.d/en_US/messages.yml +1 -1
  7. data/etc/mesg.d/ja_JP/messages.yml +1 -1
  8. data/features/message_detection/W0001.feature +41 -0
  9. data/features/message_detection/W0002.feature +68 -0
  10. data/features/message_detection/W0003.feature +134 -0
  11. data/features/message_detection/W0007.feature +264 -0
  12. data/features/message_detection/W0010.feature +75 -0
  13. data/features/message_detection/W0013.feature +189 -0
  14. data/features/message_detection/W0109.feature +50 -0
  15. data/features/message_detection/W0583.feature +30 -0
  16. data/features/message_detection/W0606.feature +20 -0
  17. data/features/message_detection/W0698.feature +20 -0
  18. data/features/message_detection/W0699.feature +21 -0
  19. data/features/message_detection/W0703.feature +73 -0
  20. data/features/message_detection/W0716.feature +67 -0
  21. data/features/message_detection/W0717.feature +64 -0
  22. data/features/message_detection/W0718.feature +64 -0
  23. data/features/message_detection/W0723.feature +18 -0
  24. data/features/message_detection/W1031.feature +328 -0
  25. data/features/step_definitions/message_detection_steps.rb +45 -0
  26. data/features/support/env.rb +58 -0
  27. data/lib/adlint/c/branch.rb +16 -23
  28. data/lib/adlint/c/code.rb +1 -12
  29. data/lib/adlint/c/conv.rb +4 -4
  30. data/lib/adlint/c/ctrlexpr.rb +10 -6
  31. data/lib/adlint/c/domain.rb +2 -2
  32. data/lib/adlint/c/expr.rb +11 -33
  33. data/lib/adlint/c/format.rb +6 -6
  34. data/lib/adlint/c/interp.rb +137 -80
  35. data/lib/adlint/c/mediator.rb +5 -2
  36. data/lib/adlint/c/message.rb +123 -140
  37. data/lib/adlint/c/message_shima.rb +44 -0
  38. data/lib/adlint/c/object.rb +93 -26
  39. data/lib/adlint/c/option.rb +53 -0
  40. data/lib/adlint/c/phase.rb +4 -1
  41. data/lib/adlint/c/type.rb +112 -46
  42. data/lib/adlint/c.rb +1 -0
  43. data/lib/adlint/version.rb +3 -3
  44. data/share/doc/developers_guide_ja.html +3 -3
  45. data/share/doc/developers_guide_ja.texi +1 -1
  46. data/share/doc/users_guide_en.html +35 -28
  47. data/share/doc/users_guide_en.texi +30 -22
  48. data/share/doc/users_guide_ja.html +35 -31
  49. data/share/doc/users_guide_ja.texi +30 -24
  50. data/spec/adlint/c/type_spec.rb +110 -0
  51. data/spec/conf.d/default_traits.yml +216 -0
  52. data/spec/conf.d/empty_cinit.h +11 -0
  53. data/spec/conf.d/empty_pinit.h +11 -0
  54. data/spec/spec_helper.rb +49 -0
  55. metadata +27 -3
  56. data/spec/MUST_WRITE_SPECS_WITH_RSPEC +0 -0
@@ -0,0 +1,264 @@
1
+ Feature: W0007
2
+
3
+ W0007 detects that the previous case or default clause does not have a
4
+ jump-statement at the last statement.
5
+
6
+ Scenario: no jump-statement in the previous case clause
7
+ Given a target source named "W0007.c" with:
8
+ """
9
+ static int foo(const int i)
10
+ {
11
+ int j;
12
+
13
+ switch (i) {
14
+ case 1:
15
+ j = 1;
16
+ break;
17
+ case 2:
18
+ j = 2;
19
+ case 3: /* W0007 */
20
+ j = 3;
21
+ break;
22
+ default:
23
+ j = 0;
24
+ break;
25
+ }
26
+
27
+ return j;
28
+ }
29
+ """
30
+ When I successfully run `adlint W0007.c` on noarch
31
+ Then the output should exactly match with:
32
+ | mesg | line | column |
33
+ | W0629 | 1 | 12 |
34
+ | W0007 | 11 | 5 |
35
+ | W0628 | 1 | 12 |
36
+
37
+ Scenario: a break-statement at the middle of the previous case clause
38
+ Given a target source named "W0007.c" with:
39
+ """
40
+ extern int rand(void);
41
+
42
+ static int foo(const int i)
43
+ {
44
+ int j;
45
+
46
+ switch (i) {
47
+ case 1:
48
+ j = 1;
49
+ break;
50
+ case 2:
51
+ if (rand() == 0) {
52
+ j = -1;
53
+ break;
54
+ }
55
+ j = 2;
56
+ case 3: /* W0007 */
57
+ j = 3;
58
+ break;
59
+ default:
60
+ j = 0;
61
+ break;
62
+ }
63
+
64
+ return j;
65
+ }
66
+ """
67
+ When I successfully run `adlint W0007.c` on noarch
68
+ Then the output should exactly match with:
69
+ | mesg | line | column |
70
+ | W0118 | 1 | 12 |
71
+ | W0629 | 3 | 12 |
72
+ | W0007 | 17 | 5 |
73
+ | W0532 | 14 | 13 |
74
+ | W0628 | 3 | 12 |
75
+
76
+ Scenario: a break-statement at the bottom of the previous case clause
77
+ Given a target source named "W0007.c" with:
78
+ """
79
+ static int foo(const int i)
80
+ {
81
+ int j;
82
+
83
+ switch (i) {
84
+ case 1:
85
+ j = 1;
86
+ break;
87
+ case 2:
88
+ j = 2;
89
+ break;
90
+ case 3: /* OK */
91
+ j = 3;
92
+ break;
93
+ default:
94
+ j = 0;
95
+ break;
96
+ }
97
+
98
+ return j;
99
+ }
100
+ """
101
+ When I successfully run `adlint W0007.c` on noarch
102
+ Then the output should exactly match with:
103
+ | mesg | line | column |
104
+ | W0629 | 1 | 12 |
105
+ | W0628 | 1 | 12 |
106
+
107
+ Scenario: a return-statement at the bottom of the previous case clause
108
+ Given a target source named "W0007.c" with:
109
+ """
110
+ static int foo(const int i)
111
+ {
112
+ int j;
113
+
114
+ switch (i) {
115
+ case 1:
116
+ j = 1;
117
+ break;
118
+ case 2:
119
+ j = 2;
120
+ return j;
121
+ case 3: /* OK */
122
+ j = 3;
123
+ break;
124
+ default:
125
+ j = 0;
126
+ break;
127
+ }
128
+
129
+ return j;
130
+ }
131
+ """
132
+ When I successfully run `adlint W0007.c` on noarch
133
+ Then the output should exactly match with:
134
+ | mesg | line | column |
135
+ | W0629 | 1 | 12 |
136
+ | W0628 | 1 | 12 |
137
+
138
+ Scenario: no jump-statement in the previous default clause
139
+ Given a target source named "W0007.c" with:
140
+ """
141
+ static int foo(const int i)
142
+ {
143
+ int j;
144
+
145
+ switch (i) {
146
+ case 1:
147
+ j = 1;
148
+ break;
149
+ default:
150
+ j = 2;
151
+ case 3: /* W0007 */
152
+ j = 3;
153
+ break;
154
+ }
155
+
156
+ return j;
157
+ }
158
+ """
159
+ When I successfully run `adlint W0007.c` on noarch
160
+ Then the output should exactly match with:
161
+ | mesg | line | column |
162
+ | W0629 | 1 | 12 |
163
+ | W0007 | 11 | 5 |
164
+ | W0538 | 9 | 5 |
165
+ | W0628 | 1 | 12 |
166
+
167
+ Scenario: a break-statement at the middle of the previous default clause
168
+ Given a target source named "W0007.c" with:
169
+ """
170
+ extern int rand(void);
171
+
172
+ static int foo(const int i)
173
+ {
174
+ int j;
175
+
176
+ switch (i) {
177
+ case 1:
178
+ j = 1;
179
+ break;
180
+ default:
181
+ if (rand() == 0) {
182
+ j = -1;
183
+ break;
184
+ }
185
+ j = 2;
186
+ case 3: /* W0007 */
187
+ j = 3;
188
+ break;
189
+ }
190
+
191
+ return j;
192
+ }
193
+ """
194
+ When I successfully run `adlint W0007.c` on noarch
195
+ Then the output should exactly match with:
196
+ | mesg | line | column |
197
+ | W0118 | 1 | 12 |
198
+ | W0629 | 3 | 12 |
199
+ | W0007 | 17 | 5 |
200
+ | W0532 | 14 | 13 |
201
+ | W0538 | 11 | 5 |
202
+ | W0628 | 3 | 12 |
203
+
204
+ Scenario: a break-statement at the bottom of the previous default clause
205
+ Given a target source named "W0007.c" with:
206
+ """
207
+ static int foo(const int i)
208
+ {
209
+ int j;
210
+
211
+ switch (i) {
212
+ case 1:
213
+ j = 1;
214
+ break;
215
+ case 2:
216
+ j = 2;
217
+ break;
218
+ case 3: /* OK */
219
+ j = 3;
220
+ break;
221
+ default:
222
+ j = 0;
223
+ break;
224
+ }
225
+
226
+ return j;
227
+ }
228
+ """
229
+ When I successfully run `adlint W0007.c` on noarch
230
+ Then the output should exactly match with:
231
+ | mesg | line | column |
232
+ | W0629 | 1 | 12 |
233
+ | W0628 | 1 | 12 |
234
+
235
+ Scenario: a return-statement at the bottom of the previous default clause
236
+ Given a target source named "W0007.c" with:
237
+ """
238
+ static int foo(const int i)
239
+ {
240
+ int j;
241
+
242
+ switch (i) {
243
+ case 1:
244
+ j = 1;
245
+ break;
246
+ default:
247
+ j = 2;
248
+ return j;
249
+ case 3: /* OK */
250
+ j = 3;
251
+ break;
252
+ }
253
+
254
+ return j;
255
+ }
256
+ """
257
+ When I successfully run `adlint W0007.c` on noarch
258
+ Then the output should exactly match with:
259
+ | mesg | line | column |
260
+ | W0629 | 1 | 12 |
261
+ | W0538 | 9 | 5 |
262
+ | W0628 | 1 | 12 |
263
+
264
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,75 @@
1
+ Feature: W0010
2
+
3
+ W0010 detects that a side-effect may occur in the conditional-expression.
4
+
5
+ Scenario: postfix-increment-expression and postfix-decrement-expression
6
+ Given a target source named "W0010.c" with:
7
+ """
8
+ static int foo(int a, int b)
9
+ {
10
+ return (a > 0) ? b++ : b--; /* W0010 */
11
+ }
12
+ """
13
+ When I successfully run `adlint W0010.c` on noarch
14
+ Then the output should exactly match with:
15
+ | mesg | line | column |
16
+ | W0597 | 3 | 20 |
17
+ | W0104 | 1 | 20 |
18
+ | W0629 | 1 | 12 |
19
+ | W0010 | 3 | 20 |
20
+ | W0628 | 1 | 12 |
21
+
22
+ Scenario: object-specifier and postfix-decrement-expression
23
+ Given a target source named "W0010.c" with:
24
+ """
25
+ static int foo(int a, int b)
26
+ {
27
+ return (a > 0) ? b : b--; /* W0010 */
28
+ }
29
+ """
30
+ When I successfully run `adlint W0010.c` on noarch
31
+ Then the output should exactly match with:
32
+ | mesg | line | column |
33
+ | W0104 | 1 | 20 |
34
+ | W0629 | 1 | 12 |
35
+ | W0010 | 3 | 20 |
36
+ | W0086 | 3 | 20 |
37
+ | W0628 | 1 | 12 |
38
+
39
+ Scenario: function-call-expression and constant-specifier
40
+ Given a target source named "W0010.c" with:
41
+ """
42
+ static int foo(int a, int b)
43
+ {
44
+ return (a > 0) ? foo(1, b) : 0; /* W0010 */
45
+ }
46
+ """
47
+ When I successfully run `adlint W0010.c` on noarch
48
+ Then the output should exactly match with:
49
+ | mesg | line | column |
50
+ | W0556 | 3 | 25 |
51
+ | W0104 | 1 | 20 |
52
+ | W0104 | 1 | 27 |
53
+ | W0010 | 3 | 20 |
54
+ | W0086 | 3 | 20 |
55
+ | W0555 | 1 | 12 |
56
+
57
+ Scenario: additive-expression and multiplicative-expression
58
+ Given a target source named "W0010.c" with:
59
+ """
60
+ static int foo(int a, int b)
61
+ {
62
+ return (a > 0) ? b / a : a + b; /* OK */
63
+ }
64
+ """
65
+ When I successfully run `adlint W0010.c` on noarch
66
+ Then the output should exactly match with:
67
+ | mesg | line | column |
68
+ | W0723 | 3 | 32 |
69
+ | W0104 | 1 | 20 |
70
+ | W0104 | 1 | 27 |
71
+ | W0629 | 1 | 12 |
72
+ | W0501 | 3 | 12 |
73
+ | W0628 | 1 | 12 |
74
+
75
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,189 @@
1
+ Feature: W0013
2
+
3
+ W0013 detects that a continue-statement is used in iteration-statement.
4
+
5
+ Scenario: a continue-statement in for-statement
6
+ Given a target source named "W0013.c" with:
7
+ """
8
+ static void foo(void)
9
+ {
10
+ int i;
11
+ int j;
12
+
13
+ for (i = 1, j = 0; i < 20; i++) {
14
+ j += 2;
15
+ if ((j % i) == 3) {
16
+ continue; /* W0013 */
17
+ }
18
+ }
19
+ }
20
+ """
21
+ When I successfully run `adlint W0013.c` on noarch
22
+ Then the output should exactly match with:
23
+ | mesg | line | column |
24
+ | W0629 | 1 | 13 |
25
+ | W0535 | 6 | 10 |
26
+ | W0013 | 9 | 13 |
27
+ | W0628 | 1 | 13 |
28
+
29
+ Scenario: a continue-statement in c99-for-statement
30
+ Given a target source named "W0013.c" with:
31
+ """
32
+ static void foo(void)
33
+ {
34
+ int j = 0;
35
+
36
+ for (int i = 1; i < 20; i++) {
37
+ j += 2;
38
+ if ((j % i) == 3) {
39
+ continue; /* W0013 */
40
+ }
41
+ }
42
+ }
43
+ """
44
+ When I successfully run `adlint W0013.c` on noarch
45
+ Then the output should exactly match with:
46
+ | mesg | line | column |
47
+ | W0629 | 1 | 13 |
48
+ | W0013 | 8 | 13 |
49
+ | W0628 | 1 | 13 |
50
+
51
+ Scenario: a continue-statement in while-statement
52
+ Given a target source named "W0013.c" with:
53
+ """
54
+ static void foo(void)
55
+ {
56
+ int i = 1;
57
+ int j = 0;
58
+
59
+ while (i < 20) {
60
+ i++;
61
+ j += 2;
62
+ if ((j % i) == 3) {
63
+ continue; /* W0013 */
64
+ }
65
+ }
66
+ }
67
+ """
68
+ When I successfully run `adlint W0013.c` on noarch
69
+ Then the output should exactly match with:
70
+ | mesg | line | column |
71
+ | W0629 | 1 | 13 |
72
+ | W0013 | 10 | 13 |
73
+ | W0628 | 1 | 13 |
74
+
75
+ Scenario: a continue-statement in do-statement
76
+ Given a target source named "W0013.c" with:
77
+ """
78
+ static void foo(void)
79
+ {
80
+ int i = 1;
81
+ int j = 0;
82
+
83
+ do {
84
+ i++;
85
+ j += 2;
86
+ if ((j % i) == 3) {
87
+ continue; /* W0013 */
88
+ }
89
+ } while (i < 20);
90
+ }
91
+ """
92
+ When I successfully run `adlint W0013.c` on noarch
93
+ Then the output should exactly match with:
94
+ | mesg | line | column |
95
+ | W0629 | 1 | 13 |
96
+ | W0013 | 10 | 13 |
97
+ | W0628 | 1 | 13 |
98
+
99
+ Scenario: no continue-statement in for-statement
100
+ Given a target source named "W0013.c" with:
101
+ """
102
+ static void foo(void)
103
+ {
104
+ int i;
105
+ int j;
106
+
107
+ for (i = 1, j = 0; i < 20; i++) {
108
+ j += 2;
109
+ if ((j % i) == 3) {
110
+ break; /* OK */
111
+ }
112
+ }
113
+ }
114
+ """
115
+ When I successfully run `adlint W0013.c` on noarch
116
+ Then the output should exactly match with:
117
+ | mesg | line | column |
118
+ | W0629 | 1 | 13 |
119
+ | W0535 | 6 | 10 |
120
+ | W0628 | 1 | 13 |
121
+
122
+ Scenario: no continue-statement in c99-for-statement
123
+ Given a target source named "W0013.c" with:
124
+ """
125
+ static void foo(void)
126
+ {
127
+ int j = 0;
128
+
129
+ for (int i = 1; i < 20; i++) {
130
+ j += 2;
131
+ if ((j % i) == 3) {
132
+ break; /* OK */
133
+ }
134
+ }
135
+ }
136
+ """
137
+ When I successfully run `adlint W0013.c` on noarch
138
+ Then the output should exactly match with:
139
+ | mesg | line | column |
140
+ | W0629 | 1 | 13 |
141
+ | W0628 | 1 | 13 |
142
+
143
+ Scenario: no continue-statement in while-statement
144
+ Given a target source named "W0013.c" with:
145
+ """
146
+ static void foo(void)
147
+ {
148
+ int i = 1;
149
+ int j = 0;
150
+
151
+ while (i < 20) {
152
+ i++;
153
+ j += 2;
154
+ if ((j % i) == 3) {
155
+ break; /* OK */
156
+ }
157
+ }
158
+ }
159
+ """
160
+ When I successfully run `adlint W0013.c` on noarch
161
+ Then the output should exactly match with:
162
+ | mesg | line | column |
163
+ | W0629 | 1 | 13 |
164
+ | W0628 | 1 | 13 |
165
+
166
+ Scenario: no continue-statement in do-statement
167
+ Given a target source named "W0013.c" with:
168
+ """
169
+ static void foo(void)
170
+ {
171
+ int i = 1;
172
+ int j = 0;
173
+
174
+ do {
175
+ i++;
176
+ j += 2;
177
+ if ((j % i) == 3) {
178
+ break; /* OK */
179
+ }
180
+ } while (i < 20);
181
+ }
182
+ """
183
+ When I successfully run `adlint W0013.c` on noarch
184
+ Then the output should exactly match with:
185
+ | mesg | line | column |
186
+ | W0629 | 1 | 13 |
187
+ | W0628 | 1 | 13 |
188
+
189
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,50 @@
1
+ Feature: W0109
2
+
3
+ W0703 detects that a function-call is performed before declaring the target
4
+ function.
5
+
6
+ Scenario: calling function is not declared
7
+ Given a target source named "W0109.c" with:
8
+ """
9
+ int main(void)
10
+ {
11
+ return foo(); /* W0109 */
12
+ }
13
+ """
14
+ When I successfully run `adlint W0109.c` on noarch
15
+ Then the output should exactly match with:
16
+ | mesg | line | column |
17
+ | W0109 | 3 | 15 |
18
+
19
+ Scenario: calling function is forward declared
20
+ Given a target source named "W0109.c" with:
21
+ """
22
+ extern int foo(void);
23
+
24
+ int main(void)
25
+ {
26
+ return foo(); /* OK */
27
+ }
28
+ """
29
+ When I successfully run `adlint W0109.c` on noarch
30
+ Then the output should exactly match with:
31
+ | mesg | line | column |
32
+ | W0118 | 1 | 12 |
33
+
34
+ Scenario: calling function is backward declared
35
+ Given a target source named "W0109.c" with:
36
+ """
37
+ int main(void)
38
+ {
39
+ return foo(); /* W0109 */
40
+ }
41
+
42
+ extern int foo(void);
43
+ """
44
+ When I successfully run `adlint W0109.c` on noarch
45
+ Then the output should exactly match with:
46
+ | mesg | line | column |
47
+ | W0109 | 3 | 15 |
48
+ | W0118 | 6 | 12 |
49
+
50
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,30 @@
1
+ Feature: W0583
2
+
3
+ W0583 detects that arguments specified to call the function does not match
4
+ with the corresponding function-definition appears after the function-call.
5
+
6
+ Scenario: array as an argument
7
+ Given a target source named "W0583.c" with:
8
+ """
9
+ int main(void)
10
+ {
11
+ int a[] = { 0, 1, 2 };
12
+ return foo(a);
13
+ }
14
+
15
+ int foo(const int *p) { /* W0583 should not be output */
16
+ return *p;
17
+ }
18
+ """
19
+ When I successfully run `adlint W0583.c` on noarch
20
+ Then the output should not match with /4:.*:W0583/
21
+ And the output should exactly match with:
22
+ | mesg | line | column |
23
+ | W0109 | 4 | 15 |
24
+ | W0117 | 7 | 5 |
25
+ | W0422 | 8 | 12 |
26
+ | W0104 | 7 | 20 |
27
+ | W0589 | 7 | 5 |
28
+ | W0591 | 7 | 5 |
29
+
30
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,20 @@
1
+ Feature: W0606
2
+
3
+ W0606 detects that floating point in union.
4
+
5
+ Scenario: floating point in union.
6
+ Given a target source named "W0606.c" with:
7
+ """
8
+ union UNI { /* W0606 */
9
+ float a;
10
+ int b;
11
+ };
12
+
13
+ """
14
+ When I successfully run `adlint W0606.c` on noarch
15
+ Then the output should exactly match with:
16
+ | mesg | line | column |
17
+ | W0551 | 1 | 7 |
18
+ | W0606 | 1 | 7 |
19
+
20
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,20 @@
1
+ Feature: W0698
2
+
3
+ W0698 detects that`return;' statement is found at except void function.
4
+
5
+ Scenario: return statement
6
+ Given a target source named "W0698.c" with:
7
+ """
8
+ int func(void)
9
+ {
10
+ return; /* W0698 */
11
+ }
12
+ """
13
+ When I successfully run `adlint W0698.c` on noarch
14
+ Then the output should exactly match with:
15
+ | mesg | line | column |
16
+ | W0117 | 1 | 5 |
17
+ | W0698 | 3 | 5 |
18
+ | W0628 | 1 | 5 |
19
+
20
+ # vim:ts=2:sw=2:sts=2:et:
@@ -0,0 +1,21 @@
1
+ Feature: W0699
2
+
3
+ W0699 detects that`return;' statement is found at except void function.
4
+
5
+ Scenario: return statement
6
+ Given a target source named "W0699.c" with:
7
+ """
8
+ extern func(void)
9
+ {
10
+ return; /* W0699 */
11
+ }
12
+ """
13
+ When I successfully run `adlint W0699.c` on noarch
14
+ Then the output should exactly match with:
15
+ | mesg | line | column |
16
+ | W0117 | 1 | 8 |
17
+ | W0457 | 1 | 8 |
18
+ | W0699 | 3 | 5 |
19
+ | W0628 | 1 | 8 |
20
+
21
+ # vim:ts=2:sw=2:sts=2:et: