adlint 1.6.0 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/ChangeLog +389 -37
  2. data/INSTALL +3 -0
  3. data/MANIFEST +7 -0
  4. data/NEWS +50 -10
  5. data/etc/conf.d/i686-mingw/cinit-gcc_4.6.1.erb +1 -1
  6. data/etc/mesg.d/en_US/messages.yml +7 -7
  7. data/etc/mesg.d/ja_JP/messages.yml +4 -4
  8. data/lib/adlint/c/branch.rb +4 -4
  9. data/lib/adlint/c/code.rb +11 -13
  10. data/lib/adlint/c/enum.rb +0 -2
  11. data/lib/adlint/c/environ.rb +13 -7
  12. data/lib/adlint/c/expr.rb +5 -1
  13. data/lib/adlint/c/interp.rb +10 -6
  14. data/lib/adlint/c/mediator.rb +1 -0
  15. data/lib/adlint/c/message.rb +294 -111
  16. data/lib/adlint/c/message_shima.rb +63 -0
  17. data/lib/adlint/c/metric.rb +25 -13
  18. data/lib/adlint/c/object.rb +168 -31
  19. data/lib/adlint/c/parser.rb +3 -3
  20. data/lib/adlint/c/phase.rb +20 -3
  21. data/lib/adlint/c/syntax.rb +175 -17
  22. data/lib/adlint/c/value.rb +199 -126
  23. data/lib/adlint/cpp/asm.rb +4 -4
  24. data/lib/adlint/cpp/constexpr.rb +1 -1
  25. data/lib/adlint/cpp/eval.rb +6 -4
  26. data/lib/adlint/cpp/message.rb +100 -7
  27. data/lib/adlint/cpp/phase.rb +12 -1
  28. data/lib/adlint/cpp/source.rb +2 -2
  29. data/lib/adlint/cpp/subst.rb +2 -4
  30. data/lib/adlint/lang.rb +5 -3
  31. data/lib/adlint/ld/metric.rb +1 -1
  32. data/lib/adlint/version.rb +2 -2
  33. data/share/demo/Makefile +5 -0
  34. data/share/demo/bad_include/bad_include.c +13 -0
  35. data/share/demo/bad_include/test'1'.h +0 -0
  36. data/share/demo/bad_include/test'2'.h +0 -0
  37. data/share/demo/incomplete_ifelse/incomplete_ifelse.c +29 -0
  38. data/share/demo/inline_asm/inline_asm.c +25 -0
  39. data/share/demo/invalid_call/invalid_call.c +12 -4
  40. data/share/demo/logical_expr/logical_expr.c +73 -0
  41. data/share/demo/register_vars/register_vars.c +12 -0
  42. data/share/demo/typedef_each_src/typedef_each_src.c +9 -0
  43. data/share/demo/wrap_around/wrap_around.c +17 -0
  44. data/share/doc/developers_guide_ja.html +3 -3
  45. data/share/doc/developers_guide_ja.texi +1 -1
  46. data/share/doc/users_guide_en.html +137 -102
  47. data/share/doc/users_guide_en.texi +121 -86
  48. data/share/doc/users_guide_ja.html +118 -91
  49. data/share/doc/users_guide_ja.texi +103 -76
  50. metadata +10 -3
@@ -557,7 +557,7 @@ module C #:nodoc:
557
557
  end
558
558
 
559
559
  private
560
- def start_function(function_definition)
560
+ def start_function(function_definition, function)
561
561
  @parameters = {}
562
562
  end
563
563
 
@@ -579,7 +579,7 @@ module C #:nodoc:
579
579
  end
580
580
  end
581
581
 
582
- def check_unused_parameter(function_definition)
582
+ def check_unused_parameter(function_definition, function)
583
583
  return unless @parameters
584
584
 
585
585
  @parameters.each do |name, param|
@@ -601,7 +601,7 @@ module C #:nodoc:
601
601
  end
602
602
 
603
603
  private
604
- def collect_labels(function_definition)
604
+ def collect_labels(function_definition, function)
605
605
  collector = LabelCollector.new
606
606
  function_definition.function_body.accept(collector)
607
607
  @labels = collector.labels
@@ -619,7 +619,7 @@ module C #:nodoc:
619
619
  end
620
620
  end
621
621
 
