adlint 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|