adlint 1.2.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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