622
- def check_unused_label(function_definition)
622
+ def check_unused_label(function_definition, function)
623
623
  return unless @labels
624
624
 
625
625
  @labels.each do |name, label|
@@ -1943,12 +1943,12 @@ module C #:nodoc:
1943
1943
  end
1944
1944
 
1945
1945
  private
1946
- def start_function(function_definition)
1946
+ def start_function(function_definition, function)
1947
1947
  @parameters = Set.new
1948
1948
  @pointer_relationship = {}
1949
1949
  end
1950
1950
 
1951
- def end_function(function_definition)
1951
+ def end_function(function_definition, function)
1952
1952
  @parameters = nil
1953
1953
  @pointer_relationship = nil
1954
1954
  end
@@ -1999,11 +1999,11 @@ module C #:nodoc:
1999
1999
  end
2000
2000
 
2001
2001
  private
2002
- def start_function(function_definition)
2002
+ def start_function(function_definition, function)
2003
2003
  @local_variables = Set.new
2004
2004
  end
2005
2005
 
2006
- def end_function(function_definition)
2006
+ def end_function(function_definition, function)
2007
2007
  @local_variables = nil
2008
2008
  end
2009
2009
 
@@ -2042,7 +2042,7 @@ module C #:nodoc:
2042
2042
  end
2043
2043
 
2044
2044
  private
2045
- def start_function(function_definition)
2045
+ def start_function(function_definition, function)
2046
2046
  @parameters = {}
2047
2047
  end
2048
2048
 
@@ -2063,7 +2063,7 @@ module C #:nodoc:
2063
2063
  end
2064
2064
  end
2065
2065
 
2066
- def check_constant_parameters(function_definition)
2066
+ def check_constant_parameters(function_definition, function)
2067
2067
  return unless @parameters
2068
2068
 
2069
2069
  @parameters.each do |name, (written, variable, location)|
@@ -2092,7 +2092,7 @@ module C #:nodoc:
2092
2092
  end
2093
2093
 
2094
2094
  private
2095
- def start_function(function_definition)
2095
+ def start_function(function_definition, function)
2096
2096
  @variable_relationship = {}
2097
2097
  @parameters = {}
2098
2098
  end
@@ -2131,7 +2131,7 @@ module C #:nodoc:
2131
2131
  end
2132
2132
  end
2133
2133
 
2134
- def check_constant_parameters(function_definition)
2134
+ def check_constant_parameters(function_definition, function)
2135
2135
  return unless @parameters
2136
2136
 
2137
2137
  @parameters.each do |pointer, (location, written)|
@@ -4151,11 +4151,11 @@ module C #:nodoc:
4151
4151
  end
4152
4152
 
4153
4153
  private
4154
- def start_function(function_definition)
4155
- @current_function = function_definition
4154
+ def start_function(function_definition, function)
4155
+ @current_function = function
4156
4156
  end
4157
4157
 
4158
- def end_function(function_definition)
4158
+ def end_function(function_definition, function)
4159
4159
  @current_function = nil
4160
4160
  end
4161
4161
 
@@ -4166,8 +4166,7 @@ module C #:nodoc:
4166
4166
  return unless result_variable
4167
4167
  if from_type.same_as?(result_variable.type) &&
4168
4168
  to_type.same_as?(@current_function.type.return_type)
4169
- W(message_id,
4170
- return_statement.location, @current_function.identifier.value)
4169
+ W(message_id, return_statement.location, @current_function.name)
4171
4170
  end
4172
4171
  end
4173
4172
 
@@ -7043,7 +7042,7 @@ module C #:nodoc:
7043
7042
  next unless !base_type.function? && base_type.const?
7044
7043
 
7045
7044
  if pointee = @interp.pointee_of(arg) and pointee.variable?
7046
- if pointee.value.must_be_undefined?
7045
+ if !pointee.temporary? && pointee.value.must_be_undefined?
7047
7046
  W(:W0461,
7048
7047
  function_call_expression.argument_expressions[index].location)
7049
7048
  end
@@ -7070,7 +7069,7 @@ module C #:nodoc:
7070
7069
 
7071
7070
  if pointee = @interp.pointee_of(arg) and pointee.variable?
7072
7071
  next if pointee.value.must_be_undefined?
