adlint 1.2.0 → 1.4.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.
@@ -0,0 +1,151 @@
1
+ # Message detection classes for C language.
2
+ #
3
+ # Author:: Rie Shima <mailto:rkakuuchi@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:: Rie Shima <mailto:rkakuuchi@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
+ require "adlint/report"
33
+ require "adlint/message"
34
+
35
+ module AdLint #:nodoc:
36
+ module C #:nodoc:
37
+
38
+ class W0606 < PassiveMessageDetection
39
+ def initialize(context)
40
+ super
41
+ visitor = context[:c_visitor]
42
+ visitor.enter_union_type_declaration += method(:check)
43
+ end
44
+
45
+ private
46
+ def check(node)
47
+ node.struct_declarations.each do |struct_declaration|
48
+ struct_declaration.items.each do |member_decl|
49
+ if member_decl.type.scalar? && member_decl.type.floating?
50
+ W(:W0606, node.location)
51
+ return
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ class W0698 < PassiveMessageDetection
59
+ def initialize(context)
60
+ super
61
+ visitor = context[:c_visitor]
62
+ visitor.enter_ansi_function_definition += method(:start_function)
63
+ visitor.enter_kandr_function_definition += method(:start_function)
64
+ visitor.leave_ansi_function_definition += method(:end_function)
65
+ visitor.leave_kandr_function_definition += method(:end_function)
66
+ visitor.enter_return_statement += method(:check)
67
+ @current_function = nil
68
+ end
69
+
70
+ private
71
+ def start_function(function_definition)
72
+ @current_function = function_definition
73
+ end
74
+
75
+ def end_function(function_definition)
76
+ @current_function = nil
77
+ end
78
+
79
+ def check(return_statement)
80
+ return unless @current_function.explicitly_typed?
81
+
82
+ if return_type = @current_function.type.return_type
83
+ if !return_type.void? && return_statement.expression.nil?
84
+ W(:W0698, return_statement.location,
85
+ @current_function.identifier.value)
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ class W0699 < W0698
92
+ private
93
+ def check(return_statement)
94
+ return unless @current_function.implicitly_typed?
95
+
96
+ if return_statement.expression.nil?
97
+ W(:W0699, return_statement.location,
98
+ @current_function.identifier.value)
99
+ end
100
+ end
101
+ end
102
+
103
+ class W0726 < W0698
104
+ private
105
+ def check(return_statement)
106
+ return unless return_statement.expression
107
+
108
+ if return_type = @current_function.type.return_type
109
+ if return_type.void? && (return_type.const? || return_type.volatile?)
110
+ W(:W0726, return_statement.location,
111
+ @current_function.identifier.value)
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ class W0801 < PassiveMessageDetection
118
+ def initialize(context)
119
+ super
120
+ visitor = context[:c_visitor]
121
+ visitor.enter_struct_type_declaration += method(:check)
122
+ visitor.enter_union_type_declaration += method(:check)
123
+ end
124
+
125
+ private
126
+ def check(node)
127
+ W(:W0801, node.location) if node.type.members.empty?
128
+ end
129
+ end
130
+
131
+ class W1033 < PassiveMessageDetection
132
+ def initialize(context)
133
+ super
134
+ visitor = context[:c_visitor]
135
+ visitor.enter_ansi_function_definition += method(:check)
136
+ visitor.enter_kandr_function_definition += method(:check)
137
+ visitor.enter_function_declaration += method(:check)
138
+ end
139
+
140
+ private
141
+ def check(definition_or_declaration)
142
+ if return_type = definition_or_declaration.type.return_type
143
+ if return_type.const? || return_type.volatile?
144
+ W(:W1033, definition_or_declaration.location)
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ end
151
+ end
@@ -563,6 +563,7 @@ module C #:nodoc:
563
563
  W0599.new(context),
564
564
  W0600.new(context),
565
565
  W0605.new(context),
566
+ W0606.new(context),
566
567
  W0609.new(context),
567
568
  W0610.new(context),
568
569
  W0611.new(context),
@@ -613,12 +614,30 @@ module C #:nodoc:
613
614
  W0682.new(context),
614
615
  W0683.new(context),
615
616
  W0684.new(context),
617
+ W0698.new(context),
618
+ W0699.new(context),
616
619
  W0703.new(context),
