adlint 1.8.2 → 1.8.10

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.
@@ -765,15 +765,15 @@ module C #:nodoc:
765
765
  # Boolean -- True if types of arguments match this directive.
766
766
  def acceptable?
767
767
  if @field_width_argument
768
- unless @field_width_argument.type.same_as?(signed_int_type) ||
769
- @field_width_argument.type.same_as?(unsigned_int_type)
768
+ unless signed_int_type.same_as?(@field_width_argument.type) ||
769
+ unsigned_int_type.same_as?(@field_width_argument.type)
770
770
  return false
771
771
  end
772
772
  end
773
773
 
774
774
  if @precision_argument
775
- unless @precision_argument.type.same_as?(signed_int_type) ||
776
- @precision_argument.type.same_as?(unsigned_int_type)
775
+ unless signed_int_type.same_as?(@precision_argument.type) ||
776
+ unsigned_int_type.same_as?(@precision_argument.type)
777
777
  return false
778
778
  end
779
779
  end
@@ -781,7 +781,7 @@ module C #:nodoc:
781
781
  if @conversion_argument
782
782
  if argument_types
783
783
  argument_types.any? do |arg_type|
784
- @conversion_argument.type.same_as?(arg_type)
784
+ arg_type.same_as?(@conversion_argument.type)
785
785
  end
786
786
  else
787
787
  true
@@ -2502,7 +2502,7 @@ module C #:nodoc:
2502
2502
  if @conversion_argument
2503
2503
  if argument_types
2504
2504
  argument_types.any? do |arg_type|
2505
- @conversion_argument.type.same_as?(arg_type)
2505
+ arg_type.same_as?(@conversion_argument.type)
2506
2506
  end
2507
2507
  else
2508
2508
  true
@@ -1156,72 +1156,31 @@ module C #:nodoc:
1156
1156
  class W0051 < PassiveMessageDetection
1157
1157
  def initialize(context)
1158
1158
  super
1159
- visitor = context[:c_visitor]
1160
- visitor.enter_compound_statement += method(:enter_compound_statement)
1161
- visitor.leave_compound_statement += method(:leave_compound_statement)
1162
- visitor.enter_variable_declaration += method(:add_variable_decl)
1163
- visitor.enter_variable_definition += method(:add_variable_def)
1164
- visitor.enter_function_declaration += method(:add_function_decl)
1165
- visitor.enter_ansi_function_definition += method(:add_function_def)
1166
- visitor.enter_kandr_function_definition += method(:add_function_def)
1167
- visitor.leave_translation_unit += method(:check)
1168
- @block_level = 0
1159
+ interp = context[:c_interpreter]
1160
+ interp.on_variable_declared += method(:add_variable)
1161
+ interp.on_variable_defined += method(:add_variable)
1162
+ interp.on_function_declared += method(:add_function)
1163
+ interp.on_function_started += method(:add_function)
1164
+ interp.on_translation_unit_ended += method(:check)
1169
1165
  @identifiers = Hash.new { |hash, key| hash[key] = [] }
1170
1166
  end
1171
1167
 
1172
1168
  private
1173
- def enter_compound_statement(node)
1174
- @block_level += 1
1175
- end
1176
-
1177
- def leave_compound_statement(node)
1178
- @block_level -= 1
1179
- end
1180
-
1181
- def add_variable_decl(node)
1182
- if @block_level == 0 && node.storage_class_specifier &&
1183
- node.storage_class_specifier.type == :EXTERN
1184
- @identifiers[mangle(node.identifier.value)].push(
1185
- [node.identifier, true])
1186
- else
1187
- @identifiers[mangle(node.identifier.value)].push(
1188
- [node.identifier, false])
1189
- end
1190
- end
1191
-
1192
- def add_variable_def(node)
1193
- if @block_level == 0 && node.storage_class_specifier.nil?
1194
- @identifiers[mangle(node.identifier.value)].push(
1195
- [node.identifier, true])
1196
- else
1197
- @identifiers[mangle(node.identifier.value)].push(
1198
- [node.identifier, false])
1199
- end
1200
- end
1201
-
1202
- def add_function_decl(node)
1203
- if node.storage_class_specifier.nil? ||
1204
- node.storage_class_specifier.type == :EXTERN
1205
- @identifiers[mangle(node.identifier.value)].push(
1206
- [node.identifier, true])
1207
- else
1208
- @identifiers[mangle(node.identifier.value)].push(
1209
- [node.identifier, false])
1169
+ def add_variable(decl_or_def, variable)
1170
+ if variable.named?
1171
+ @identifiers[mangle(variable.name)].push(
1172
+ [decl_or_def.identifier, variable.declared_as_extern?])
1210
1173
  end
1211
1174
  end
1212
1175
 