7073
- if pointee.value.may_be_undefined?
7072
+ if !pointee.temporary? && pointee.value.may_be_undefined?
7074
7073
  W(:W0462,
7075
7074
  function_call_expression.argument_expressions[index].location)
7076
7075
  end
@@ -9735,17 +9734,11 @@ module C #:nodoc:
9735
9734
  end
9736
9735
 
9737
9736
  private
9738
- def enter_function(function_definition)
9739
- if declarator = function_definition.declarator
9740
- if identifier = declarator.identifier
9741
- @functions.push(@interp.function_named(identifier.value))
9742
- return
9743
- end
9744
- end
9745
- @functions.push(nil)
9737
+ def enter_function(function_definition, function)
9738
+ @functions.push(function)
9746
9739
  end
9747
9740
 
9748
- def leave_function(function_definition)
9741
+ def leave_function(function_definition, function)
9749
9742
  @functions.pop
9750
9743
  end
9751
9744
 
@@ -10233,7 +10226,7 @@ module C #:nodoc:
10233
10226
  end
10234
10227
  end
10235
10228
 
10236
- def clear_rvalues(function_definition)
10229
+ def clear_rvalues(function_definition, function)
10237
10230
  @rvalues = {}
10238
10231
  end
10239
10232
 
@@ -10295,7 +10288,7 @@ module C #:nodoc:
10295
10288
  end
10296
10289
  end
10297
10290
 
10298
- def clear_rvalues(function_definition)
10291
+ def clear_rvalues(function_definition, function)
10299
10292
  @rvalues = {}
10300
10293
  end
10301
10294
 
@@ -10341,12 +10334,12 @@ module C #:nodoc:
10341
10334
  end
10342
10335
 
10343
10336
  private
10344
- def start_function(function_definition)
10337
+ def start_function(function_definition, function)
10345
10338
  @parameters = Set.new
10346
10339
  @pointer_relationship = {}
10347
10340
  end
10348
10341
 
10349
- def end_function(function_definition)
10342
+ def end_function(function_definition, function)
10350
10343
  @parameters = nil
10351
10344
  @pointer_relationship = nil
10352
10345
  end
@@ -10396,17 +10389,34 @@ module C #:nodoc:
10396
10389
  private
10397
10390
  def check(function_call_expression, function, arg_variables,
10398
10391
  result_variable)
10392
+ return unless function.named?
10399
10393
  return if prototype_declaration_of(function)
10400
10394
 
10401
10395
  arg_types = arg_variables.map { |var| var.type.unqualify }
10402
10396
 
10403
- if call_history = @function_calls[function]
10404
- if call_history.any? { |prev_arg_types| prev_arg_types != arg_types }
10397
+ @function_calls[function.name].each do |prev_arg_types|
10398
+ if prev_arg_types.size == arg_types.size
10399
+ conformed = prev_arg_types.zip(arg_types).all? { |prev, last|
10400
+ case
10401
+ when prev.array? && last.array?,
10402
+ prev.array? && last.pointer?,
10403
+ prev.pointer? && last.array?
10404
+ prev.base_type == last.base_type
10405
+ else
10406
+ prev == last
10407
+ end
10408
+ }
10409
+ else
10410
+ conformed = false
10411
+ end
10412
+
10413
+ unless conformed
10405
10414
  W(:W0581, function_call_expression.location)
10415
+ break
10406
10416
  end
10407
10417
  end
10408
10418
 
10409
- @function_calls[function].push(arg_types)
10419
+ @function_calls[function.name].push(arg_types)
10410
10420
  end
10411
10421
 
10412
10422
  def prototype_declaration_of(function)
@@ -10427,17 +10437,30 @@ module C #:nodoc:
10427
10437
 
10428
10438
  private
10429
10439
  def check(function_declaration, function)
10440
+ return unless function.named?
10430
10441
  return if function.type.have_va_list?
10431
10442
 
