adlint 3.0.4 → 3.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/ChangeLog +374 -13
  2. data/INSTALL +1 -3
  3. data/MANIFEST +12 -0
  4. data/NEWS +30 -4
  5. data/README +0 -4
  6. data/TODO +2 -1
  7. data/etc/mesg.d/c_builtin/en_US/messages.yml +2 -2
  8. data/etc/mesg.d/c_builtin/ja_JP/messages.yml +2 -2
  9. data/etc/mesg.d/core/en_US/messages.yml +5 -1
  10. data/etc/mesg.d/core/ja_JP/messages.yml +5 -1
  11. data/features/code_check/W0422.feature +128 -0
  12. data/features/code_check/W0491.feature +57 -0
  13. data/features/code_check/W0492.feature +80 -0
  14. data/features/code_check/W0542.feature +20 -0
  15. data/features/code_check/W0580.feature +25 -0
  16. data/features/code_check/W0610.feature +36 -0
  17. data/features/code_check/W0642.feature +67 -0
  18. data/features/code_check/W0786.feature +39 -0
  19. data/features/code_check/W0830.feature +27 -0
  20. data/features/code_check/W1047.feature +72 -0
  21. data/features/code_check/W9003.feature +22 -0
  22. data/features/code_extraction/TODO +1 -0
  23. data/features/metric_measurement/TODO +1 -0
  24. data/lib/adlint/analyzer.rb +2 -2
  25. data/lib/adlint/cc1/ctrlexpr.rb +27 -6
  26. data/lib/adlint/cc1/domain.rb +72 -12
  27. data/lib/adlint/cc1/enum.rb +4 -0
  28. data/lib/adlint/cc1/expr.rb +31 -29
  29. data/lib/adlint/cc1/interp.rb +45 -56
  30. data/lib/adlint/cc1/lexer.rb +26 -5
  31. data/lib/adlint/cc1/mediator.rb +35 -6
  32. data/lib/adlint/cc1/object.rb +62 -19
  33. data/lib/adlint/cc1/parser.rb +948 -904
  34. data/lib/adlint/cc1/parser.y +59 -29
  35. data/lib/adlint/cc1/phase.rb +6 -8
  36. data/lib/adlint/cc1/syntax.rb +70 -17
  37. data/lib/adlint/cc1/util.rb +4 -4
  38. data/lib/adlint/code.rb +16 -6
  39. data/lib/adlint/cpp/eval.rb +31 -25
  40. data/lib/adlint/cpp/lexer.rb +11 -5
  41. data/lib/adlint/cpp/macro.rb +34 -7
  42. data/lib/adlint/cpp/phase.rb +8 -8
  43. data/lib/adlint/error.rb +6 -0
  44. data/lib/adlint/exam/c_builtin/cc1_check.rb +557 -594
  45. data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +72 -72
  46. data/lib/adlint/exam/c_builtin/cc1_code.rb +72 -52
  47. data/lib/adlint/exam/c_builtin/cc1_metric.rb +131 -131
  48. data/lib/adlint/exam/c_builtin/cpp_check.rb +48 -48
  49. data/lib/adlint/exam/c_builtin/cpp_check_shima.rb +2 -2
  50. data/lib/adlint/exam/c_builtin/cpp_code.rb +21 -21
  51. data/lib/adlint/exam/c_builtin/ld_check.rb +88 -87
  52. data/lib/adlint/exam/c_builtin/ld_metric.rb +4 -5
  53. data/lib/adlint/exam/c_builtin.rb +6 -6
  54. data/lib/adlint/ld/object.rb +269 -186
  55. data/lib/adlint/ld/phase.rb +19 -19
  56. data/lib/adlint/ld/typedef.rb +7 -7
  57. data/lib/adlint/ld/util.rb +25 -17
  58. data/lib/adlint/location.rb +6 -1
  59. data/lib/adlint/memo.rb +66 -13
  60. data/lib/adlint/prelude.rb +2 -2
  61. data/lib/adlint/report.rb +13 -14
  62. data/lib/adlint/util.rb +1 -1
  63. data/lib/adlint/version.rb +2 -2
  64. data/share/doc/Makefile +6 -2
  65. data/share/doc/c99gram.dot +502 -0
  66. data/share/doc/c99gram.pdf +0 -0
  67. data/share/doc/developers_guide_ja.html +4 -3
  68. data/share/doc/developers_guide_ja.texi +2 -1
  69. data/share/doc/users_guide_en.html +9 -9
  70. data/share/doc/users_guide_en.texi +7 -7
  71. data/share/doc/users_guide_ja.html +9 -9
  72. data/share/doc/users_guide_ja.texi +7 -7
  73. 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.
@@ -199,8 +199,8 @@ module AdLint #:nodoc:
199
199
  Ld::MapTypedefPhase,
200
200
  Ld::MapFunctionPhase,
201
201
  Ld::MapVariablePhase,
202
- Ld::LinkFunctionPhase,
203
- Ld::LinkVariablePhase,
202
+ Ld::BuildCallGraphPhase,
203
+ Ld::BuildXRefGraphPhase,
204
204
  Ld::PreparePhase,
205
205
  Ld::TypedefReviewPhase,
206
206
  Ld::FunctionReviewPhase,
@@ -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