1213
- def add_function_def(node)
1214
- if node.storage_class_specifier.nil? ||
1215
- node.storage_class_specifier.type == :EXTERN
1216
- @identifiers[mangle(node.identifier.value)].push(
1217
- [node.identifier, true])
1218
- else
1219
- @identifiers[mangle(node.identifier.value)].push(
1220
- [node.identifier, false])
1176
+ def add_function(decl_or_def, function)
1177
+ if function.named?
1178
+ @identifiers[mangle(function.name)].push(
1179
+ [decl_or_def.identifier, function.declared_as_extern?])
1221
1180
  end
1222
1181
  end
1223
1182
 
1224
- def check(node)
1183
+ def check(*)
1225
1184
  @identifiers.each do |key, id_array|
1226
1185
  id_array.uniq! { |id| id[0].value }
1227
1186
  if id_array.size > 1
@@ -1578,30 +1537,29 @@ module C #:nodoc:
1578
1537
  class W0080 < PassiveMessageDetection
1579
1538
  def initialize(context)
1580
1539
  super
1581
- visitor = context[:c_visitor]
1582
- visitor.enter_variable_definition += method(:check)
1583
- visitor.enter_compound_statement += method(:enter_block)
1584
- visitor.leave_compound_statement += method(:leave_block)
1540
+ interp = context[:c_interpreter]
1541
+ interp.on_variable_defined += method(:check)
1542
+ interp.on_block_started += method(:enter_block)
1543
+ interp.on_block_ended += method(:leave_block)
1585
1544
  @block_level = 0
1586
1545
  end
1587
1546
 
1588
1547
  private
1589
- def check(node)
1590
- return if @block_level > 0
1591
-
1592
- return if node.storage_class_specifier &&
1593
- node.storage_class_specifier.type == :EXTERN
1594
-
1595
- if node.type.const?
1596
- W(:W0080, node.location) unless node.initializer
1548
+ def check(variable_definition, variable)
1549
+ if @block_level == 0
1550
+ if variable.declared_as_extern? || variable.declared_as_static?
1551
+ if variable.type.const? && variable_definition.initializer.nil?
1552
+ W(:W0080, variable_definition.location)
1553
+ end
1554
+ end
1597
1555
  end
1598
1556
  end
1599
1557
 
1600
- def enter_block(node)
1558
+ def enter_block(*)
1601
1559
  @block_level += 1
1602
1560
  end
1603
1561
 
1604
- def leave_block(node)
1562
+ def leave_block(*)
1605
1563
  @block_level -= 1
1606
1564
  end
1607
1565
  end
@@ -1916,8 +1874,13 @@ module C #:nodoc:
1916
1874
  return unless lhs_variable.type.pointer? && rhs_variable.type.pointer?
1917
1875
 
1918
1876
  if rhs_pointee = @interp.pointee_of(rhs_variable)
1919
- if rhs_pointee.variable? && rhs_pointee.named? &&
1920
- rhs_pointee.binding.memory.dynamic?
1877
+ if rhs_pointee.variable? && rhs_pointee.named?
1878
+ return unless rhs_pointee.binding.memory.dynamic?
1879
+ # NOTE: An array typed parameter can be considerd as an alias of the
1880
+ # corresponding argument. So, it is safe to return an address
1881
+ # of the argument.
1882
+ return if rhs_pointee.type.parameter? && rhs_pointee.type.array?
1883
+
1921
1884
  case
1922
1885
  when lhs_variable.binding.memory.static?
1923
1886
  W(:W0101, assignment_expression.location)
@@ -1978,8 +1941,12 @@ module C #:nodoc:
1978
1941
  end
1979
1942
 
1980
1943
  if rhs_pointee = @interp.pointee_of(rhs_variable)
1981
- if rhs_pointee.variable? && rhs_pointee.named? &&
1982
- rhs_pointee.binding.memory.dynamic?
1944
+ if rhs_pointee.variable? && rhs_pointee.named?
1945
+ return unless rhs_pointee.binding.memory.dynamic?
1946
+ # NOTE: An array typed parameter can be considerd as an alias of the
1947
+ # corresponding argument. So, it is safe to return an address
1948
+ # of the argument.
1949
+ return if rhs_pointee.type.parameter? && rhs_pointee.type.array?
1983
1950
  W(:W0102, assignment_expression.location)
1984
1951
  end
1985
1952
  end
@@ -2022,6 +1989,10 @@ module C #:nodoc:
2022
1989
 
2023
1990
  if pointee = @interp.pointee_of(result_variable)
2024
1991
  if pointee.variable? && pointee.named?
1992
+ # NOTE: An array typed parameter can be considerd as an alias of the
1993
+ # corresponding argument. So, it is safe to return an address
1994
+ # of the argument.
1995
+ return if pointee.type.parameter? && pointee.type.array?
2025
1996
  if @local_variables.include?(pointee.name)
2026
1997
  W(:W0103, return_statement.location)
2027
1998
  end