10432
- if function.named?
10433
- if call_history = @function_calls[function.name]
10434
- call_history.each do |expr, arg_types|
10435
- param_types = function.type.parameter_types.map { |type|
10436
- type.unqualify
10437
- }
10438
- W(:W0582, expr.location) if param_types != arg_types
10439
- end
10443
+ param_types = function.type.parameter_types.map { |type|
10444
+ type.void? ? nil : type.unqualify
10445
+ }.compact
10446
+
10447
+ @function_calls[function.name].each do |expr, arg_types|
10448
+ if arg_types.size == param_types.size
10449
+ conformed = arg_types.zip(param_types).all? { |atype, ptype|
10450
+ case
10451
+ when atype.array? && ptype.array?,
10452
+ atype.array? && ptype.pointer?,
10453
+ atype.pointer? && ptype.array?
10454
+ atype.base_type == ptype.base_type
10455
+ else
10456
+ atype == ptype
10457
+ end
10458
+ }
10459
+ else
10460
+ conformed = false
10440
10461
  end
10462
+
10463
+ W(:W0582, expr.location) unless conformed
10441
10464
  end
10442
10465
  end
10443
10466
 
@@ -10459,16 +10482,31 @@ module C #:nodoc:
10459
10482
  end
10460
10483
 
10461
10484
  private
10462
- def check(function_definition)
10463
- return if function_definition.type.have_va_list?
10485
+ def check(function_definition, function)
10486
+ return unless function.named?
10487
+ return if function.type.have_va_list?
10464
10488
 
