adlint 1.6.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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