617
620
  W0704.new(context),
618
621
  W0705.new(context),
619
622
  W0708.new(context),
623
+ W0720.new(context),
624
+ W0721.new(context),
625
+ W0722.new(context),
626
+ W0723.new(context),
627
+ W0726.new(context),
628
+ W0727.new(context),
629
+ W0728.new(context),
630
+ W0729.new(context),
631
+ W0730.new(context),
632
+ W0731.new(context),
620
633
  W0736.new(context),
634
+ W0737.new(context),
635
+ W0738.new(context),
636
+ W0739.new(context),
637
+ W0740.new(context),
638
+ W0741.new(context),
621
639
  W0742.new(context),
640
+ W0743.new(context),
622
641
  W0744.new(context),
623
642
  W0745.new(context),
624
643
  W0747.new(context),
@@ -660,6 +679,7 @@ module C #:nodoc:
660
679
  W0798.new(context),
661
680
  W0799.new(context),
662
681
  W0800.new(context),
682
+ W0801.new(context),
663
683
  W0810.new(context),
664
684
  W0827.new(context),
665
685
  W0828.new(context),
@@ -672,11 +692,14 @@ module C #:nodoc:
672
692
  W1029.new(context),
673
693
  W1031.new(context),
674
694
  W1032.new(context),
695
+ W1033.new(context),
675
696
  W1034.new(context),
676
697
  W1049.new(context),
677
698
  W1050.new(context),
678
699
  W1051.new(context),
679
700
  W1052.new(context),
701
+ W1064.new(context),
702
+ W1065.new(context),
680
703
  W9001.new(context)
681
704
  ]
682
705
  end
@@ -94,6 +94,7 @@ module C #:nodoc:
94
94
  checkpoint(node.location)
95
95
  type = @type_table.install_enum_type(node)
96
96
  node.type = type
97
+ node.enumerators.each { |enum| enum.type = type }
97
98
  end
98
99
 
99
100
  def visit_typedef_declaration(node)
@@ -1107,7 +1107,38 @@ module C #:nodoc:
1107
1107
  end
1108
1108
  end
1109
1109
 
1110
+ module DeclarationSpecifiersHolder
1111
+ def storage_class_specifier
1112
+ @declaration_specifiers ?
1113
+ @declaration_specifiers.storage_class_specifier : nil
1114
+ end
1115
+
1116
+ def function_specifier
1117
+ # NOTE: A function-specifier should only be in function-definitions.
1118
+ @declaration_specifiers ?
1119
+ @declaration_specifiers.function_specifier : nil
1120
+ end
1121
+
1122
+ def type_qualifiers
1123
+ @declaration_specifiers ? @declaration_specifiers.type_qualifiers : []
1124
+ end
1125
+
1126
+ def type_specifiers
1127
+ @declaration_specifiers ? @declaration_specifiers.type_specifiers : []
1128
+ end
1129
+
1130
+ def explicitly_typed?
1131
+ @declaration_specifiers && @declaration_specifiers.explicitly_typed?
1132
+ end
1133
+
1134
+ def implicitly_typed?
1135
+ !explicitly_typed?
1136
+ end
1137
+ end
1138
+
1110
1139
  class Declaration < SyntaxNode
1140
+ include DeclarationSpecifiersHolder
1141
+
1111
1142
  def initialize(declaration_specifiers, init_declarators, symbol_table)
1112
1143
  super()
1113
1144
  @declaration_specifiers = declaration_specifiers
@@ -1174,8 +1205,7 @@ module C #:nodoc:
1174
1205
  return []
1175
1206
  end
1176
1207
 
1177
- result = []
1178
- init_declarators.each do |init_declarator|
1208
+ init_declarators.each_with_object([]) do |init_declarator, result|
1179
1209
  if init_declarator.declarator.function?
1180
1210
  symbol = symbol_table.create_new_symbol(
1181
1211
  ObjectName, init_declarator.declarator.identifier)
@@ -1183,51 +1213,51 @@ module C #:nodoc:
1183
1213
  init_declarator, symbol))
1184
1214
  end
1185
1215
  end
1186
- result
1187
1216
  end
1188
1217
 
1189
1218
  def build_variable_declaration(declaration_specifiers, init_declarators,
1190
1219
  symbol_table)