@@ -2161,9 +2132,13 @@ module C #:nodoc:
2161
2132
 
2162
2133
  if rhs_pointee = @interp.pointee_of(rhs_variable)
2163
2134
  if rhs_pointee.variable? && rhs_pointee.named?
2164
- if lhs_variable.scope.local? &&
2165
- lhs_variable.binding.memory.static? &&
2166
- rhs_pointee.binding.memory.dynamic?
2135
+ return unless rhs_pointee.binding.memory.dynamic?
2136
+ # NOTE: An array typed parameter can be considerd as an alias of the
2137
+ # corresponding argument. So, it is safe to return an address
2138
+ # of the argument.
2139
+ return if rhs_pointee.type.parameter? && rhs_pointee.type.array?
2140
+
2141
+ if lhs_variable.scope.local? && lhs_variable.binding.memory.static?
2167
2142
  W(:W0107, assignment_expression.location)
2168
2143
  end
2169
2144
  end
@@ -2515,114 +2490,85 @@ module C #:nodoc:
2515
2490
  class W0117 < PassiveMessageDetection
2516
2491
  def initialize(context)
2517
2492
  super
2518
- visitor = context[:c_visitor]
2519
- visitor.enter_function_declaration += method(:declare_function)
2520
- visitor.enter_variable_declaration += method(:declare_variable)
2521
- visitor.enter_ansi_function_definition += method(:check_function)
2522
- visitor.enter_kandr_function_definition += method(:check_function)
2523
- visitor.enter_variable_definition += method(:check_variable)
2524
- visitor.enter_compound_statement += method(:enter_block)
2525
- visitor.leave_compound_statement += method(:leave_block)
2493
+ interp = context[:c_interpreter]
2494
+ interp.on_function_declared += method(:declare_function)
2495
+ interp.on_variable_declared += method(:declare_variable)
2496
+ interp.on_function_started += method(:check_function)
2497
+ interp.on_variable_defined += method(:check_variable)
2526
2498
  @target_fpath = context[:sources].first.fpath
2527
2499
  @external_symbols = Set.new
2528
- @scope_depth = 0
2529
2500
  end
2530
2501
 
2531
2502
  private
2532
- def declare_function(node)
2533
- if external_declaration?(node)
2534
- unless @external_symbols.include?(node.identifier.value)
2535
- @external_symbols.add(node.identifier.value)
2536
- end
2503
+ def declare_function(function_declaration, function)
2504
+ if function.named? && function.declared_as_extern?
2505
+ @external_symbols.add(function.name)
2537
2506
  end
2538
2507
  end
2539
2508
 
2540
- def declare_variable(node)
2541
- if external_declaration?(node)
2542
- unless @external_symbols.include?(node.identifier.value)
2543
- @external_symbols.add(node.identifier.value)
2544
- end
2509
+ def declare_variable(variable_declaration, variable)
2510
+ if variable.named? && variable.declared_as_extern?
2511
+ @external_symbols.add(variable.name)
2545
2512
  end
2546
2513
  end
2547
2514
 
2548
- def check_function(node)
2549
- return if node.identifier.value == "main"
2550
- if external_definition?(node)
2551
- unless @external_symbols.include?(node.identifier.value)
2552
- if node.location.fpath == @target_fpath
2553
- W(:W0117, node.location, node.identifier.value)
2515
+ def check_function(function_definition, function)
2516
+ if function.named? && function.declared_as_extern?
2517
+ return if function.name == "main"
2518
+
2519
+ unless @external_symbols.include?(function.name)
2520
+ if function_definition.location.fpath == @target_fpath
2521
+ W(:W0117, function_definition.location, function.name)
2554
2522
  end
2555
2523
  end
2556
2524
  end
2557
2525
  end
2558
2526
 
2559
- def check_variable(node)
2560
- if external_definition?(node)
2561
- unless @external_symbols.include?(node.identifier.value)
2562
- if node.location.fpath == @target_fpath
2563
- W(:W0117, node.location, node.identifier.value)
2527
+ def check_variable(variable_definition, variable)
2528
+ if variable.named? && variable.declared_as_extern?
2529
+ unless @external_symbols.include?(variable.name)
2530
+ if variable_definition.location.fpath == @target_fpath
2531
+ W(:W0117, variable_definition.location, variable.name)
2564
2532
  end
2565
2533
  end
2566
2534
  end
2567
2535
  end
2568
-
2569
- def enter_block(node)
2570
- @scope_depth += 1
2571
- end
2572
-
2573
- def leave_block(node)
2574
- @scope_depth -= 1
2575
- end
2576
-
2577
- def external_declaration?(node)
2578
- node.storage_class_specifier &&
2579
- node.storage_class_specifier.type == :EXTERN
2580
- end
2581
-
2582
- def external_definition?(node)
2583
- (@scope_depth == 0 && node.storage_class_specifier.nil?) ||
2584
- (node.storage_class_specifier &&
2585
- node.storage_class_specifier.type == :EXTERN)
2586
- end
2587
2536
  end