10465
- if call_history = @function_calls[function_definition.identifier.value]
10466
- call_history.each do |expr, arg_types|
10467
- param_types = function_definition.type.parameter_types.map { |type|
10468
- type.unqualify
10489
+ param_types = function.type.parameter_types.map { |type|
10490
+ type.void? ? nil : type.unqualify
10491
+ }.compact
10492
+
10493
+ @function_calls[function.name].each do |expr, arg_types|
10494
+ if arg_types.size == param_types.size
10495
+ conformed = arg_types.zip(param_types).all? { |atype, ptype|
10496
+ case
10497
+ when atype.array? && ptype.array?,
10498
+ atype.array? && ptype.pointer?,
10499
+ atype.pointer? && ptype.array?
10500
+ atype.base_type == ptype.base_type
10501
+ else
10502
+ atype == ptype
10503
+ end
10469
10504
  }
10470
- W(:W0583, expr.location) if param_types != arg_types
10505
+ else
10506
+ conformed = false
10471
10507
  end
10508
+
10509
+ W(:W0583, expr.location) unless conformed
10472
10510
  end
10473
10511
  end
10474
10512
 
@@ -10489,12 +10527,27 @@ module C #:nodoc:
10489
10527
 
10490
10528
  private
10491
10529
  def check(expression, function, arg_variables, result_variable)
10492
- if kandr_style_definition_of(function)
10493
- param_types = function.type.parameter_types
10494
- arg_types = arg_variables.map { |var| var.type }
10530
+ return unless function.named?
10531
+ return unless kandr_style_definition_of(function)
10532
+ return if function.type.have_va_list?
10533
+
10534
+ arg_types = arg_variables.map { |var| var.type.unqualify }
10535
+ param_types = function.type.parameter_types.map { |type|
10536
+ type.void? ? nil : type.unqualify
10537
+ }.compact
10495
10538
 
10539
+ if arg_types.size == param_types.size
10496
10540
  arg_types.zip(param_types).each_with_index do |(atype, ptype), index|
10497
- if atype && ptype && !atype.same_as?(ptype)
10541
+ conformed = case
10542
+ when atype.array? && ptype.array?,
10543
+ atype.array? && ptype.pointer?,
10544
+ atype.pointer? && ptype.array?
10545
+ atype.base_type == ptype.base_type
10546
+ else
10547
+ atype == ptype
10548
+ end
10549
+
10550
+ unless conformed
10498
10551
  W(:W0584,
10499
10552
  expression.argument_expressions[index].location, index + 1)
10500
10553
  end
@@ -10790,6 +10843,62 @@ module C #:nodoc:
10790
10843
  end
10791
10844
  end
10792
10845
 
10846
+ class W0607 < PassiveMessageDetection
10847
+ def initialize(context)
10848
+ super
10849
+ interp = context[:c_interpreter]
10850
+ interp.on_explicit_conv_performed += method(:check)
10851
+ end
10852
+
10853
+ private
10854
+ def check(expression, original_variable, result_variable)
10855
+ orig_type = original_variable.type
10856
+ conv_type = result_variable.type
10857
+
10858
+ unless orig_type.scalar? && orig_type.integer? &&
10859
+ conv_type.scalar? && conv_type.integer? && conv_type.unsigned?
10860
+ return
10861
+ end
10862
+
10863
+ orig_value = original_variable.value
10864
+ return unless orig_value.scalar?
10865
+
10866
+ lower_test = orig_value < ScalarValue.of(0)
10867
+
10868
+ if lower_test.must_be_true?
10869
+ W(:W0607, expression.location)
10870
+ end
10871
+ end
10872
+ end
10873
+
10874
+ class W0608 < PassiveMessageDetection
10875
+ def initialize(context)
10876
+ super
10877
+ interp = context[:c_interpreter]
10878
+ interp.on_explicit_conv_performed += method(:check)
10879
+ end
10880
+
10881
+ private
10882
+ def check(expression, original_variable, result_variable)
10883
+ orig_type = original_variable.type
10884
+ conv_type = result_variable.type
10885
+
10886
+ unless orig_type.scalar? && orig_type.integer? &&
10887
+ conv_type.scalar? && conv_type.integer? && conv_type.unsigned?
10888
+ return
10889
+ end
10890
+
10891
+ orig_value = original_variable.value
10892
+ return unless orig_value.scalar?
10893
+
10894
+ lower_test = orig_value < ScalarValue.of(0)
10895
+
10896
+ if !lower_test.must_be_true? && lower_test.may_be_true?
10897
+ W(:W0608, expression.location)
10898
+ end
10899
+ end
10900
+ end
10901
+
10793
10902
  class W0609 < PassiveMessageDetection
10794
10903
  def initialize(context)
10795
10904
  super
@@ -11086,6 +11195,54 @@ module C #:nodoc:
11086
11195
  end
11087
11196
  end
11088
11197
 
11198
+ class W0625 < PassiveMessageDetection
11199
+ # NOTE: W0625 may be duplicative when the same typedef is used twice or
11200
+ # more.
11201
+ ensure_uniqueness_of :W0625
11202
+
11203
+ include SyntaxNodeCollector
11204
+
11205
+ def initialize(context)
11206
+ super
11207
+ @fpath = context[:sources].first.fpath
11208
+ interp = context[:c_interpreter]
11209
+ interp.on_typedef_declared += method(:declare_typedef)
11210
+ interp.on_variable_defined += method(:check)
11211
+ interp.on_variable_declared += method(:check)
11212
+ interp.on_function_declared += method(:check)
11213
+ interp.on_function_started += method(:check)
11214
+ @typedef_types = {}
11215
+ end
11216
+
11217
+ private
11218
+ def declare_typedef(typedef_declaration)
11219
+ typedef_name = typedef_declaration.identifier.value
11220
+
11221
+ if @fpath == typedef_declaration.location.fpath
11222
+ @typedef_types[typedef_name] = typedef_declaration
11223
+ else
11224
+ @typedef_types.delete(typedef_name)
11225
+ end
11226
+ end
11227
+
11228
+ def check(decl_or_def, object, *)
11229
+ return unless object.declared_as_extern?
11230
+
11231
+ if declaration_specifiers = decl_or_def.declaration_specifiers
11232
+ find_bad_typedef_decls(declaration_specifiers).each do |decl|
11233
+ W(:W0625, decl.location, decl.identifier.value)
11234
+ break
11235
+ end
11236
+ end
11237
+ end
11238
+
11239
+ def find_bad_typedef_decls(node)
11240
+ collect_typedef_type_specifiers(node).map { |type_spec|
11241
+ @typedef_types[type_spec.identifier.value]
11242
+ }.compact
11243
+ end
11244
+ end
11245
+
11089
11246
  class W0626 < PassiveMessageDetection
11090
11247
  def initialize(context)
11091
11248
  super
@@ -11167,7 +11324,7 @@ module C #:nodoc:
11167
11324
  super
11168
11325
  interp = context[:c_interpreter]
11169
11326
  interp.on_function_started += method(:define_function)
11170
- interp.on_function_call_expr_evaled += method(:call_function)
11327
+ interp.on_function_referred += method(:refer_function)
11171
11328
  interp.on_translation_unit_ended += method(:check)
11172
11329
  @static_functions = {}
11173
11330
  end
@@ -11181,18 +11338,14 @@ module C #:nodoc:
11181
11338
  end
11182
11339
  end
11183
11340
 
11184
- def define_function(function_definition)
11185
- if storage_class_specifier = function_definition.storage_class_specifier
11186
- if storage_class_specifier.type == :STATIC
11187
- name = function_definition.identifier.value
11188
- @static_functions[name] ||= [0, function_definition.location]
11189
- @static_functions[name][1] ||= function_definition.location
11190
- end
11341
+ def define_function(function_definition, function)
11342
+ if function.declared_as_static?
11343
+ @static_functions[function.name] ||= [0, function_definition.location]
11344
+ @static_functions[function.name][1] ||= function_definition.location
11191
11345
  end
11192
11346
  end
11193
11347
 
11194
- def call_function(function_call_expression,
11195
- function, arg_variables, result_variable)
11348
+ def refer_function(expression, function)
11196
11349
  return unless function.named?
11197
11350
 
11198
11351
  if record = @static_functions[function.name]
@@ -11473,6 +11626,28 @@ module C #:nodoc:
11473
11626
  end
11474
11627
  end
11475
11628
 
11629
+ class W0642 < PassiveMessageDetection
11630
+ def initialize(context)
11631
+ super
11632
+ interp = context[:c_interpreter]
11633
+ interp.on_address_expr_evaled += method(:check_address_expression)
11634
+ interp.on_implicit_conv_performed += method(:check_conversion)
11635
+ end
11636
+
11637
+ private
11638
+ def check_address_expression(expression, object, pointer_variable)
11639
+ if object.declared_as_register?
11640
+ W(:W0642, expression.location)
11641
+ end
11642
+ end
11643
+
11644
+ def check_conversion(expression, original_variable, result_variable)
11645
+ if original_variable.declared_as_register?
11646
+ W(:W0642, expression.location)
11647
+ end
11648
+ end
11649
+ end
11650
+
11476
11651
  class W0653 < PassiveMessageDetection
11477
11652
  def initialize(context)
11478
11653
  super
@@ -12149,7 +12324,7 @@ module C #:nodoc:
12149
12324
  @tdefs[0..-2] + @enums[0..-2]).reduce(Set.new) { |r, s| r + s }