1191
1220
  return [] unless declaration_specifiers
1192
1221
 
1193
- result = []
1194
- if declaration_specifiers.storage_class_specifier &&
1222
+ unless declaration_specifiers.storage_class_specifier &&
1195
1223
  declaration_specifiers.storage_class_specifier.type == :EXTERN
1196
- init_declarators.each do |init_declarator|
1197
- if init_declarator.declarator.variable?
1198
- declarator = init_declarator.declarator
1199
- symbol =
1200
- symbol_table.create_new_symbol(ObjectName, declarator.identifier)
1201
- result.push(VariableDeclaration.new(declaration_specifiers,
1202
- declarator, symbol))
1203
- end
1224
+ return []
1225
+ end
1226
+
1227
+ init_declarators.each_with_object([]) do |init_declarator, result|
1228
+ if init_declarator.declarator.variable?
1229
+ declarator = init_declarator.declarator
1230
+ symbol =
1231
+ symbol_table.create_new_symbol(ObjectName, declarator.identifier)
1232
+ result.push(VariableDeclaration.new(declaration_specifiers,
1233
+ declarator, symbol))
1204
1234
  end
1205
1235
  end
1206
- result
1207
1236
  end
1208
1237
 
1209
1238
  def build_variable_definition(declaration_specifiers, init_declarators,
1210
1239
  symbol_table)
1211
- result = []
1212
- unless declaration_specifiers &&
1240
+ if declaration_specifiers &&
1213
1241
  declaration_specifiers.storage_class_specifier &&
1214
1242
  (declaration_specifiers.storage_class_specifier.type == :EXTERN ||
1215
1243
  declaration_specifiers.storage_class_specifier.type == :TYPEDEF)
1216
- init_declarators.each do |init_declarator|
1217
- if init_declarator.declarator.variable?
1218
- symbol = symbol_table.create_new_symbol(
1219
- ObjectName, init_declarator.declarator.identifier)
1220
- result.push(VariableDefinition.new(declaration_specifiers,
1221
- init_declarator, symbol))
1222
- end
1244
+ return []
1245
+ end
1246
+
1247
+ init_declarators.each_with_object([]) do |init_declarator, result|
1248
+ if init_declarator.declarator.variable?
1249
+ symbol = symbol_table.create_new_symbol(
1250
+ ObjectName, init_declarator.declarator.identifier)
1251
+ result.push(VariableDefinition.new(declaration_specifiers,
1252
+ init_declarator, symbol))
1223
1253
  end
1224
1254
  end
1225
- result
1226
1255
  end
1227
1256
  end
1228
1257
 
1229
1258
  class FunctionDeclaration < SyntaxNode
1230
1259
  include SymbolicElement
1260
+ include DeclarationSpecifiersHolder
1231
1261
  include SyntaxNodeCollector
1232
1262
 
1233
1263
  def initialize(declaration_specifiers, init_declarator, symbol)
@@ -1247,11 +1277,6 @@ module C #:nodoc:
1247
1277
  @init_declarator.declarator.identifier
1248
1278
  end
1249
1279
 
1250
- def storage_class_specifier
1251
- @declaration_specifiers ?
1252
- @declaration_specifiers.storage_class_specifier : nil
1253
- end
1254
-
1255
1280
  def signature
1256
1281
  FunctionSignature.new(identifier, @type)
1257
1282
  end
@@ -1272,6 +1297,7 @@ module C #:nodoc:
1272
1297
 
1273
1298
  class VariableDeclaration < SyntaxNode
1274
1299
  include SymbolicElement
1300
+ include DeclarationSpecifiersHolder
1275
1301
 
1276
1302
  def initialize(declaration_specifiers, declarator, symbol)
1277
1303
  super()
@@ -1290,11 +1316,6 @@ module C #:nodoc:
1290
1316
  @declarator.identifier
1291
1317
  end
1292
1318
 
1293
- def storage_class_specifier
1294
- @declaration_specifiers ?
1295
- @declaration_specifiers.storage_class_specifier : nil
1296
- end
1297
-
1298
1319
  def location
1299
1320
  identifier.location
1300
1321
  end
@@ -1305,33 +1326,35 @@ module C #:nodoc:
1305
1326
  end
1306
1327
  end
1307
1328
 