2588
2537
 
2589
2538
  class W0118 < PassiveMessageDetection
2590
2539
  def initialize(context)
2591
2540
  super
2592
- visitor = context[:c_visitor]
2593
- visitor.enter_function_declaration += method(:check_function)
2594
- visitor.enter_variable_declaration += method(:check_variable)
2541
+ interp = context[:c_interpreter]
2542
+ interp.on_function_declared += method(:check_function)
2543
+ interp.on_variable_declared += method(:check_variable)
2595
2544
  @target_fpath = context[:sources].first.fpath
2596
2545
  @external_symbols = Set.new
2597
2546
  end
2598
2547
 
2599
2548
  private
2600
- def check_function(node)
2601
- if external?(node)
2602
- unless @external_symbols.include?(node.identifier.value)
2603
- if node.location.fpath == @target_fpath
2604
- W(:W0118, node.location, node.identifier.value)
2549
+ def check_function(function_declaration, function)
2550
+ if function.named? && function.declared_as_extern?
2551
+ unless @external_symbols.include?(function.name)
2552
+ if function_declaration.location.fpath == @target_fpath
2553
+ W(:W0118, function_declaration.location, function.name)
2554
+ else
2555
+ @external_symbols.add(function.name)
2605
2556
  end
2606
- @external_symbols.add(node.identifier.value)
2607
2557
  end
2608
2558
  end
2609
2559
  end
2610
2560
 
2611
- def check_variable(node)
2612
- if external?(node)
2613
- unless @external_symbols.include?(node.identifier.value)
2614
- if node.location.fpath == @target_fpath
2615
- W(:W0118, node.location, node.identifier.value)
2561
+ def check_variable(variable_declaration, variable)
2562
+ if variable.named? && variable.declared_as_extern?
2563
+ unless @external_symbols.include?(variable.name)
2564
+ if variable_declaration.location.fpath == @target_fpath
2565
+ W(:W0118, variable_declaration.location, variable.name)
2566
+ else
2567
+ @external_symbols.add(variable.name)
2616
2568
  end
2617
- @external_symbols.add(node.identifier.value)
2618
2569
  end
2619
2570
  end
2620
2571
  end
2621
-
2622
- def external?(node)
2623
- node.storage_class_specifier &&
2624
- node.storage_class_specifier.type == :EXTERN
2625
- end
2626
2572
  end
2627
2573
 
2628
2574
  class W0119 < PassiveMessageDetection
@@ -6920,42 +6866,28 @@ module C #:nodoc:
6920
6866
  class W0456 < PassiveMessageDetection
6921
6867
  def initialize(context)
6922
6868
  super
6923
- visitor = context[:c_visitor]
6924
- visitor.enter_variable_definition += method(:check_variable)
6925
- visitor.enter_ansi_function_definition += method(:check_function)
6926
- visitor.enter_kandr_function_definition += method(:check_function)
6927
- visitor.enter_compound_statement += method(:enter_block)
6928
- visitor.leave_compound_statement += method(:leave_block)
6869
+ interp = context[:c_interpreter]
6870
+ interp.on_variable_defined += method(:check_variable)
6871
+ interp.on_function_started += method(:check_function)
6929
6872
  @target_fpath = context[:sources].first.fpath
6930
- @scope_depth = 0
6931
6873
  end
6932
6874
 
6933
6875
  private
6934
- def check_variable(node)
6935
- if external?(node) && node.location.fpath != @target_fpath
6936
- W(:W0456, node.location, node.identifier.value)
6876
+ def check_variable(variable_definition, variable)
6877
+ if variable.declared_as_extern?
6878
+ unless variable_definition.location.fpath == @target_fpath
6879
+ W(:W0456, variable_definition.location, variable.name)
6880
+ end
6937
6881
  end
6938
6882
  end
6939
6883
 
6940
- def check_function(node)
6941
- if external?(node) && node.location.fpath != @target_fpath
6942
- W(:W0456, node.location, node.identifier.value)
6884
+ def check_function(function_definition, function)
6885
+ if function.declared_as_extern?
6886
+ unless function_definition.location.fpath == @target_fpath
6887
+ W(:W0456, function_definition.location, function.name)
6888
+ end
6943
6889
  end
6944
6890
  end
6945
-
6946
- def enter_block(node)
6947
- @scope_depth += 1
6948
- end
6949
-
6950
- def leave_block(node)
6951
- @scope_depth -= 1
6952
- end
6953
-
6954
- def external?(node)
6955
- (@scope_depth == 0 && node.storage_class_specifier.nil?) ||
6956
- (node.storage_class_specifier &&
6957
- node.storage_class_specifier.type == :EXTERN)
6958
- end
6959
6891
  end