12150
12325
  end
12151
12326
 
12152
- def define_function(function_definition)
12327
+ def define_function(function_definition, function)
12153
12328
  identifier = function_definition.identifier.value
12154
12329
  if wider_identifiers_of_function_definition.include?(identifier)
12155
12330
  W(:W0704, function_definition.location, identifier)
@@ -12555,11 +12730,11 @@ module C #:nodoc:
12555
12730
  end
12556
12731
 
12557
12732
  private
12558
- def start_function(function_definition)
12559
- @current_function = function_definition
12733
+ def start_function(function_definition, function)
12734
+ @current_function = function
12560
12735
  end
12561
12736
 
12562
- def end_function(function_definition)
12737
+ def end_function(function_definition, function)
12563
12738
  @current_function = nil
12564
12739
  end
12565
12740
 
@@ -12645,11 +12820,11 @@ module C #:nodoc:
12645
12820
  end
12646
12821
  end
12647
12822
 
12648
- def enter_function(function_definition)
12649
- @functions.push(function_definition)
12823
+ def enter_function(function_definition, function)
12824
+ @functions.push(function)
12650
12825
  end
12651
12826
 
12652
- def leave_function(function_definition)
12827
+ def leave_function(function_definition, function)
12653
12828
  @functions.pop
12654
12829
  end
12655
12830
 
@@ -13306,7 +13481,7 @@ module C #:nodoc:
13306
13481
  end
13307
13482
  end
13308
13483
 
13309
- def clear_rvalues(function_definition)
13484
+ def clear_rvalues(function_definition, function)
13310
13485
  @rvalues = {}
13311
13486
  end
13312
13487
 
@@ -14381,12 +14556,13 @@ module C #:nodoc:
14381
14556
  def declare_variable(variable_declaration)
14382
14557
  if @block_depth == 0
14383
14558
  name = variable_declaration.identifier.value
14384
- if prev_linkage = @global_objects[name]
14385
- unless prev_linkage == linkage_of(variable_declaration)
14386
- W(:W1031, variable_declaration.location, name)
14387
- end
14388
- else
14389
- @global_objects[name] = linkage_of(variable_declaration)
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
14390
14566
  end