1308
- class Definition < SyntaxNode; end
1329
+ class Definition < SyntaxNode
1330
+ include DeclarationSpecifiersHolder
1331
+
1332
+ def initialize(declaration_specifiers)
1333
+ @declaration_specifiers = declaration_specifiers
1334
+ @type = nil
1335
+ end
1336
+
1337
+ attr_reader :declaration_specifiers
1338
+ attr_accessor :type
1339
+ end
1309
1340
 
1310
1341
  class VariableDefinition < Definition
1311
1342
  include SymbolicElement
1312
1343
 
1313
1344
  def initialize(declaration_specifiers, init_declarator, symbol)
1314
- super()
1315
- @declaration_specifiers = declaration_specifiers
1345
+ super(declaration_specifiers)
1346
+
1316
1347
  @init_declarator = init_declarator
1317
1348
  @symbol = symbol
1318
- @type = nil
1319
1349
  end
1320
1350
 
1321
- attr_reader :declaration_specifiers
1322
1351
  attr_reader :init_declarator
1323
1352
  attr_reader :symbol
1324
- attr_accessor :type
1325
1353
 
1326
1354
  def identifier
1327
1355
  @init_declarator.declarator.identifier
1328
1356
  end
1329
1357
 
1330
- def storage_class_specifier
1331
- @declaration_specifiers ?
1332
- @declaration_specifiers.storage_class_specifier : nil
1333
- end
1334
-
1335
1358
  def initializer
1336
1359
  @init_declarator.initializer
1337
1360
  end
@@ -1358,6 +1381,8 @@ module C #:nodoc:
1358
1381
  end
1359
1382
 
1360
1383
  class TypedefDeclaration < TypeDeclaration
1384
+ include DeclarationSpecifiersHolder
1385
+
1361
1386
  def initialize(declaration_specifiers, init_declarator, symbol)
1362
1387
  super(symbol)
1363
1388
  @declaration_specifiers = declaration_specifiers
@@ -1377,14 +1402,6 @@ module C #:nodoc:
1377
1402
  @init_declarator.declarator
1378
1403
  end
1379
1404
 
1380
- def type_qualifiers
1381
- @declaration_specifiers.type_qualifiers
1382
- end
1383
-
1384
- def type_specifiers
1385
- @declaration_specifiers.type_specifiers
1386
- end
1387
-
1388
1405
  def location
1389
1406
  identifier.location
1390
1407
  end
@@ -1519,6 +1536,14 @@ module C #:nodoc:
1519
1536
  head_location
1520
1537
  end
1521
1538
 
1539
+ def explicitly_typed?
1540
+ !implicitly_typed?
1541
+ end
1542
+
1543
+ def implicitly_typed?
1544
+ @type_specifiers.empty?
1545
+ end
1546
+
1522
1547
  def inspect(indent = 0)
1523
1548
  " " * indent + short_class_name
1524
1549
  end
@@ -1689,14 +1714,12 @@ module C #:nodoc:
1689
1714
 
1690
1715
  private
1691
1716
  def build_items(specifier_qualifier_list, struct_declarators)
1692
- result = []
1693
- struct_declarators.each do |struct_declarator|
1717
+ struct_declarators.each_with_object([]) do |struct_declarator, items|
1694
1718
  # FIXME: Must support unnamed bit padding.
1695
1719
  next unless struct_declarator.declarator
1696
- result.push(MemberDeclaration.new(specifier_qualifier_list,
1697
- struct_declarator))
1720
+ items.push(MemberDeclaration.new(specifier_qualifier_list,
1721
+ struct_declarator))
1698
1722
  end
1699
- result
1700
1723
  end
1701
1724
  end
1702
1725
 
@@ -1818,6 +1841,7 @@ module C #:nodoc:
1818
1841
  attr_reader :expression
1819
1842
  attr_reader :symbol
1820
1843
  attr_accessor :value
1844
+ attr_accessor :type
1821
1845
 
1822
1846
  def location
1823
1847
  @identifier.location
@@ -2114,6 +2138,8 @@ module C #:nodoc:
2114
2138
  end
2115
2139
 
2116
2140
  class ParameterDeclaration < SyntaxNode
2141
+ include DeclarationSpecifiersHolder
2142
+
2117
2143
  def initialize(declaration_specifiers, declarator)