6960
6892
 
6961
6893
  class W0457 < PassiveMessageDetection
@@ -11109,62 +11041,52 @@ module C #:nodoc:
11109
11041
  class W0622 < PassiveMessageDetection
11110
11042
  def initialize(context)
11111
11043
  super
11112
- visitor = context[:c_visitor]
11113
- visitor.enter_function_declaration += method(:check)
11114
- visitor.enter_compound_statement += method(:enter_block)
11115
- visitor.leave_compound_statement += method(:leave_block)
11116
- @block_depth = 0
11044
+ interp = context[:c_interpreter]
11045
+ interp.on_function_declared += method(:check)
11046
+ interp.on_block_started += method(:enter_block)
11047
+ interp.on_block_ended += method(:leave_block)
11048
+ @block_level = 0
11117
11049
  end
11118
11050
 
11119
11051
  private
11120
- def check(function_declaration)
11121
- if @block_depth > 0 && external_declaration?(function_declaration)
11052
+ def check(function_declaration, function)
11053
+ if @block_level > 0 && function.declared_as_extern?
11122
11054
  W(:W0622, function_declaration.location)
11123
11055
  end
11124
11056
  end
11125
11057
 
11126
- def enter_block(node)
11127
- @block_depth += 1
11128
- end
11129
-
11130
- def leave_block(node)
11131
- @block_depth -= 1
11058
+ def enter_block(*)
11059
+ @block_level += 1
11132
11060
  end
11133
11061
 
11134
- def external_declaration?(node)
11135
- node.storage_class_specifier.nil? ||
11136
- node.storage_class_specifier.type == :EXTERN
11062
+ def leave_block(*)
11063
+ @block_level -= 1
11137
11064
  end
11138
11065
  end
11139
11066
 
11140
11067
  class W0623 < PassiveMessageDetection
11141
11068
  def initialize(context)
11142
11069
  super
11143
- visitor = context[:c_visitor]
11144
- visitor.enter_variable_declaration += method(:check)
11145
- visitor.enter_compound_statement += method(:enter_block)
11146
- visitor.leave_compound_statement += method(:leave_block)
11147
- @block_depth = 0
11070
+ interp = context[:c_interpreter]
11071
+ interp.on_variable_declared += method(:check)
11072
+ interp.on_block_started += method(:enter_block)
11073
+ interp.on_block_ended += method(:leave_block)
11074
+ @block_level = 0
11148
11075
  end
11149
11076
 
11150
11077
  private
11151
- def check(variable_declaration)
11152
- if @block_depth > 0 && external_declaration?(variable_declaration)
11078
+ def check(variable_declaration, variable)
11079
+ if @block_level > 0 && variable.declared_as_extern?
11153
11080
  W(:W0623, variable_declaration.location)
11154
11081
  end
11155
11082
  end
11156
11083
 
11157
- def enter_block(node)
11158
- @block_depth += 1
11159
- end
11160
-
11161
- def leave_block(node)
11162
- @block_depth -= 1
11084
+ def enter_block(*)
11085
+ @block_level += 1
11163
11086
  end
11164
11087
 
11165
- def external_declaration?(node)
11166
- node.storage_class_specifier.nil? ||
11167
- node.storage_class_specifier.type == :EXTERN
11088
+ def leave_block(*)
11089
+ @block_level -= 1
11168
11090
  end
11169
11091
  end
11170
11092
 
@@ -12805,10 +12727,8 @@ module C #:nodoc:
12805
12727
  def define_variable(variable_definition, variable)
12806
12728
  return unless @functions.empty?
12807
12729
 
12808
- if storage_class_specifier = variable_definition.storage_class_specifier
12809
- if storage_class_specifier.type == :STATIC
12810
- @static_variables[variable] = [variable_definition, Set.new]
12811
- end
12730
+ if variable.declared_as_static?
12731
+ @static_variables[variable] = [variable_definition, Set.new]
12812
12732
  end
12813
12733
  end
12814
12734
 
@@ -13381,42 +13301,46 @@ module C #:nodoc:
13381
13301
  class W0771 < PassiveMessageDetection
13382
13302
  def initialize(context)
13383
13303
  super
13384
- visitor = context[:c_visitor]
13385
- visitor.enter_variable_declaration += method(:add_variable_declaration)
13386
- visitor.enter_function_declaration += method(:add_function_declaration)
13387
- visitor.leave_translation_unit += method(:check)
13304
+ interp = context[:c_interpreter]
13305
+ interp.on_variable_declared += method(:declare_variable)
13306
+ interp.on_function_declared += method(:declare_function)
13307
+ interp.on_translation_unit_ended += method(:check)
13388
13308
  @variable_declarations = Hash.new { |hash, key| hash[key] = [] }
13389
13309
  @function_declarations = Hash.new { |hash, key| hash[key] = [] }
13390
13310
  end
