adlint 3.0.4 → 3.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +374 -13
- data/INSTALL +1 -3
- data/MANIFEST +12 -0
- data/NEWS +30 -4
- data/README +0 -4
- data/TODO +2 -1
- data/etc/mesg.d/c_builtin/en_US/messages.yml +2 -2
- data/etc/mesg.d/c_builtin/ja_JP/messages.yml +2 -2
- data/etc/mesg.d/core/en_US/messages.yml +5 -1
- data/etc/mesg.d/core/ja_JP/messages.yml +5 -1
- data/features/code_check/W0422.feature +128 -0
- data/features/code_check/W0491.feature +57 -0
- data/features/code_check/W0492.feature +80 -0
- data/features/code_check/W0542.feature +20 -0
- data/features/code_check/W0580.feature +25 -0
- data/features/code_check/W0610.feature +36 -0
- data/features/code_check/W0642.feature +67 -0
- data/features/code_check/W0786.feature +39 -0
- data/features/code_check/W0830.feature +27 -0
- data/features/code_check/W1047.feature +72 -0
- data/features/code_check/W9003.feature +22 -0
- data/features/code_extraction/TODO +1 -0
- data/features/metric_measurement/TODO +1 -0
- data/lib/adlint/analyzer.rb +2 -2
- data/lib/adlint/cc1/ctrlexpr.rb +27 -6
- data/lib/adlint/cc1/domain.rb +72 -12
- data/lib/adlint/cc1/enum.rb +4 -0
- data/lib/adlint/cc1/expr.rb +31 -29
- data/lib/adlint/cc1/interp.rb +45 -56
- data/lib/adlint/cc1/lexer.rb +26 -5
- data/lib/adlint/cc1/mediator.rb +35 -6
- data/lib/adlint/cc1/object.rb +62 -19
- data/lib/adlint/cc1/parser.rb +948 -904
- data/lib/adlint/cc1/parser.y +59 -29
- data/lib/adlint/cc1/phase.rb +6 -8
- data/lib/adlint/cc1/syntax.rb +70 -17
- data/lib/adlint/cc1/util.rb +4 -4
- data/lib/adlint/code.rb +16 -6
- data/lib/adlint/cpp/eval.rb +31 -25
- data/lib/adlint/cpp/lexer.rb +11 -5
- data/lib/adlint/cpp/macro.rb +34 -7
- data/lib/adlint/cpp/phase.rb +8 -8
- data/lib/adlint/error.rb +6 -0
- data/lib/adlint/exam/c_builtin/cc1_check.rb +557 -594
- data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +72 -72
- data/lib/adlint/exam/c_builtin/cc1_code.rb +72 -52
- data/lib/adlint/exam/c_builtin/cc1_metric.rb +131 -131
- data/lib/adlint/exam/c_builtin/cpp_check.rb +48 -48
- data/lib/adlint/exam/c_builtin/cpp_check_shima.rb +2 -2
- data/lib/adlint/exam/c_builtin/cpp_code.rb +21 -21
- data/lib/adlint/exam/c_builtin/ld_check.rb +88 -87
- data/lib/adlint/exam/c_builtin/ld_metric.rb +4 -5
- data/lib/adlint/exam/c_builtin.rb +6 -6
- data/lib/adlint/ld/object.rb +269 -186
- data/lib/adlint/ld/phase.rb +19 -19
- data/lib/adlint/ld/typedef.rb +7 -7
- data/lib/adlint/ld/util.rb +25 -17
- data/lib/adlint/location.rb +6 -1
- data/lib/adlint/memo.rb +66 -13
- data/lib/adlint/prelude.rb +2 -2
- data/lib/adlint/report.rb +13 -14
- data/lib/adlint/util.rb +1 -1
- data/lib/adlint/version.rb +2 -2
- data/share/doc/Makefile +6 -2
- data/share/doc/c99gram.dot +502 -0
- data/share/doc/c99gram.pdf +0 -0
- data/share/doc/developers_guide_ja.html +4 -3
- data/share/doc/developers_guide_ja.texi +2 -1
- data/share/doc/users_guide_en.html +9 -9
- data/share/doc/users_guide_en.texi +7 -7
- data/share/doc/users_guide_ja.html +9 -9
- data/share/doc/users_guide_ja.texi +7 -7
- metadata +14 -2
@@ -0,0 +1,128 @@
|
|
1
|
+
Feature: W0422
|
2
|
+
|
3
|
+
W0422 detects that an inconstant expression may cause NULL pointer
|
4
|
+
dereference.
|
5
|
+
|
6
|
+
Scenario: pointer variable definition with self referring sizeof-expression
|
7
|
+
in the initializer
|
8
|
+
Given a target source named "fixture.c" with:
|
9
|
+
"""
|
10
|
+
struct foo { int i; };
|
11
|
+
extern void *malloc(unsigned long);
|
12
|
+
|
13
|
+
static int bar(void)
|
14
|
+
{
|
15
|
+
struct foo * const p = (struct foo *) malloc(sizeof *p);
|
16
|
+
return p->i; /* W0422 */
|
17
|
+
}
|
18
|
+
|
19
|
+
static int baz(void)
|
20
|
+
{
|
21
|
+
struct foo * const p = (struct foo *) malloc(sizeof(struct foo));
|
22
|
+
return p->i; /* W0422 */
|
23
|
+
}
|
24
|
+
"""
|
25
|
+
When I successfully run `adlint fixture.c` on noarch
|
26
|
+
Then the output should exactly match with:
|
27
|
+
| mesg | line | column |
|
28
|
+
| W0118 | 2 | 14 |
|
29
|
+
| W1076 | 4 | 12 |
|
30
|
+
| W0422 | 7 | 13 |
|
31
|
+
| W1076 | 10 | 12 |
|
32
|
+
| W0422 | 13 | 13 |
|
33
|
+
| W0629 | 4 | 12 |
|
34
|
+
| W0629 | 10 | 12 |
|
35
|
+
| W0628 | 4 | 12 |
|
36
|
+
| W0628 | 10 | 12 |
|
37
|
+
|
38
|
+
Scenario: pointer variable as a part of controlling expression
|
39
|
+
Given a target source named "fixture.c" with:
|
40
|
+
"""
|
41
|
+
struct node { struct node *prev; };
|
42
|
+
|
43
|
+
void foo(const struct node *list)
|
44
|
+
{
|
45
|
+
if (list != NULL)
|
46
|
+
{
|
47
|
+
while (1)
|
48
|
+
{
|
49
|
+
list = list->prev; /* OK */
|
50
|
+
if (list == NULL)
|
51
|
+
{
|
52
|
+
break;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
"""
|
58
|
+
When I successfully run `adlint fixture.c` on noarch
|
59
|
+
Then the output should exactly match with:
|
60
|
+
| mesg | line | column |
|
61
|
+
| W0117 | 3 | 6 |
|
62
|
+
| W0114 | 7 | 9 |
|
63
|
+
| W0628 | 3 | 6 |
|
64
|
+
|
65
|
+
Scenario: pointer variable as a part of controlling expression is declared in
|
66
|
+
the iteration body
|
67
|
+
Given a target source named "fixture.c" with:
|
68
|
+
"""
|
69
|
+
static int *bar(void);
|
70
|
+
|
71
|
+
void foo(void)
|
72
|
+
{
|
73
|
+
if (1) {
|
74
|
+
int *p1;
|
75
|
+
p1 = bar();
|
76
|
+
while (1) {
|
77
|
+
int *p2;
|
78
|
+
p2 = p1;
|
79
|
+
while (*p2 != 3) { /* W0422 */
|
80
|
+
p2++;
|
81
|
+
}
|
82
|
+
if (*p2 == 4) {
|
83
|
+
break;
|
84
|
+
}
|
85
|
+
else {
|
86
|
+
p1 = bar();
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
"""
|
92
|
+
When I successfully run `adlint fixture.c` on noarch
|
93
|
+
Then the output should exactly match with:
|
94
|
+
| mesg | line | column |
|
95
|
+
| W0117 | 3 | 6 |
|
96
|
+
| W0422 | 11 | 20 |
|
97
|
+
| W0024 | 12 | 19 |
|
98
|
+
| W0114 | 5 | 5 |
|
99
|
+
| W0114 | 8 | 9 |
|
100
|
+
| W0628 | 3 | 6 |
|
101
|
+
|
102
|
+
Scenario: pointer variable has the same name with previously declared
|
103
|
+
function
|
104
|
+
Given a target source named "fixture.c" with:
|
105
|
+
"""
|
106
|
+
extern void instr(void);
|
107
|
+
|
108
|
+
void foo(char *instr)
|
109
|
+
{
|
110
|
+
if (instr[0] == '*') { /* W0422 */
|
111
|
+
return;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
"""
|
115
|
+
When I successfully run `adlint fixture.c` on noarch
|
116
|
+
Then the output should exactly match with:
|
117
|
+
| mesg | line | column |
|
118
|
+
| W0118 | 1 | 13 |
|
119
|
+
| W0117 | 3 | 6 |
|
120
|
+
| W0704 | 3 | 16 |
|
121
|
+
| C0001 | 1 | 13 |
|
122
|
+
| W0422 | 5 | 14 |
|
123
|
+
| W0123 | 5 | 14 |
|
124
|
+
| W0104 | 3 | 16 |
|
125
|
+
| W0105 | 3 | 16 |
|
126
|
+
| W1071 | 3 | 6 |
|
127
|
+
| W0948 | 5 | 21 |
|
128
|
+
| W0628 | 3 | 6 |
|
@@ -0,0 +1,57 @@
|
|
1
|
+
Feature: W0491
|
2
|
+
|
3
|
+
W0491 detects that the same name appears in different namespaces.
|
4
|
+
|
5
|
+
Scenario: hard to parse
|
6
|
+
Given a target source named "fixture.c" with:
|
7
|
+
"""
|
8
|
+
typedef struct named_ref {
|
9
|
+
int id;
|
10
|
+
} named_ref; /* W0491 */
|
11
|
+
|
12
|
+
typedef struct code_props {
|
13
|
+
named_ref *named_ref; /* W0492 */
|
14
|
+
} code_props; /* W0491 */
|
15
|
+
|
16
|
+
void func(named_ref *named_ref);
|
17
|
+
void bar(int, named_ref *, named_ref *);
|
18
|
+
"""
|
19
|
+
When I successfully run `adlint fixture.c` on noarch
|
20
|
+
Then the output should exactly match with:
|
21
|
+
| mesg | line | column |
|
22
|
+
| W0491 | 3 | 3 |
|
23
|
+
| C0001 | 1 | 16 |
|
24
|
+
| W0492 | 6 | 16 |
|
25
|
+
| C0001 | 3 | 3 |
|
26
|
+
| C0001 | 1 | 16 |
|
27
|
+
| W0491 | 7 | 3 |
|
28
|
+
| C0001 | 5 | 16 |
|
29
|
+
| W0118 | 9 | 6 |
|
30
|
+
| W0118 | 10 | 6 |
|
31
|
+
|
32
|
+
Scenario: hard to parse
|
33
|
+
Given a target source named "fixture.c" with:
|
34
|
+
"""
|
35
|
+
#define RETSIGTYPE void
|
36
|
+
|
37
|
+
typedef int sighandler_t;
|
38
|
+
typedef RETSIGTYPE (*sighandler_t)(int);
|
39
|
+
|
40
|
+
struct sighandler_t {
|
41
|
+
RETSIGTYPE (*ptr)(int);
|
42
|
+
};
|
43
|
+
|
44
|
+
typedef struct sighandler_t *(*sighandler_t)(struct sighandler_t *);
|
45
|
+
"""
|
46
|
+
When I successfully run `adlint fixture.c` on noarch
|
47
|
+
Then the output should exactly match with:
|
48
|
+
| mesg | line | column |
|
49
|
+
| W0491 | 6 | 8 |
|
50
|
+
| C0001 | 3 | 13 |
|
51
|
+
| C0001 | 4 | 22 |
|
52
|
+
| W0491 | 10 | 32 |
|
53
|
+
| C0001 | 6 | 8 |
|
54
|
+
| W0482 | 1 | 1 |
|
55
|
+
| W0586 | 3 | 13 |
|
56
|
+
| W0586 | 4 | 22 |
|
57
|
+
| W0586 | 10 | 32 |
|
@@ -0,0 +1,80 @@
|
|
1
|
+
Feature: W0492
|
2
|
+
|
3
|
+
W0492 detects that the same name appears in different namespaces.
|
4
|
+
|
5
|
+
Scenario: hard to parse
|
6
|
+
Given a target source named "fixture.c" with:
|
7
|
+
"""
|
8
|
+
typedef int foo;
|
9
|
+
|
10
|
+
foo bar(foo baz)
|
11
|
+
{
|
12
|
+
goto foo;
|
13
|
+
foo:
|
14
|
+
return baz;
|
15
|
+
}
|
16
|
+
|
17
|
+
struct foo { foo foo, (*bar)(foo); }; /* W0492 */
|
18
|
+
union bar { foo foo, (*bar)(foo (*baz)(foo)); }; /* W0492 */
|
19
|
+
enum baz { baz };
|
20
|
+
|
21
|
+
struct {
|
22
|
+
foo :1;
|
23
|
+
foo foo:1; /* W0492 */
|
24
|
+
foo :1;
|
25
|
+
foo bar:1; /* W0492 */
|
26
|
+
foo :1;
|
27
|
+
} qux;
|
28
|
+
|
29
|
+
struct qux {
|
30
|
+
foo;
|
31
|
+
union bar bar; /* W0492 */
|
32
|
+
};
|
33
|
+
|
34
|
+
int const long volatile unsigned cv_ulong;
|
35
|
+
const foo volatile cv_foo;
|
36
|
+
"""
|
37
|
+
When I successfully run `adlint fixture.c` on noarch
|
38
|
+
Then the output should exactly match with:
|
39
|
+
| mesg | line | column |
|
40
|
+
| W0117 | 3 | 5 |
|
41
|
+
| W0625 | 1 | 13 |
|
42
|
+
| W0491 | 6 | 1 |
|
43
|
+
| C0001 | 1 | 13 |
|
44
|
+
| W0104 | 3 | 13 |
|
45
|
+
| W0491 | 10 | 8 |
|
46
|
+
| C0001 | 1 | 13 |
|
47
|
+
| W0492 | 10 | 18 |
|
48
|
+
| C0001 | 1 | 13 |
|
49
|
+
| C0001 | 10 | 8 |
|
50
|
+
| W0492 | 11 | 7 |
|
51
|
+
| C0001 | 10 | 25 |
|
52
|
+
| W0492 | 11 | 17 |
|
53
|
+
| C0001 | 1 | 13 |
|
54
|
+
| C0001 | 10 | 8 |
|
55
|
+
| W0492 | 11 | 24 |
|
56
|
+
| C0001 | 11 | 7 |
|
57
|
+
| W0492 | 16 | 9 |
|
58
|
+
| C0001 | 1 | 13 |
|
59
|
+
| C0001 | 10 | 8 |
|
60
|
+
| W0492 | 18 | 9 |
|
61
|
+
| C0001 | 11 | 7 |
|
62
|
+
| W0117 | 20 | 3 |
|
63
|
+
| W0491 | 22 | 8 |
|
64
|
+
| C0001 | 20 | 3 |
|
65
|
+
| W0492 | 24 | 15 |
|
66
|
+
| C0001 | 11 | 7 |
|
67
|
+
| W0080 | 27 | 34 |
|
68
|
+
| W0117 | 27 | 34 |
|
69
|
+
| W0080 | 28 | 20 |
|
70
|
+
| W0117 | 28 | 20 |
|
71
|
+
| W1072 | 5 | 5 |
|
72
|
+
| W0551 | 11 | 7 |
|
73
|
+
| W0525 | 16 | 9 |
|
74
|
+
| W0525 | 18 | 9 |
|
75
|
+
| W0040 | 14 | 1 |
|
76
|
+
| W0425 | 10 | 25 |
|
77
|
+
| W0425 | 11 | 24 |
|
78
|
+
| W0431 | 6 | 1 |
|
79
|
+
| W0432 | 6 | 1 |
|
80
|
+
| W0628 | 3 | 5 |
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: W0542
|
2
|
+
|
3
|
+
W0542 detects that some of parameters have an identifier.
|
4
|
+
|
5
|
+
Scenario: hard to parse
|
6
|
+
Given a target source named "fixture.c" with:
|
7
|
+
"""
|
8
|
+
typedef unsigned int VALUE;
|
9
|
+
typedef void *ANYARGS;
|
10
|
+
|
11
|
+
VALUE foo(VALUE(*p1)(VALUE),VALUE,VALUE(*p2)(ANYARGS),VALUE); /* W0542 */
|
12
|
+
VALUE bar(VALUE(*)(VALUE),VALUE,VALUE(*)(ANYARGS),VALUE);
|
13
|
+
"""
|
14
|
+
When I successfully run `adlint fixture.c` on noarch
|
15
|
+
Then the output should exactly match with:
|
16
|
+
| mesg | line | column |
|
17
|
+
| W0118 | 4 | 7 |
|
18
|
+
| W0625 | 1 | 22 |
|
19
|
+
| W0118 | 5 | 7 |
|
20
|
+
| W0542 | 4 | 7 |
|
@@ -0,0 +1,25 @@
|
|
1
|
+
Feature: W0580
|
2
|
+
|
3
|
+
W0580 detects that address of the function local static variable is assigned
|
4
|
+
to the global pointer variable declared in wider scope.
|
5
|
+
|
6
|
+
Scenario: assigning address of an array element to the global pointer
|
7
|
+
Given a target source named "fixture.c" with:
|
8
|
+
"""
|
9
|
+
extern int *p;
|
10
|
+
|
11
|
+
static void foo(void)
|
12
|
+
{
|
13
|
+
static int a[] = { 1, 2, 3 };
|
14
|
+
p = &a[1]; /* W0580 */
|
15
|
+
}
|
16
|
+
"""
|
17
|
+
When I successfully run `adlint fixture.c` on noarch
|
18
|
+
Then the output should exactly match with:
|
19
|
+
| mesg | line | column |
|
20
|
+
| W0118 | 1 | 13 |
|
21
|
+
| W1076 | 3 | 13 |
|
22
|
+
| W0580 | 6 | 7 |
|
23
|
+
| W0100 | 5 | 16 |
|
24
|
+
| W0629 | 3 | 13 |
|
25
|
+
| W0628 | 3 | 13 |
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Feature: W0610
|
2
|
+
|
3
|
+
W0610 detects that a logical expression makes always true.
|
4
|
+
|
5
|
+
Scenario: comparison of static storage duration variable
|
6
|
+
Given a target source named "fixture.c" with:
|
7
|
+
"""
|
8
|
+
struct { char *p; } foo = { NULL };
|
9
|
+
int *p = NULL;
|
10
|
+
|
11
|
+
static void bar(void)
|
12
|
+
{
|
13
|
+
if (p != NULL) { /* OK */
|
14
|
+
return;
|
15
|
+
}
|
16
|
+
|
17
|
+
if (foo.p != NULL) { /* OK */
|
18
|
+
return;
|
19
|
+
}
|
20
|
+
}
|
21
|
+
"""
|
22
|
+
When I successfully run `adlint fixture.c` on noarch
|
23
|
+
Then the output should exactly match with:
|
24
|
+
| mesg | line | column |
|
25
|
+
| W0117 | 1 | 21 |
|
26
|
+
| W0117 | 2 | 6 |
|
27
|
+
| W0492 | 2 | 6 |
|
28
|
+
| C0001 | 1 | 16 |
|
29
|
+
| W1076 | 4 | 13 |
|
30
|
+
| W1071 | 4 | 13 |
|
31
|
+
| W0629 | 4 | 13 |
|
32
|
+
| W0628 | 4 | 13 |
|
33
|
+
| W0589 | 1 | 21 |
|
34
|
+
| W0593 | 1 | 21 |
|
35
|
+
| W0589 | 2 | 6 |
|
36
|
+
| W0593 | 2 | 6 |
|
@@ -0,0 +1,67 @@
|
|
1
|
+
Feature: W0642
|
2
|
+
|
3
|
+
W0642 detects that an expression trys to derive address of the array declared
|
4
|
+
as `register'.
|
5
|
+
|
6
|
+
Scenario: register array passed as function parameter
|
7
|
+
Given a target source named "fixture.c" with:
|
8
|
+
"""
|
9
|
+
extern void foo(char *);
|
10
|
+
|
11
|
+
static void bar(void)
|
12
|
+
{
|
13
|
+
register char a[3];
|
14
|
+
foo(a); /* W0642 */
|
15
|
+
}
|
16
|
+
"""
|
17
|
+
When I successfully run `adlint fixture.c` on noarch
|
18
|
+
Then the output should exactly match with:
|
19
|
+
| mesg | line | column |
|
20
|
+
| W0118 | 1 | 13 |
|
21
|
+
| W1076 | 3 | 13 |
|
22
|
+
| W0642 | 6 | 9 |
|
23
|
+
| W0100 | 5 | 19 |
|
24
|
+
| W0629 | 3 | 13 |
|
25
|
+
| W0950 | 5 | 21 |
|
26
|
+
| W0628 | 3 | 13 |
|
27
|
+
|
28
|
+
Scenario: register array designated in initializer
|
29
|
+
Given a target source named "fixture.c" with:
|
30
|
+
"""
|
31
|
+
static void foo(void)
|
32
|
+
{
|
33
|
+
register char a[3];
|
34
|
+
char *p = a; /* W0642 */
|
35
|
+
}
|
36
|
+
"""
|
37
|
+
When I successfully run `adlint fixture.c` on noarch
|
38
|
+
Then the output should exactly match with:
|
39
|
+
| mesg | line | column |
|
40
|
+
| W1076 | 1 | 13 |
|
41
|
+
| W0642 | 4 | 15 |
|
42
|
+
| W0100 | 3 | 19 |
|
43
|
+
| W0100 | 4 | 11 |
|
44
|
+
| W0629 | 1 | 13 |
|
45
|
+
| W0950 | 3 | 21 |
|
46
|
+
| W0628 | 1 | 13 |
|
47
|
+
|
48
|
+
Scenario: register array designated in assignment
|
49
|
+
Given a target source named "fixture.c" with:
|
50
|
+
"""
|
51
|
+
static void foo(void)
|
52
|
+
{
|
53
|
+
register char a[3];
|
54
|
+
char *p;
|
55
|
+
p = a; /* W0642 */
|
56
|
+
}
|
57
|
+
"""
|
58
|
+
When I successfully run `adlint fixture.c` on noarch
|
59
|
+
Then the output should exactly match with:
|
60
|
+
| mesg | line | column |
|
61
|
+
| W1076 | 1 | 13 |
|
62
|
+
| W0642 | 5 | 9 |
|
63
|
+
| W0100 | 3 | 19 |
|
64
|
+
| W0100 | 4 | 11 |
|
65
|
+
| W0629 | 1 | 13 |
|
66
|
+
| W0950 | 3 | 21 |
|
67
|
+
| W0628 | 1 | 13 |
|
@@ -0,0 +1,39 @@
|
|
1
|
+
Feature: W0786
|
2
|
+
|
3
|
+
W0786 detects that a bit-field whose base type is not in signed or unsigned
|
4
|
+
`int' is declared.
|
5
|
+
|
6
|
+
Scenario: typedefed `unsigned long' bit-field declaration
|
7
|
+
Given a target source named "fixture.c" with:
|
8
|
+
"""
|
9
|
+
typedef unsigned long base_t;
|
10
|
+
|
11
|
+
static struct { /* W0786 */
|
12
|
+
base_t :1; /* bit padding */
|
13
|
+
base_t foo:1;
|
14
|
+
base_t :1; /* bit padding */
|
15
|
+
base_t bar:1;
|
16
|
+
base_t :1; /* bit padding */
|
17
|
+
} bf;
|
18
|
+
"""
|
19
|
+
When I successfully run `adlint fixture.c` on noarch
|
20
|
+
Then the output should exactly match with:
|
21
|
+
| mesg | line | column |
|
22
|
+
| W0786 | 3 | 8 |
|
23
|
+
|
24
|
+
Scenario: typedefed `unsigned int' bit-field declaration
|
25
|
+
Given a target source named "fixture.c" with:
|
26
|
+
"""
|
27
|
+
typedef unsigned int base_t;
|
28
|
+
|
29
|
+
static struct { /* OK */
|
30
|
+
base_t :1; /* bit padding */
|
31
|
+
base_t foo:1;
|
32
|
+
base_t :1; /* bit padding */
|
33
|
+
base_t bar:1;
|
34
|
+
base_t :1; /* bit padding */
|
35
|
+
} bf;
|
36
|
+
"""
|
37
|
+
When I successfully run `adlint fixture.c` on noarch
|
38
|
+
Then the output should exactly match with:
|
39
|
+
| mesg | line | column |
|
@@ -61,3 +61,30 @@ Feature: W0830
|
|
61
61
|
Then the output should exactly match with:
|
62
62
|
| mesg | line | column |
|
63
63
|
| W0830 | 1 | 36 |
|
64
|
+
|
65
|
+
Scenario: hard to preprocess
|
66
|
+
Given a target source named "fixture.c" with:
|
67
|
+
"""
|
68
|
+
#include "config.h"
|
69
|
+
"""
|
70
|
+
And a target source named "config.h" with:
|
71
|
+
"""
|
72
|
+
typedef enum jid {
|
73
|
+
#define DEFINE_JOB(id, func) JOBID_##id,
|
74
|
+
#include "job_tbl.h"
|
75
|
+
#undef DEFINE_JOB
|
76
|
+
} jid_t;
|
77
|
+
"""
|
78
|
+
And a target source named "job_tbl.h" with:
|
79
|
+
"""
|
80
|
+
DEFINE_JOB(1id, func1)
|
81
|
+
DEFINE_JOB(id2, func2)
|
82
|
+
"""
|
83
|
+
When I successfully run `adlint fixture.c` on noarch
|
84
|
+
Then the output should exactly match with:
|
85
|
+
| mesg | line | column |
|
86
|
+
| W0442 | 2 | 1 |
|
87
|
+
| W0073 | 1 | 1 |
|
88
|
+
| W0073 | 1 | 1 |
|
89
|
+
| W0830 | 2 | 1 |
|
90
|
+
| W0071 | 3 | 1 |
|
@@ -159,3 +159,75 @@ Feature: W1047
|
|
159
159
|
| W0100 | 22 | 18 |
|
160
160
|
| W0551 | 14 | 5 |
|
161
161
|
| W0628 | 20 | 5 |
|
162
|
+
|
163
|
+
Scenario: initializing array with address-constant
|
164
|
+
Given a target source named "fixture.c" with:
|
165
|
+
"""
|
166
|
+
extern int foo(void);
|
167
|
+
extern int bar(void);
|
168
|
+
extern int baz(void);
|
169
|
+
|
170
|
+
static int (*fun_tbl[])(void) = { foo, bar, baz }; /* OK */
|
171
|
+
"""
|
172
|
+
When I successfully run `adlint fixture.c` on noarch
|
173
|
+
Then the output should exactly match with:
|
174
|
+
| mesg | line | column |
|
175
|
+
| W0118 | 1 | 12 |
|
176
|
+
| W0118 | 2 | 12 |
|
177
|
+
| W0118 | 3 | 12 |
|
178
|
+
|
179
|
+
Scenario: initializing struct with constant-specifier and address-constant
|
180
|
+
Given a target source named "fixture.c" with:
|
181
|
+
"""
|
182
|
+
typedef struct handler {
|
183
|
+
int id;
|
184
|
+
int (*ptr)(void);
|
185
|
+
} handler_t;
|
186
|
+
|
187
|
+
extern int foo(void);
|
188
|
+
extern int bar(void);
|
189
|
+
extern int baz(void);
|
190
|
+
|
191
|
+
static handler_t h = { 1, foo }; /* OK */
|
192
|
+
"""
|
193
|
+
When I successfully run `adlint fixture.c` on noarch
|
194
|
+
Then the output should exactly match with:
|
195
|
+
| mesg | line | column |
|
196
|
+
| W0118 | 6 | 12 |
|
197
|
+
| W0118 | 7 | 12 |
|
198
|
+
| W0118 | 8 | 12 |
|
199
|
+
|
200
|
+
Scenario: initializing struct with inconstant expression and address-constant
|
201
|
+
Given a target source named "fixture.c" with:
|
202
|
+
"""
|
203
|
+
typedef struct handler {
|
204
|
+
int id;
|
205
|
+
int (*ptr)(void);
|
206
|
+
} handler_t;
|
207
|
+
|
208
|
+
extern int foo(void);
|
209
|
+
extern int bar;
|
210
|
+
extern int baz;
|
211
|
+
|
212
|
+
static handler_t h = { bar + baz, foo }; /* W1047 */
|
213
|
+
"""
|
214
|
+
When I successfully run `adlint fixture.c` on noarch
|
215
|
+
Then the output should exactly match with:
|
216
|
+
| mesg | line | column |
|
217
|
+
| W0118 | 6 | 12 |
|
218
|
+
| W0118 | 7 | 12 |
|
219
|
+
| W0118 | 8 | 12 |
|
220
|
+
| W0723 | 10 | 28 |
|
221
|
+
| W1047 | 10 | 18 |
|
222
|
+
|
223
|
+
Scenario: initializing array with address-constant
|
224
|
+
Given a target source named "fixture.c" with:
|
225
|
+
"""
|
226
|
+
static int i, j, k;
|
227
|
+
static int *var_tbl[] = { &i, &j, &k }; /* OK */
|
228
|
+
"""
|
229
|
+
When I successfully run `adlint fixture.c` on noarch
|
230
|
+
Then the output should exactly match with:
|
231
|
+
| mesg | line | column |
|
232
|
+
| W0425 | 1 | 15 |
|
233
|
+
| W0425 | 1 | 18 |
|
@@ -269,3 +269,25 @@ Feature: W9003
|
|
269
269
|
| W0105 | 1 | 23 |
|
270
270
|
| W0629 | 1 | 13 |
|
271
271
|
| W0628 | 1 | 13 |
|
272
|
+
|
273
|
+
Scenario: no implicit convertion of register variable
|
274
|
+
Given a target source named "fixture.c" with:
|
275
|
+
"""
|
276
|
+
static void foo(void)
|
277
|
+
{
|
278
|
+
register char a[3];
|
279
|
+
char *p;
|
280
|
+
p = &a[0]; /* OK */
|
281
|
+
}
|
282
|
+
"""
|
283
|
+
When I successfully run `adlint fixture.c` on noarch
|
284
|
+
Then the output should exactly match with:
|
285
|
+
| mesg | line | column |
|
286
|
+
| W1076 | 1 | 13 |
|
287
|
+
| W0459 | 5 | 9 |
|
288
|
+
| W0642 | 5 | 9 |
|
289
|
+
| W0100 | 3 | 19 |
|
290
|
+
| W0100 | 4 | 11 |
|
291
|
+
| W0629 | 1 | 13 |
|
292
|
+
| W0950 | 3 | 21 |
|
293
|
+
| W0628 | 1 | 13 |
|
@@ -0,0 +1 @@
|
|
1
|
+
Must write functional specifications about the code extraction feature.
|
@@ -0,0 +1 @@
|
|
1
|
+
Must write functional specifications about the metric measurement feature.
|
data/lib/adlint/analyzer.rb
CHANGED
@@ -199,8 +199,8 @@ module AdLint #:nodoc:
|
|
199
199
|
Ld::MapTypedefPhase,
|
200
200
|
Ld::MapFunctionPhase,
|
201
201
|
Ld::MapVariablePhase,
|
202
|
-
Ld::
|
203
|
-
Ld::
|
202
|
+
Ld::BuildCallGraphPhase,
|
203
|
+
Ld::BuildXRefGraphPhase,
|
204
204
|
Ld::PreparePhase,
|
205
205
|
Ld::TypedefReviewPhase,
|
206
206
|
Ld::FunctionReviewPhase,
|
data/lib/adlint/cc1/ctrlexpr.rb
CHANGED
@@ -669,6 +669,27 @@ module Cc1 #:nodoc:
|
|
669
669
|
|
670
670
|
def_delegator :@manipulator, :interpreter
|
671
671
|
private :interpreter
|
672
|
+
|
673
|
+
alias :_org_interpret :interpret
|
674
|
+
def interpret(node)
|
675
|
+
case node
|
676
|
+
when ObjectSpecifier
|
677
|
+
if safely_evaluable_object_specifier?(node)
|
678
|
+
_org_interpret(node)
|
679
|
+
else
|
680
|
+
# NOTE: Nothing to do with an undeclared object.
|
681
|
+
create_tmpvar
|
682
|
+
end
|
683
|
+
else
|
684
|
+
_org_interpret(node)
|
685
|
+
end
|
686
|
+
end
|
687
|
+
|
688
|
+
def safely_evaluable_object_specifier?(obj_spec)
|
689
|
+
variable_named(obj_spec.identifier.value) ||
|
690
|
+
function_named(obj_spec.identifier.value) ||
|
691
|
+
enumerator_named(obj_spec.identifier.value)
|
692
|
+
end
|
672
693
|
end
|
673
694
|
|
674
695
|
class ValueComparison < ValueDomainNarrowing
|
@@ -682,10 +703,10 @@ module Cc1 #:nodoc:
|
|
682
703
|
private
|
683
704
|
def do_narrowing
|
684
705
|
@lhs_manip.execute!
|
685
|
-
lhs_var = object_to_variable(@lhs_manip.result)
|
706
|
+
lhs_var = object_to_variable(@lhs_manip.result, @node.lhs_operand)
|
686
707
|
|
687
708
|
@rhs_manip.execute!
|
688
|
-
rhs_var = object_to_variable(@rhs_manip.result)
|
709
|
+
rhs_var = object_to_variable(@rhs_manip.result, @node.rhs_operand)
|
689
710
|
|
690
711
|
unless lhs_var.type.scalar? && rhs_var.type.scalar?
|
691
712
|
return create_tmpvar(int_t)
|
@@ -754,7 +775,7 @@ module Cc1 #:nodoc:
|
|
754
775
|
def do_narrowing
|
755
776
|
@lhs_manip.execute!
|
756
777
|
@lhs_manip.ensure_result_equal_to(scalar_value_of_true)
|
757
|
-
lhs_var = object_to_variable(@lhs_manip.result)
|
778
|
+
lhs_var = object_to_variable(@lhs_manip.result, @node.lhs_operand)
|
758
779
|
|
759
780
|
# NOTE: The ISO C99 standard says;
|
760
781
|
#
|
@@ -772,7 +793,7 @@ module Cc1 #:nodoc:
|
|
772
793
|
@rhs_manip.load_original_values!(@lhs_manip)
|
773
794
|
@rhs_manip.execute!
|
774
795
|
@rhs_manip.ensure_result_equal_to(scalar_value_of_true)
|
775
|
-
rhs_var = object_to_variable(@rhs_manip.result)
|
796
|
+
rhs_var = object_to_variable(@rhs_manip.result, @node.rhs_operand)
|
776
797
|
|
777
798
|
notify_sequence_point_reached(SequencePoint.new(@node.rhs_operand))
|
778
799
|
|
@@ -811,7 +832,7 @@ module Cc1 #:nodoc:
|
|
811
832
|
def do_narrowing
|
812
833
|
@lhs_manip.execute!
|
813
834
|
@lhs_manip.ensure_result_equal_to(scalar_value_of_true)
|
814
|
-
lhs_var = object_to_variable(@lhs_manip.result)
|
835
|
+
lhs_var = object_to_variable(@lhs_manip.result, @node.lhs_operand)
|
815
836
|
|
816
837
|
# NOTE: The ISO C99 standard says;
|
817
838
|
#
|
@@ -830,7 +851,7 @@ module Cc1 #:nodoc:
|
|
830
851
|
# the LHS condition is false.
|
831
852
|
@rhs_manip.execute!
|
832
853
|
@rhs_manip.ensure_result_equal_to(scalar_value_of_true)
|
833
|
-
rhs_var = object_to_variable(@rhs_manip.result)
|
854
|
+
rhs_var = object_to_variable(@rhs_manip.result, @node.rhs_operand)
|
834
855
|
|
835
856
|
notify_sequence_point_reached(SequencePoint.new(@node.rhs_operand))
|
836
857
|
|