2118
2144
  super()
2119
2145
  @declaration_specifiers = declaration_specifiers
@@ -2749,36 +2775,23 @@ module C #:nodoc:
2749
2775
 
2750
2776
  def initialize(declaration_specifiers, declarator, parameter_definitions,
2751
2777
  compound_statement, symbol_table)
2752
- super()
2753
- @declaration_specifiers = declaration_specifiers
2778
+ super(declaration_specifiers)
2779
+
2754
2780
  @declarator = declarator
2755
2781
  @parameter_definitions = parameter_definitions
2756
2782
  @function_body = compound_statement
2757
2783
  @symbol = symbol_table.create_new_symbol(ObjectName, identifier)
2758
- @type = nil
2759
2784
  @type_declaration = build_type_declaration(declaration_specifiers,
2760
2785
  symbol_table)
2761
2786
  build_label_references(compound_statement)
2762
2787
  end
2763
2788
 
2764
- attr_reader :declaration_specifiers
2765
2789
  attr_reader :declarator
2766
2790
  attr_reader :parameter_definitions
2767
2791
  attr_reader :function_body
2768
2792
  attr_reader :symbol
2769
- attr_accessor :type
2770
2793
  attr_reader :type_declaration
2771
2794
 
2772
- def storage_class_specifier
2773
- @declaration_specifiers ?
2774
- @declaration_specifiers.storage_class_specifier : nil
2775
- end
2776
-
2777
- def function_specifier
2778
- @declaration_specifiers ?
2779
- @declaration_specifiers.function_specifier : nil
2780
- end
2781
-
2782
2795
  def identifier
2783
2796
  @declarator.identifier
2784
2797
  end
@@ -2856,14 +2869,12 @@ module C #:nodoc:
2856
2869
  def create_parameters(parameter_names, declarations, symbol_table)
2857
2870
  return [] unless parameter_names
2858
2871
 
2859
- result = []
2860
- parameter_names.each do |name|
2872
+ parameter_names.each_with_object([]) do |name, result|
2861
2873
  variable_definition =
2862
2874
  find_variable_definition(declarations, name, symbol_table)
2863
2875
  result.push(
2864
2876
  variable_definition_to_parameter_definition(variable_definition))
2865
2877
  end
2866
- result
2867
2878
  end
2868
2879
 
2869
2880
  def find_variable_definition(declarations, name, symbol_table)
@@ -2942,15 +2953,12 @@ module C #:nodoc:
2942
2953
 
2943
2954
  class ParameterDefinition < Definition
2944
2955
  def initialize(declaration_specifiers, declarator)
2945
- super()
2946
- @declaration_specifiers = declaration_specifiers
2956
+ super(declaration_specifiers)
2957
+
2947
2958
  @declarator = declarator
2948
- @type = nil
2949
2959
  end
2950
2960
 
2951
- attr_reader :declaration_specifiers
2952
2961
  attr_reader :declarator
2953
- attr_accessor :type
2954
2962
 
2955
2963
  def identifier
2956
2964
  if @declarator
@@ -2964,19 +2972,14 @@ module C #:nodoc:
2964
2972
  end
2965
2973
  end
2966
2974
 
2967
- def storage_class_specifier
2968
- @declaration_specifiers ?
2969
- @declaration_specifiers.storage_class_specifier : nil
2970
- end
2971
-
2972
2975
  def location
2973
2976
  identifier ? identifier.location : nil
2974
2977
  end
2975
2978
 
2976
2979
  def to_variable_definition
2977
- PseudoVariableDefinition.new(@declaration_specifiers,
2980
+ PseudoVariableDefinition.new(declaration_specifiers,
2978
2981
  InitDeclarator.new(@declarator, nil),
2979
- @type)
2982
+ type)
2980
2983
  end
2981
2984
 
2982
2985
  def inspect(indent = 0)
@@ -2989,7 +2992,8 @@ module C #:nodoc:
2989
2992
  class PseudoVariableDefinition < VariableDefinition
2990
2993
  def initialize(declaration_specifiers, init_declarator, type)
2991
2994
  super(declaration_specifiers, init_declarator, nil)
2992
- @type = type
2995
+
2996
+ self.type = type
2993
2997
  end
2994
2998
 
2995
2999
  def mark_as_referred_by(token) end