13391
13311
 
13392
13312
  private
13393
- def add_variable_declaration(declaration)
13394
- if declaration.storage_class_specifier &&
13395
- declaration.storage_class_specifier.type == :EXTERN
13396
- @variable_declarations[declaration.identifier.value].push(declaration)
13313
+ def declare_variable(variable_declaration, variable)
13314
+ if variable.named? && variable.declared_as_extern?
13315
+ @variable_declarations[variable.name].push(variable_declaration)
13397
13316
  end
13398
13317
  end
13399
13318
 
13400
- def add_function_declaration(declaration)
13401
- if declaration.storage_class_specifier &&
13402
- declaration.storage_class_specifier.type == :EXTERN
13403
- @function_declarations[declaration.identifier.value].push(declaration)
13319
+ def declare_function(function_declaration, function)
13320
+ if function.named? && function.declared_as_extern?
13321
+ @function_declarations[function.name].push(function_declaration)
13404
13322
  end
13405
13323
  end
13406
13324
 
13407
- def check(node)
13325
+ def check(*)
13408
13326
  @variable_declarations.each_value do |declarations|
13409
- if declarations.size > 1
13410
- declarations.each do |decl|
13411
- W(:W0771, decl.location, decl.identifier.value)
13327
+ decl_locations = declarations.map { |decl|
13328
+ decl.location
13329
+ }.uniq { |location| location.fpath }
13330
+ if decl_locations.size > 1
13331
+ decl_locations.each do |location|
13332
+ W(:W0771, location, declarations.first.identifier.value)
13412
13333
  end
13413
13334
  end
13414
13335
  end
13415
13336
 
13416
13337
  @function_declarations.each_value do |declarations|
13417
- if declarations.size > 1
13418
- declarations.each do |decl|
13419
- W(:W0771, decl.location, decl.identifier.value)
13338
+ decl_locations = declarations.map { |decl|
13339
+ decl.location
13340
+ }.uniq { |location| location.fpath }
13341
+ if decl_locations.size > 1
13342
+ decl_locations.each do |location|
13343
+ W(:W0771, location, declarations.first.identifier.value)
13420
13344
  end
13421
13345
  end
13422
13346
  end
@@ -14022,20 +13946,19 @@ module C #:nodoc:
14022
13946
  class W0790 < PassiveMessageDetection
14023
13947
  def initialize(context)
14024
13948
  super
14025
- visitor = context[:c_visitor]
14026
- visitor.enter_variable_definition += method(:check_variable)
14027
- visitor.enter_ansi_function_definition += method(:check_function)
14028
- visitor.enter_kandr_function_definition += method(:check_function)
14029
- visitor.enter_compound_statement += method(:enter_block)
14030
- visitor.leave_compound_statement += method(:leave_block)
13949
+ interp = context[:c_interpreter]
13950
+ interp.on_variable_defined += method(:check_variable)
13951
+ interp.on_function_started += method(:check_function)
13952
+ interp.on_block_started += method(:enter_block)
13953
+ interp.on_block_ended += method(:leave_block)
14031
13954
  @global_var_names = Set.new
14032
13955
  @global_fun_names = Set.new
14033
13956
  @block_level = 0
14034
13957
  end
14035
13958
 
14036
13959
  private
14037
- def check_variable(variable_definition)
14038
- return unless global?(variable_definition)
13960
+ def check_variable(variable_definition, variable)
13961
+ return unless @block_level == 0 && variable.declared_as_extern?
14039
13962
 
14040
13963
  name = variable_definition.identifier.value
14041
13964
  if @global_var_names.include?(name) || @global_fun_names.include?(name)
@@ -14045,8 +13968,8 @@ module C #:nodoc:
14045
13968
  end
14046
13969
  end
14047
13970
 
14048
- def check_function(function_definition)
14049
- return unless global?(function_definition)
13971
+ def check_function(function_definition, function)
13972
+ return unless @block_level == 0 && function.declared_as_extern?
14050
13973
 
14051
13974
  name = function_definition.identifier.value
14052
13975
  if @global_var_names.include?(name) || @global_fun_names.include?(name)
@@ -14056,25 +13979,13 @@ module C #:nodoc:
14056
13979
  end
14057
13980
  end
14058
13981
 
14059
- def enter_block(node)
13982
+ def enter_block(*)
14060
13983
  @block_level += 1
14061
13984
  end
14062
13985
 
14063
- def leave_block(node)
13986
+ def leave_block(*)
14064
13987
  @block_level -= 1
14065
13988
  end
14066
-
14067
- def global?(definition)
14068
- return false if @block_level > 0
14069
-
14070
- if declaration_specifiers = definition.declaration_specifiers
14071
- if declaration_specifiers.storage_class_specifier &&
14072
- declaration_specifiers.storage_class_specifier.type == :STATIC
14073
- return false
14074
- end
14075
- end
14076
- true
14077
- end
14078
13989
  end
