adlint 1.0.0 → 1.2.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.
- data/AUTHORS +3 -2
- data/ChangeLog +208 -63
- data/MANIFEST +4 -0
- data/NEWS +24 -5
- data/etc/conf.d/fallback/traits.erb +1 -1
- data/etc/conf.d/i686-cygwin/traits-gcc_4.3.4.erb +1 -1
- data/etc/conf.d/i686-devkit/traits-gcc_4.5.2.erb +1 -1
- data/etc/conf.d/i686-linux/traits-gcc_4.5.1.erb +1 -1
- data/etc/conf.d/i686-mingw/traits-gcc_4.6.1.erb +1 -1
- data/etc/mesg.d/en_US/messages.yml +3 -3
- data/etc/mesg.d/ja_JP/messages.yml +4 -4
- data/lib/adlint/c/builtin.rb +3 -3
- data/lib/adlint/c/ctrlexpr.rb +7 -11
- data/lib/adlint/c/expr.rb +548 -363
- data/lib/adlint/c/interp.rb +233 -525
- data/lib/adlint/c/mediator.rb +1 -0
- data/lib/adlint/c/message.rb +144 -1
- data/lib/adlint/c/object.rb +15 -6
- data/lib/adlint/c/parser.rb +170 -128
- data/lib/adlint/c/parser.y +36 -0
- data/lib/adlint/c/phase.rb +4 -0
- data/lib/adlint/c/seqp.rb +72 -0
- data/lib/adlint/c/syntax.rb +254 -3
- data/lib/adlint/c.rb +1 -0
- data/lib/adlint/cpp/code.rb +2 -2
- data/lib/adlint/cpp/eval.rb +29 -13
- data/lib/adlint/cpp/message.rb +71 -70
- data/lib/adlint/cpp/message_shima.rb +100 -0
- data/lib/adlint/cpp/phase.rb +4 -0
- data/lib/adlint/cpp/syntax.rb +5 -1
- data/lib/adlint/cpp.rb +1 -0
- data/lib/adlint/message.rb +6 -3
- data/lib/adlint/traits.rb +1 -1
- data/lib/adlint/version.rb +5 -5
- data/share/demo/Makefile +3 -1
- data/share/demo/bad_line/bad_line.c +27 -0
- data/share/demo/sequence_point/sequence_point.c +31 -0
- data/share/doc/adlint_on_vim_en.png +0 -0
- data/share/doc/adlint_on_vim_ja.png +0 -0
- data/share/doc/developers_guide_ja.html +3 -3
- data/share/doc/developers_guide_ja.texi +1 -1
- data/share/doc/users_guide_en.html +3118 -41
- data/share/doc/users_guide_en.texi +3090 -37
- data/share/doc/users_guide_ja.html +3120 -47
- data/share/doc/users_guide_ja.texi +3106 -65
- data/share/sample/ctags-5.8/adlint/GNUmakefile +13 -1
- data/share/sample/ctags-5.8/adlint/adlint_cinit.h +14 -2
- data/share/sample/ctags-5.8/adlint/adlint_pinit.h +14 -4
- data/share/sample/ctags-5.8/adlint/adlint_traits.yml +14 -1
- data/share/sample/flex-2.5.35/adlint/GNUmakefile +13 -1
- data/share/sample/flex-2.5.35/adlint/adlint_cinit.h +14 -2
- data/share/sample/flex-2.5.35/adlint/adlint_pinit.h +14 -4
- data/share/sample/flex-2.5.35/adlint/adlint_traits.yml +14 -1
- metadata +6 -2
data/lib/adlint/c/parser.y
CHANGED
@@ -852,6 +852,7 @@ type_specifier
|
|
852
852
|
{
|
853
853
|
checkpoint(val[0].location)
|
854
854
|
|
855
|
+
val[2].full = true
|
855
856
|
result = TypeofTypeSpecifier.new(val[2], nil)
|
856
857
|
result.head_token = val[0]
|
857
858
|
result.tail_token = val[3]
|
@@ -1054,6 +1055,7 @@ struct_declarator
|
|
1054
1055
|
{
|
1055
1056
|
checkpoint(val[0].location)
|
1056
1057
|
|
1058
|
+
val[1].full = true
|
1057
1059
|
result = StructDeclarator.new(nil, val[1])
|
1058
1060
|
result.head_token = val[0]
|
1059
1061
|
result.tail_token = val[1].tail_token
|
@@ -1062,6 +1064,7 @@ struct_declarator
|
|
1062
1064
|
{
|
1063
1065
|
checkpoint(val[0].location)
|
1064
1066
|
|
1067
|
+
val[2].full = true
|
1065
1068
|
result = StructDeclarator.new(val[0], val[2])
|
1066
1069
|
result.head_token = val[0].head_token
|
1067
1070
|
result.tail_token = val[2].tail_token
|
@@ -1139,6 +1142,7 @@ enumerator
|
|
1139
1142
|
{
|
1140
1143
|
checkpoint(val[0].location)
|
1141
1144
|
|
1145
|
+
val[2].full = true
|
1142
1146
|
symbol = @symbol_table.create_new_symbol(EnumeratorName, val[0])
|
1143
1147
|
result = Enumerator.new(val[0], val[2], symbol)
|
1144
1148
|
result.head_token = val[0]
|
@@ -1164,8 +1168,15 @@ declarator
|
|
1164
1168
|
result = val[1]
|
1165
1169
|
result.pointer = val[0]
|
1166
1170
|
result.head_token = val[0].first
|
1171
|
+
result.full = true
|
1167
1172
|
}
|
1168
1173
|
| direct_declarator
|
1174
|
+
{
|
1175
|
+
checkpoint(val[0].location)
|
1176
|
+
|
1177
|
+
result = val[0]
|
1178
|
+
result.full = true
|
1179
|
+
}
|
1169
1180
|
;
|
1170
1181
|
|
1171
1182
|
direct_declarator
|
@@ -1190,6 +1201,7 @@ direct_declarator
|
|
1190
1201
|
{
|
1191
1202
|
checkpoint(val[0].location)
|
1192
1203
|
|
1204
|
+
val[3].full = true
|
1193
1205
|
result = ArrayDeclarator.new(val[0], val[3])
|
1194
1206
|
result.head_token = val[0].head_token
|
1195
1207
|
result.tail_token = val[4]
|
@@ -1206,6 +1218,7 @@ direct_declarator
|
|
1206
1218
|
{
|
1207
1219
|
checkpoint(val[0].location)
|
1208
1220
|
|
1221
|
+
val[2].full = true
|
1209
1222
|
result = ArrayDeclarator.new(val[0], val[2])
|
1210
1223
|
result.head_token = val[0].head_token
|
1211
1224
|
result.tail_token = val[3]
|
@@ -1215,6 +1228,7 @@ direct_declarator
|
|
1215
1228
|
{
|
1216
1229
|
checkpoint(val[0].location)
|
1217
1230
|
|
1231
|
+
val[3].full = true
|
1218
1232
|
result = ArrayDeclarator.new(val[0], val[4])
|
1219
1233
|
result.head_token = val[0].head_token
|
1220
1234
|
result.tail_token = val[5]
|
@@ -1224,6 +1238,7 @@ direct_declarator
|
|
1224
1238
|
{
|
1225
1239
|
checkpoint(val[0].location)
|
1226
1240
|
|
1241
|
+
val[4].full = true
|
1227
1242
|
result = ArrayDeclarator.new(val[0], val[4])
|
1228
1243
|
result.head_token = val[0].head_token
|
1229
1244
|
result.tail_token = val[5]
|
@@ -1429,6 +1444,7 @@ abstract_declarator
|
|
1429
1444
|
result = PointerAbstractDeclarator.new(nil, val[0])
|
1430
1445
|
result.head_token = val[0].first
|
1431
1446
|
result.tail_token = val[0].last
|
1447
|
+
result.full = true
|
1432
1448
|
}
|
1433
1449
|
| pointer direct_abstract_declarator
|
1434
1450
|
{
|
@@ -1437,8 +1453,15 @@ abstract_declarator
|
|
1437
1453
|
result = PointerAbstractDeclarator.new(val[1], val[0])
|
1438
1454
|
result.head_token = val[0].first
|
1439
1455
|
result.tail_token = val[1].tail_token
|
1456
|
+
result.full = true
|
1440
1457
|
}
|
1441
1458
|
| direct_abstract_declarator
|
1459
|
+
{
|
1460
|
+
checkpoint(val[0].location)
|
1461
|
+
|
1462
|
+
result = val[0]
|
1463
|
+
result.full = true
|
1464
|
+
}
|
1442
1465
|
;
|
1443
1466
|
|
1444
1467
|
direct_abstract_declarator
|
@@ -1468,6 +1491,7 @@ direct_abstract_declarator
|
|
1468
1491
|
|
1469
1492
|
@lexer.start_identifier_translation
|
1470
1493
|
|
1494
|
+
val[1].full = true
|
1471
1495
|
result = ArrayAbstractDeclarator.new(nil, val[1])
|
1472
1496
|
result.head_token = val[0]
|
1473
1497
|
result.tail_token = val[2]
|
@@ -1484,6 +1508,7 @@ direct_abstract_declarator
|
|
1484
1508
|
{
|
1485
1509
|
checkpoint(val[0].location)
|
1486
1510
|
|
1511
|
+
val[2].full = true
|
1487
1512
|
result = ArrayAbstractDeclarator.new(val[0], val[2])
|
1488
1513
|
result.head_token = val[0].head_token
|
1489
1514
|
result.tail_token = val[3]
|
@@ -1549,6 +1574,7 @@ initializer
|
|
1549
1574
|
{
|
1550
1575
|
checkpoint(val[0].location)
|
1551
1576
|
|
1577
|
+
val[0].full = true
|
1552
1578
|
result = Initializer.new(val[0], nil)
|
1553
1579
|
result.head_token = val[0].head_token
|
1554
1580
|
result.tail_token = val[0].tail_token
|
@@ -1645,6 +1671,7 @@ labeled_statement
|
|
1645
1671
|
{
|
1646
1672
|
checkpoint(val[0].location)
|
1647
1673
|
|
1674
|
+
val[1].full = true
|
1648
1675
|
result = CaseLabeledStatement.new(val[1], val[3])
|
1649
1676
|
result.head_token = val[0]
|
1650
1677
|
result.tail_token = val[3].tail_token
|
@@ -1711,6 +1738,7 @@ expression_statement
|
|
1711
1738
|
{
|
1712
1739
|
checkpoint(val[0].location)
|
1713
1740
|
|
1741
|
+
val[0].full = true
|
1714
1742
|
result = ExpressionStatement.new(val[0])
|
1715
1743
|
result.head_token = val[0].head_token
|
1716
1744
|
result.tail_token = val[1]
|
@@ -1722,6 +1750,7 @@ selection_statement
|
|
1722
1750
|
{
|
1723
1751
|
checkpoint(val[0].location)
|
1724
1752
|
|
1753
|
+
val[2].full = true
|
1725
1754
|
result = IfStatement.new(val[2], val[4], val[3])
|
1726
1755
|
result.head_token = val[0]
|
1727
1756
|
result.tail_token = val[4].tail_token
|
@@ -1730,6 +1759,7 @@ selection_statement
|
|
1730
1759
|
{
|
1731
1760
|
checkpoint(val[0].location)
|
1732
1761
|
|
1762
|
+
val[2].full = true
|
1733
1763
|
result = IfElseStatement.new(val[2], val[4], val[6], val[3], val[5])
|
1734
1764
|
result.head_token = val[0]
|
1735
1765
|
result.tail_token = val[6].tail_token
|
@@ -1738,6 +1768,7 @@ selection_statement
|
|
1738
1768
|
{
|
1739
1769
|
checkpoint(val[0].location)
|
1740
1770
|
|
1771
|
+
val[2].full = true
|
1741
1772
|
result = SwitchStatement.new(val[2], val[4])
|
1742
1773
|
result.head_token = val[0]
|
1743
1774
|
result.tail_token = val[4].tail_token
|
@@ -1749,6 +1780,7 @@ iteration_statement
|
|
1749
1780
|
{
|
1750
1781
|
checkpoint(val[0].location)
|
1751
1782
|
|
1783
|
+
val[2].full = true
|
1752
1784
|
result = WhileStatement.new(val[2], val[4], val[3])
|
1753
1785
|
result.head_token = val[0]
|
1754
1786
|
result.tail_token = val[4].tail_token
|
@@ -1757,6 +1789,7 @@ iteration_statement
|
|
1757
1789
|
{
|
1758
1790
|
checkpoint(val[0].location)
|
1759
1791
|
|
1792
|
+
val[4].full = true
|
1760
1793
|
result = DoStatement.new(val[1], val[4], val[0], val[2])
|
1761
1794
|
result.head_token = val[0]
|
1762
1795
|
result.tail_token = val[6]
|
@@ -1774,6 +1807,7 @@ iteration_statement
|
|
1774
1807
|
{
|
1775
1808
|
checkpoint(val[0].location)
|
1776
1809
|
|
1810
|
+
val[4].full = true
|
1777
1811
|
result = ForStatement.new(val[2], val[3], val[4], val[6], val[5])
|
1778
1812
|
result.head_token = val[0]
|
1779
1813
|
result.tail_token = val[6].tail_token
|
@@ -1790,6 +1824,7 @@ iteration_statement
|
|
1790
1824
|
{
|
1791
1825
|
checkpoint(val[0].location)
|
1792
1826
|
|
1827
|
+
val[4].full = true
|
1793
1828
|
result = C99ForStatement.new(val[2], val[3], val[4], val[6], val[5])
|
1794
1829
|
result.head_token = val[0]
|
1795
1830
|
result.tail_token = val[6].tail_token
|
@@ -1842,6 +1877,7 @@ jump_statement
|
|
1842
1877
|
{
|
1843
1878
|
checkpoint(val[0].location)
|
1844
1879
|
|
1880
|
+
val[1].full = true
|
1845
1881
|
result = ReturnStatement.new(val[1])
|
1846
1882
|
result.head_token = val[0]
|
1847
1883
|
result.tail_token = val[2]
|
data/lib/adlint/c/phase.rb
CHANGED
@@ -558,6 +558,10 @@ module C #:nodoc:
|
|
558
558
|
W0583.new(context),
|
559
559
|
W0584.new(context),
|
560
560
|
W0585.new(context),
|
561
|
+
W0597.new(context),
|
562
|
+
W0598.new(context),
|
563
|
+
W0599.new(context),
|
564
|
+
W0600.new(context),
|
561
565
|
W0605.new(context),
|
562
566
|
W0609.new(context),
|
563
567
|
W0610.new(context),
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# Sequence points of C language evaluation.
|
2
|
+
#
|
3
|
+
# Author:: Yutaka Yanoh <mailto:yanoh@users.sourceforge.net>
|
4
|
+
# Copyright:: Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
|
5
|
+
# License:: GPLv3+: GNU General Public License version 3 or later
|
6
|
+
#
|
7
|
+
# Owner:: Yutaka Yanoh <mailto:yanoh@users.sourceforge.net>
|
8
|
+
|
9
|
+
#--
|
10
|
+
# ___ ____ __ ___ _________
|
11
|
+
# / | / _ |/ / / / | / /__ __/ Source Code Static Analyzer
|
12
|
+
# / /| | / / / / / / / |/ / / / AdLint - Advanced Lint
|
13
|
+
# / __ |/ /_/ / /___/ / /| / / /
|
14
|
+
# /_/ |_|_____/_____/_/_/ |_/ /_/ Copyright (C) 2010-2012, OGIS-RI Co.,Ltd.
|
15
|
+
#
|
16
|
+
# This file is part of AdLint.
|
17
|
+
#
|
18
|
+
# AdLint is free software: you can redistribute it and/or modify it under the
|
19
|
+
# terms of the GNU General Public License as published by the Free Software
|
20
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
21
|
+
# version.
|
22
|
+
#
|
23
|
+
# AdLint is distributed in the hope that it will be useful, but WITHOUT ANY
|
24
|
+
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
25
|
+
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
26
|
+
#
|
27
|
+
# You should have received a copy of the GNU General Public License along with
|
28
|
+
# AdLint. If not, see <http://www.gnu.org/licenses/>.
|
29
|
+
#
|
30
|
+
#++
|
31
|
+
|
32
|
+
module AdLint #:nodoc:
|
33
|
+
module C #:nodoc:
|
34
|
+
|
35
|
+
# NOTE: The ISO C99 standard saids;
|
36
|
+
#
|
37
|
+
# Annex C (informative) Sequence points
|
38
|
+
#
|
39
|
+
# 1 The following are the sequence points described in 5.1.2.3:
|
40
|
+
#
|
41
|
+
# -- The call to a function, after the arguments have been evaluated
|
42
|
+
# (6.5.2.2).
|
43
|
+
# -- The end of the first operand of the following operators: logical AND
|
44
|
+
# && (6.5.13); logical OR || (6.5.14); conditional ? (6.5.15); comma ,
|
45
|
+
# (6.5.17).
|
46
|
+
# -- The end of a full declarator: declarators (6.7.5).
|
47
|
+
# -- The end of a full expression: an initializer (6.7.8); the expression
|
48
|
+
# in an expression statement (6.8.3); the controlling expression of a
|
49
|
+
# while or do statement (6.8.5); each of the expressions of a for
|
50
|
+
# statement (6.8.5.3); the expression in a return statement (6.8.6.4).
|
51
|
+
# -- Immediately before a library function returns (7.1.4).
|
52
|
+
# -- After the actions associated with each formatted input/output function
|
53
|
+
# conversion specifier (7.19.6, 7.24.2).
|
54
|
+
# -- Immediately before and immediately after each call to a comparison
|
55
|
+
# function, and also between any call to a comparison function and any
|
56
|
+
# movement of the objects passed as arguments to that call (7.20.5).
|
57
|
+
|
58
|
+
class SequencePoint
|
59
|
+
def initialize(last_node, obvious = true)
|
60
|
+
@last_node = last_node
|
61
|
+
@obvious = obvious
|
62
|
+
end
|
63
|
+
|
64
|
+
attr_reader :last_node
|
65
|
+
|
66
|
+
def obvious?
|
67
|
+
@obvious
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
data/lib/adlint/c/syntax.rb
CHANGED
@@ -31,20 +31,142 @@
|
|
31
31
|
|
32
32
|
require "adlint/symbol"
|
33
33
|
require "adlint/util"
|
34
|
+
require "adlint/c/seqp"
|
34
35
|
|
35
36
|
module AdLint #:nodoc:
|
36
37
|
module C #:nodoc:
|
37
38
|
|
39
|
+
# == DESCRIPTION
|
40
|
+
# === SyntaxNode class hierarchy
|
41
|
+
# SyntaxNode
|
42
|
+
# <--- Expression
|
43
|
+
# <--- ErrorExpression
|
44
|
+
# <--- PrimaryExpression
|
45
|
+
# <--- ObjectSpecifier
|
46
|
+
# <--- ConstantSpecifier
|
47
|
+
# <--- StringLiteralSpecifier
|
48
|
+
# <--- NullConstantSpecifier
|
49
|
+
# <--- GroupedExpression
|
50
|
+
# <--- PostfixExpression
|
51
|
+
# <--- ArraySubscriptExpression
|
52
|
+
# <--- FunctionCallExpression
|
53
|
+
# <--- MemberAccessByValueExpression
|
54
|
+
# <--- MemberAccessByPointerExpression
|
55
|
+
# <--- BitAccessByValueExpression
|
56
|
+
# <--- BitAccessByPointerExpression
|
57
|
+
# <--- PostfixIncrementExpression
|
58
|
+
# <--- PostfixDecrementExpression
|
59
|
+
# <--- CompoundLiteralExpression
|
60
|
+
# <--- UnaryExpression
|
61
|
+
# <--- PrefixIncrementExpression
|
62
|
+
# <--- PrefixDecrementExpression
|
63
|
+
# <--- AddressExpression
|
64
|
+
# <--- IndirectionExpression
|
65
|
+
# <--- UnaryArithmeticExpression
|
66
|
+
# <--- SizeofExpression
|
67
|
+
# <--- SizeofTypeExpression
|
68
|
+
# <--- AlignofExpression
|
69
|
+
# <--- AlignofTypeExpression
|
70
|
+
# <--- CastExpression
|
71
|
+
# <--- BinaryExpression
|
72
|
+
# <--- MultiplicativeExpression
|
73
|
+
# <--- AdditiveExpression
|
74
|
+
# <--- ShiftExpression
|
75
|
+
# <--- RelationalExpression
|
76
|
+
# <--- EqualityExpression
|
77
|
+
# <--- AndExpression
|
78
|
+
# <--- ExclusiveOrExpression
|
79
|
+
# <--- InclusiveOrExpression
|
80
|
+
# <--- LogicalAndExpression
|
81
|
+
# <--- LogicalOrExpression
|
82
|
+
# <--- ConditionalExpression
|
83
|
+
# <--- SimpleAssignmentExpression
|
84
|
+
# <--- CompoundAssignmentExpression
|
85
|
+
# <--- CommaSeparatedExpression
|
86
|
+
# <--- Declaration
|
87
|
+
# <--- FunctionDeclaration -------------------- SymbolicElement <<module>>
|
88
|
+
# <--- VariableDeclaration ----------------------+ | | | |
|
89
|
+
# <--- Definition | | | |
|
90
|
+
# <--- VariableDefinition -------------------+ | | |
|
91
|
+
# <--- PseudoVariableDefinition | | |
|
92
|
+
# <--- FunctionDefinition ----------------------+ | |
|
93
|
+
# <--- KandRFunctionDefinition | |
|
94
|
+
# <--- AnsiFunctionDefinition | |
|
95
|
+
# <--- ParameterDefinition | |
|
96
|
+
# <--- TypeDeclaration -----------------------------------+ |
|
97
|
+
# <--- TypedefDeclaration |
|
98
|
+
# <--- StructTypeDeclaration |
|
99
|
+
# <--- PseudoStructTypeDeclaration |
|
100
|
+
# <--- UnionTypeDeclaration |
|
101
|
+
# <--- PseudoUnionTypeDeclaration |
|
102
|
+
# <--- EnumTypeDeclaration |
|
103
|
+
# <--- PseudoEnumTypeDeclaration |
|
104
|
+
# <--- DeclarationSpecifiers |
|
105
|
+
# <--- InitDeclarator |
|
106
|
+
# <--- TypeSpecifier |
|
107
|
+
# <--- StandardTypeSpecifier |
|
108
|
+
# <--- TypedefTypeSpecifier |
|
109
|
+
# <--- StructSpecifier |
|
110
|
+
# <--- UnionSpecifier |
|
111
|
+
# <--- TypeofTypeSpecifier |
|
112
|
+
# <--- StructDeclaration |
|
113
|
+
# <--- MemberDeclaration |
|
114
|
+
# <--- SpecifierQualifierList |
|
115
|
+
# <--- StructDeclarator |
|
116
|
+
# <--- EnumSpecifier |
|
117
|
+
# <--- Enumerator -------------------------------------------+
|
118
|
+
# <--- Declarator
|
119
|
+
# <--- IdentifierDeclarator
|
120
|
+
# <--- GroupedDeclarator
|
121
|
+
# <--- ArrayDeclarator
|
122
|
+
# <--- FunctionDeclarator
|
123
|
+
# <--- AnsiFunctionDeclarator
|
124
|
+
# <--- KandRFunctionDeclarator
|
125
|
+
# <--- AbbreviatedFunctionDeclarator
|
126
|
+
# <--- AbstractDeclarator
|
127
|
+
# <--- PointerAbstractDeclarator
|
128
|
+
# <--- GroupedAbstractDeclarator
|
129
|
+
# <--- ArrayAbstractDeclarator
|
130
|
+
# <--- FunctionAbstractDeclarator
|
131
|
+
# <--- ParameterTypeList
|
132
|
+
# <--- ParameterDeclaration
|
133
|
+
# <--- Statement
|
134
|
+
# <--- ErrorStatement
|
135
|
+
# <--- LabeledStatement
|
136
|
+
# <--- GenericLabeledStatement
|
137
|
+
# <--- CaseLabeledStatement
|
138
|
+
# <--- DefaultLabeledStatement
|
139
|
+
# <--- CompoundStatement
|
140
|
+
# <--- ExpressionStatement
|
141
|
+
# <--- SelectionStatement
|
142
|
+
# <--- IfStatement
|
143
|
+
# <--- IfElseStatement
|
144
|
+
# <--- SwitchStatement
|
145
|
+
# <--- IterationStatement
|
146
|
+
# <--- WhileStatement
|
147
|
+
# <--- DoStatement
|
148
|
+
# <--- ForStatement
|
149
|
+
# <--- C99ForStatement
|
150
|
+
# <--- JumpStatement
|
151
|
+
# <--- GotoStatement
|
152
|
+
# <--- ContinueStatement
|
153
|
+
# <--- BreakStatement
|
154
|
+
# <--- ReturnStatement
|
155
|
+
# <--- TranslationUnit
|
156
|
+
# <--- TypeName
|
157
|
+
# <--- Initializer
|
38
158
|
class SyntaxNode
|
39
159
|
include Visitable
|
40
160
|
|
41
161
|
def initialize
|
42
162
|
@head_token = nil
|
43
163
|
@tail_token = nil
|
164
|
+
@subsequent_sequence_point = nil
|
44
165
|
end
|
45
166
|
|
46
167
|
attr_accessor :head_token
|
47
168
|
attr_accessor :tail_token
|
169
|
+
attr_reader :subsequent_sequence_point
|
48
170
|
|
49
171
|
def location
|
50
172
|
subclass_responsibility
|
@@ -65,6 +187,19 @@ module C #:nodoc:
|
|
65
187
|
def short_class_name
|
66
188
|
self.class.name.sub(/\A.*::/, "")
|
67
189
|
end
|
190
|
+
|
191
|
+
protected
|
192
|
+
# === DESCRIPTION
|
193
|
+
# Append a subsequent sequence-point of this node.
|
194
|
+
def append_sequence_point!
|
195
|
+
@subsequent_sequence_point = SequencePoint.new(self)
|
196
|
+
end
|
197
|
+
|
198
|
+
# === DESCRIPTION
|
199
|
+
# Delete a subsequent sequence-point of this node.
|
200
|
+
def delete_sequence_point!
|
201
|
+
@subsequent_sequence_point = nil
|
202
|
+
end
|
68
203
|
end
|
69
204
|
|
70
205
|
module SyntaxNodeCollector
|
@@ -246,6 +381,32 @@ module C #:nodoc:
|
|
246
381
|
end
|
247
382
|
|
248
383
|
class Expression < SyntaxNode
|
384
|
+
def initialize
|
385
|
+
super
|
386
|
+
@full = false
|
387
|
+
end
|
388
|
+
|
389
|
+
def full=(full_expression)
|
390
|
+
@full = full_expression
|
391
|
+
|
392
|
+
# NOTE: The ISO C99 standard saids;
|
393
|
+
#
|
394
|
+
# Annex C (informative) Sequence points
|
395
|
+
#
|
396
|
+
# 1 The following are the sequence points described in 5.1.2.3:
|
397
|
+
#
|
398
|
+
# -- The end of a full expression: an initializer (6.7.8); the
|
399
|
+
# expression in an expression statement (6.8.3); the controlling
|
400
|
+
# expression of a while or do statement (6.8.5); each of the
|
401
|
+
# expressions of a for statement (6.8.5.3); the expression in a
|
402
|
+
# return statement (6.8.6.4).
|
403
|
+
if full_expression
|
404
|
+
append_sequence_point!
|
405
|
+
else
|
406
|
+
delete_sequence_point!
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
249
410
|
def have_side_effect?
|
250
411
|
subclass_responsibility
|
251
412
|
end
|
@@ -801,9 +962,41 @@ module C #:nodoc:
|
|
801
962
|
|
802
963
|
class InclusiveOrExpression < BinaryExpression; end
|
803
964
|
|
804
|
-
class LogicalAndExpression < BinaryExpression
|
965
|
+
class LogicalAndExpression < BinaryExpression
|
966
|
+
def initialize(operator, lhs_operand, rhs_operand)
|
967
|
+
super
|
968
|
+
|
969
|
+
# NOTE: The ISO C99 standard saids;
|
970
|
+
#
|
971
|
+
# 6.5.13 Logical AND operator
|
972
|
+
#
|
973
|
+
# Semantics
|
974
|
+
#
|
975
|
+
# 4 Unlike the bitwise binary & operator, the && operator guarantees
|
976
|
+
# left-to-right evaluation; there is a sequence point after the
|
977
|
+
# evaluation of the first operand. If the first operand compares equal
|
978
|
+
# to 0, the second operand is not evaluated.
|
979
|
+
@lhs_operand.append_sequence_point!
|
980
|
+
end
|
981
|
+
end
|
982
|
+
|
983
|
+
class LogicalOrExpression < BinaryExpression
|
984
|
+
def initialize(operator, lhs_operand, rhs_operand)
|
985
|
+
super
|
805
986
|
|
806
|
-
|
987
|
+
# NOTE: The ISO C99 standard saids;
|
988
|
+
#
|
989
|
+
# 6.5.14 Logical OR operator
|
990
|
+
#
|
991
|
+
# Semantics
|
992
|
+
#
|
993
|
+
# 4 Unlike the bitwise | operator, the || operator guarantees
|
994
|
+
# left-to-right evaluation; there is a sequence point after the
|
995
|
+
# evaluation of the first operand. If the first operand compares
|
996
|
+
# unequal to 0, the second operand is not evaluated.
|
997
|
+
@lhs_operand.append_sequence_point!
|
998
|
+
end
|
999
|
+
end
|
807
1000
|
|
808
1001
|
class ConditionalExpression < Expression
|
809
1002
|
def initialize(condition, then_expression, else_expression, question_mark)
|
@@ -812,6 +1005,22 @@ module C #:nodoc:
|
|
812
1005
|
@then_expression = then_expression
|
813
1006
|
@else_expression = else_expression
|
814
1007
|
@question_mark = question_mark
|
1008
|
+
|
1009
|
+
# NOTE: The ISO C99 standard saids;
|
1010
|
+
#
|
1011
|
+
# 6.5.15 Conditional operator
|
1012
|
+
#
|
1013
|
+
# Semantics
|
1014
|
+
#
|
1015
|
+
# 4 The first operand is evaluated; there is a sequence poit after its
|
1016
|
+
# evaluation. The second operand is evaluated only if the first
|
1017
|
+
# compares unequal to 0; the third operand is evaluated only if the
|
1018
|
+
# first compares equal to 0; thre result is the value of the second or
|
1019
|
+
# third operand (whichever is evaluated), converted to the type
|
1020
|
+
# described below. If an attempt is made to modify the result of a
|
1021
|
+
# conditional operator or to access it after the next sequence point,
|
1022
|
+
# the behavior is undefined.
|
1023
|
+
@condition.append_sequence_point!
|
815
1024
|
end
|
816
1025
|
|
817
1026
|
attr_reader :condition
|
@@ -856,7 +1065,8 @@ module C #:nodoc:
|
|
856
1065
|
class CommaSeparatedExpression < Expression
|
857
1066
|
def initialize(first_expression)
|
858
1067
|
super()
|
859
|
-
@expressions = [
|
1068
|
+
@expressions = []
|
1069
|
+
push(first_expression)
|
860
1070
|
end
|
861
1071
|
|
862
1072
|
attr_reader :expressions
|
@@ -875,6 +1085,19 @@ module C #:nodoc:
|
|
875
1085
|
|
876
1086
|
def push(expression)
|
877
1087
|
@expressions.push(expression)
|
1088
|
+
|
1089
|
+
# NOTE: The ISO C99 standard saids;
|
1090
|
+
#
|
1091
|
+
# 6.5.17 Comma operator
|
1092
|
+
#
|
1093
|
+
# Semantics
|
1094
|
+
#
|
1095
|
+
# 2 The left operand of a comma operator is evaluated as a void
|
1096
|
+
# expression; there is a sequence point after its evaluation. Then the
|
1097
|
+
# right operand is evaluated; the result has its type and value. If an
|
1098
|
+
# attempt is made to modify the result of a comma operator or to access
|
1099
|
+
# it after the next sequence point, the behavior is undefined.
|
1100
|
+
@expressions[-2].append_sequence_point! if @expressions.size > 1
|
878
1101
|
self
|
879
1102
|
end
|
880
1103
|
|
@@ -1644,6 +1867,7 @@ module C #:nodoc:
|
|
1644
1867
|
def initialize
|
1645
1868
|
super
|
1646
1869
|
@pointer = nil
|
1870
|
+
@full = false
|
1647
1871
|
end
|
1648
1872
|
|
1649
1873
|
attr_accessor :pointer
|
@@ -1656,6 +1880,33 @@ module C #:nodoc:
|
|
1656
1880
|
false
|
1657
1881
|
end
|
1658
1882
|
|
1883
|
+
def full=(full_declarator)
|
1884
|
+
@full = full_declarator
|
1885
|
+
|
1886
|
+
# NOTE: The ISO C99 standard saids;
|
1887
|
+
#
|
1888
|
+
# 6.7.5 Declarators
|
1889
|
+
#
|
1890
|
+
# Semantics
|
1891
|
+
#
|
1892
|
+
# 3 A full declarator is a declarator that is not part of another
|
1893
|
+
# declarator. The end of a full declarator is a sequence point. If,
|
1894
|
+
# in the nested sequence of declarators in a full declarator, there is
|
1895
|
+
# a declarator specifying a variable length array type, the type
|
1896
|
+
# specified by the full declarator is said to be variably modified.
|
1897
|
+
# Furthermore, any type derived by declarator type derivation from a
|
1898
|
+
# variably modified type is itself variably modified.
|
1899
|
+
if full_declarator
|
1900
|
+
append_sequence_point!
|
1901
|
+
else
|
1902
|
+
delete_sequence_point!
|
1903
|
+
end
|
1904
|
+
end
|
1905
|
+
|
1906
|
+
def full?
|
1907
|
+
@full
|
1908
|
+
end
|
1909
|
+
|
1659
1910
|
def base
|
1660
1911
|
subclass_responsibility
|
1661
1912
|
end
|
data/lib/adlint/c.rb
CHANGED
data/lib/adlint/cpp/code.rb
CHANGED
@@ -166,7 +166,7 @@ module Cpp #:nodoc:
|
|
166
166
|
|
167
167
|
def extract_line(line_line)
|
168
168
|
PP_DIRECTIVE(line_line.location, line_line.keyword.value,
|
169
|
-
line_line.pp_tokens
|
169
|
+
line_line.pp_tokens ? line_line.pp_tokens.to_s : "")
|
170
170
|
end
|
171
171
|
|
172
172
|
def extract_error(error_line)
|
@@ -176,7 +176,7 @@ module Cpp #:nodoc:
|
|
176
176
|
|
177
177
|
def extract_pragma(pragma_line)
|
178
178
|
PP_DIRECTIVE(pragma_line.location, pragma_line.keyword.value,
|
179
|
-
pragma_line.pp_tokens
|
179
|
+
pragma_line.pp_tokens ? pragma_line.pp_tokens.to_s : "")
|
180
180
|
end
|
181
181
|
|
182
182
|
def extract_null(null_directive)
|