14391
14567
  end
14392
14568
  end
@@ -14394,12 +14570,13 @@ module C #:nodoc:
14394
14570
  def define_variable(variable_definition)
14395
14571
  if @block_depth == 0
14396
14572
  name = variable_definition.identifier.value
14397
- if prev_linkage = @global_objects[name]
14398
- unless prev_linkage == linkage_of(variable_definition)
14399
- W(:W1031, variable_definition.location, name)
14400
- end
14401
- else
14402
- @global_objects[name] = linkage_of(variable_definition)
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
14403
14580
  end
14404
14581
  end
14405
14582
  end
@@ -14407,12 +14584,13 @@ module C #:nodoc:
14407
14584
  def declare_function(function_declaration)
14408
14585
  if @block_depth == 0
14409
14586
  name = function_declaration.identifier.value
14410
- if prev_linkage = @global_objects[name]
14411
- unless prev_linkage == linkage_of(function_declaration)
14412
- W(:W1031, function_declaration.location, name)
14413
- end
14414
- else
14415
- @global_objects[name] = linkage_of(function_declaration)
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
14416
14594
  end
14417
14595
  end
14418
14596
  end
@@ -14420,12 +14598,13 @@ module C #:nodoc:
14420
14598
  def define_function(function_definition)
14421
14599
  if @block_depth == 0
14422
14600
  name = function_definition.identifier.value
14423
- if prev_linkage = @global_objects[name]
14424
- unless prev_linkage == linkage_of(function_definition)
14425
- W(:W1031, function_definition.location, name)
14426
- end
14427
- else
14428
- @global_objects[name] = linkage_of(function_definition)
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
14429
14608
  end
14430
14609
  end
14431
14610
  end
@@ -14440,10 +14619,14 @@ module C #:nodoc:
14440
14619
 
14441
14620
  def linkage_of(node)
14442
14621
  if storage_class_specifier = node.storage_class_specifier
14443
- storage_class_specifier.type == :STATIC ? :internal : :external
14444
- else
14445
- :external
14622
+ case storage_class_specifier.type
14623
+ when :STATIC
14624
+ return :internal
14625
+ when :EXTERN
14626
+ return :external
14627
+ end
14446
14628
  end
14629
+ nil
14447
14630
  end
14448
14631
  end
14449
14632
 
@@ -14691,11 +14874,11 @@ module C #:nodoc:
14691
14874
  end
14692
14875
 
14693
14876
  private
14694
- def start_function(function_definition)
14695
- @current_function = function_definition
14877
+ def start_function(function_definition, function)
14878
+ @current_function = function
14696
14879
  end
14697
14880
 
14698
- def end_function(function_definition)
14881
+ def end_function(function_definition, function)
14699
14882
  @current_function = nil
14700
14883
  end
14701
14884
 
@@ -14770,11 +14953,11 @@ module C #:nodoc:
14770
14953
  end
14771
14954
 
14772
14955
  private
14773
- def start_function(function_definition)
14774
- @current_function = function_definition
14956
+ def start_function(function_definition, function)
14957
+ @current_function = function
14775
14958
  end
14776
14959
 
14777
- def end_function(function_definition)
14960
+ def end_function(function_definition, function)
14778
14961
  @current_function = nil
14779
14962
  end
14780
14963
 
@@ -14826,11 +15009,11 @@ module C #:nodoc:
14826
15009
  end
14827
15010
 
14828
15011
  private
14829
- def start_function(function_definition)
14830
- @current_function = function_definition
15012
+ def start_function(function_definition, function)
15013
+ @current_function = function
14831
15014
  end
14832
15015
 
14833
- def end_function(function_definition)
15016
+ def end_function(function_definition, function)
14834
15017
  @current_function = nil
14835
15018
  end
14836
15019
 
@@ -14897,11 +15080,11 @@ module C #:nodoc:
14897
15080
  end
14898
15081
 
14899
15082
  private
14900
- def start_function(function_definition)
14901
- @current_function = function_definition
15083
+ def start_function(function_definition, function)
15084
+ @current_function = function
14902
15085
  end
14903
15086
 
14904
- def end_function(function_definition)
15087
+ def end_function(function_definition, function)
14905
15088
  @current_function = nil
14906
15089
  end
14907
15090