14079
13990
 
14080
13991
  class W0795 < PassiveMessageDetection
@@ -14256,27 +14167,16 @@ module C #:nodoc:
14256
14167
  super
14257
14168
  interp = context[:c_interpreter]
14258
14169
  interp.on_variable_defined += method(:check)
14259
- interp.on_block_started += method(:enter_block)
14260
- interp.on_block_ended += method(:leave_block)
14261
- @block_depth = 0
14262
14170
  end
14263
14171
 
14264
14172
  private
14265
14173
  def check(variable_definition, variable)
14266
- unless variable_definition.storage_class_specifier
14174
+ unless variable.declared_as_extern?
14267
14175
  if variable.type.incomplete?
14268
14176
  W(:W0800, variable_definition.location, variable.name)
14269
14177
  end
14270
14178
  end
14271
14179
  end
14272
-
14273
- def enter_block(compound_statement)
14274
- @block_depth += 1
14275
- end
14276
-
14277
- def leave_block(compound_statement)
14278
- @block_depth -= 1
14279
- end
14280
14180
  end
14281
14181
 
14282
14182
  class W0810 < PassiveMessageDetection
@@ -14373,7 +14273,8 @@ module C #:nodoc:
14373
14273
  def check(type, initializer)
14374
14274
  return unless initializer
14375
14275
 
14376
- if initializers = initializer.initializers
14276
+ case
14277
+ when initializers = initializer.initializers
14377
14278
  case
14378
14279
  when type.array?
14379
14280
  check(type.base_type, initializers.first)
@@ -14382,6 +14283,7 @@ module C #:nodoc:
14382
14283
  check(memb.type, init) if init
14383
14284
  end
14384
14285
  end
14286
+ when initializer.expression.kind_of?(StringLiteralSpecifier)
14385
14287
  else
14386
14288
  W(:W0828, initializer.location) if type.array?
14387
14289
  end
@@ -14548,110 +14450,94 @@ module C #:nodoc:
14548
14450
  visitor.enter_kandr_function_definition += method(:define_function)
14549
14451
  visitor.enter_compound_statement += method(:enter_block)
14550
14452
  visitor.leave_compound_statement += method(:leave_block)
14551
- @block_depth = 0
14453
+ @block_level = 0
14552
14454
  @global_objects = {}
14553
14455
  end
14554
14456
 
14555
14457
  private
14556
14458
  def declare_variable(variable_declaration)
14557
- if @block_depth == 0
14558
- name = variable_declaration.identifier.value
14559
- linkage = linkage_of(variable_declaration)
14560
- prev_linkage = @global_objects[name]
14561
- case
14562
- when linkage && prev_linkage && linkage != prev_linkage
14563
- W(:W1031, variable_declaration.location, name)
14564
- when linkage
14565
- @global_objects[name] = linkage
14566
- end
14459
+ name = variable_declaration.identifier.value
14460
+ linkage = linkage_of(variable_declaration)
14461
+ prev_linkage = @global_objects[name]
14462
+ case
14463
+ when linkage && prev_linkage && linkage != prev_linkage
14464
+ W(:W1031, variable_declaration.location, name)
14465
+ when linkage
14466
+ @global_objects[name] = linkage
14567
14467
  end
14568
14468
  end
14569
14469
 
14570
14470
  def define_variable(variable_definition)
14571
- if @block_depth == 0
14572
- name = variable_definition.identifier.value
14573
- linkage = linkage_of(variable_definition)
14574
- prev_linkage = @global_objects[name]
14575
- case
14576
- when linkage && prev_linkage && linkage != prev_linkage
14577
- W(:W1031, variable_definition.location, name)
14578
- when linkage
14579
- @global_objects[name] = linkage
14580
- end
14471
+ name = variable_definition.identifier.value
14472
+ linkage = linkage_of(variable_definition)
14473
+ prev_linkage = @global_objects[name]
14474
+ case
14475
+ when linkage && prev_linkage && linkage != prev_linkage
14476
+ W(:W1031, variable_definition.location, name)
14477
+ when linkage
14478
+ @global_objects[name] = linkage
14581
14479
  end
14582
14480
  end
14583
14481
 
14584
14482
  def declare_function(function_declaration)
14585
- if @block_depth == 0
14586
- name = function_declaration.identifier.value
14587
- linkage = linkage_of(function_declaration)
14588
- prev_linkage = @global_objects[name]
14589
- case
14590
- when linkage && prev_linkage && linkage != prev_linkage
14591
- W(:W1031, function_declaration.location, name)
14592
- when linkage
14593
- @global_objects[name] = linkage
14594
- end
14483
+ name = function_declaration.identifier.value
14484
+ linkage = linkage_of(function_declaration)
14485
+ prev_linkage = @global_objects[name]
14486
+ case
14487
+ when linkage && prev_linkage && linkage != prev_linkage
14488
+ W(:W1031, function_declaration.location, name)
14489
+ when linkage
14490
+ @global_objects[name] = linkage
14595
14491
  end
