adlint 1.8.2 → 1.8.10

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