14596
14492
  end
14597
14493
 
14598
14494
  def define_function(function_definition)
14599
- if @block_depth == 0
14600
- name = function_definition.identifier.value
14601
- linkage = linkage_of(function_definition)
14602
- prev_linkage = @global_objects[name]
14603
- case
14604
- when linkage && prev_linkage && linkage != prev_linkage
14605
- W(:W1031, function_definition.location, name)
14606
- when linkage
14607
- @global_objects[name] = linkage
14608
- end
14495
+ name = function_definition.identifier.value
14496
+ linkage = linkage_of(function_definition)
14497
+ prev_linkage = @global_objects[name]
14498
+ case
14499
+ when linkage && prev_linkage && linkage != prev_linkage
14500
+ W(:W1031, function_definition.location, name)
14501
+ when linkage
14502
+ @global_objects[name] = linkage
14609
14503
  end
14610
14504
  end
14611
14505
 
14612
- def enter_block(node)
14613
- @block_depth += 1
14506
+ def enter_block(*)
14507
+ @block_level += 1
14614
14508
  end
14615
14509
 
14616
- def leave_block(node)
14617
- @block_depth -= 1
14510
+ def leave_block(*)
14511
+ @block_level -= 1
14618
14512
  end
14619
14513
 
14620
- def linkage_of(node)
14621
- if storage_class_specifier = node.storage_class_specifier
14514
+ def linkage_of(decl_or_def)
14515
+ if storage_class_specifier = decl_or_def.storage_class_specifier
14622
14516
  case storage_class_specifier.type
14623
14517
  when :STATIC
14624
- return :internal
14518
+ :internal
14625
14519
  when :EXTERN
14626
- return :external
14520
+ :external
14521
+ else
14522
+ nil
14627
14523
  end
14524
+ else
14525
+ @block_level == 0 ? :external : nil
14628
14526
  end
14629
- nil
14630
14527
  end
14631
14528
  end
14632
14529
 
14633
14530
  class W1032 < PassiveMessageDetection
14634
14531
  def initialize(context)
14635
14532
  super
14636
- visitor = context[:c_visitor]
14637
- visitor.enter_variable_definition += method(:check)
14533
+ interp = context[:c_interpreter]
14534
+ interp.on_variable_defined += method(:check)
14638
14535
  end
14639
14536
 
14640
14537
  private
14641
- def check(variable_definition)
14642
- if linkage_of(variable_definition) == :internal
14643
- if variable_definition.type.incomplete?
14644
- W(:W1032, variable_definition.location,
14645
- variable_definition.identifier.value)
14646
- end
14647
- end
14648
- end
14649
-
14650
- def linkage_of(node)
14651
- if storage_class_specifier = node.storage_class_specifier
14652
- storage_class_specifier.type == :STATIC ? :internal : :external
14653
- else
14654
- :external
14538
+ def check(variable_definition, variable)
14539
+ if variable.declared_as_static? && variable.type.incomplete?
14540
+ W(:W1032, variable_definition.location, variable.name)
14655
14541
  end
14656
14542
  end
14657
14543
  end
@@ -14663,33 +14549,24 @@ module C #:nodoc:
14663
14549
  visitor.enter_function_declaration += method(:check)
14664
14550
  visitor.enter_compound_statement += method(:enter_block)
14665
14551
  visitor.leave_compound_statement += method(:leave_block)
14666
- @block_depth = 0
14552
+ @block_level = 0
14667
14553
  end
14668
14554
 
14669
14555
  private
14670
- def check(function_declaration)
14671
- return if @block_depth == 0
14672
-
14673
- if linkage_of(function_declaration) == :internal
14674
- W(:W1034, function_declaration.location,
14675
- function_declaration.identifier.value)
14556
+ def check(declaration)
14557
+ if @block_level > 0
14558
+ if scs = declaration.storage_class_specifier and scs.type == :STATIC
14559
+ W(:W1034, declaration.location, declaration.identifier.value)
14560
+ end
14676
14561
  end
14677
14562
  end
14678
14563
 
14679
- def enter_block(node)
14680
- @block_depth += 1
14681
- end
14682
-
14683
- def leave_block(node)
14684
- @block_depth -= 1
14564
+ def enter_block(*)
14565
+ @block_level += 1
14685
14566
  end
14686
14567
 
14687
- def linkage_of(node)
14688
- if storage_class_specifier = node.storage_class_specifier
14689
- storage_class_specifier.type == :STATIC ? :internal : :external
14690
- else
14691
- :external
14692
- end
14568
+ def leave_block(*)
14569
+ @block_level -= 1
14693
14570
  end
14694
14571
  end
14695
14572