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
@@ -187,6 +187,69 @@ module C #:nodoc:
187
187
  end
188
188
  end
189
189
 
190
+ class W0711 < PassiveMessageDetection
191
+ def initialize(context)
192
+ super
193
+ visitor = context[:c_visitor]
194
+ visitor.enter_relational_expression += method(:check)
195
+ end
196
+
197
+ private
198
+ def check(expression)
199
+ if !expression.lhs_operand.logical? && expression.rhs_operand.logical?
200
+ W(:W0711, expression.rhs_operand.location)
201
+ end
202
+ end
203
+ end
204
+
205
+ class W0712 < W0711
206
+ private
207
+ def check(expression)
208
+ if expression.lhs_operand.logical? && !expression.rhs_operand.logical?
209
+ W(:W0712, expression.lhs_operand.location)
210
+ end
211
+ end
212
+ end
213
+
214
+ class W0713 < W0711
215
+ private
216
+ def check(expression)
217
+ if expression.lhs_operand.logical? && expression.rhs_operand.logical?
218
+ W(:W0713, expression.location)
219
+ end
220
+ end
221
+ end
222
+
223
+ class W0714 < PassiveMessageDetection
224
+ def initialize(context)
225
+ super
226
+ visitor = context[:c_visitor]
227
+ visitor.enter_and_expression += method(:check)
228
+ end
229
+
230
+ private
231
+ def check(expression)
232
+ if expression.lhs_operand.logical? && expression.rhs_operand.logical?
233
+ W(:W0714, expression.location)
234
+ end
235
+ end
236
+ end
237
+
238
+ class W0715 < PassiveMessageDetection
239
+ def initialize(context)
240
+ super
241
+ visitor = context[:c_visitor]
242
+ visitor.enter_inclusive_or_expression += method(:check)
243
+ end
244
+
245
+ private
246
+ def check(expression)
247
+ if expression.lhs_operand.logical? && expression.rhs_operand.logical?
248
+ W(:W0715, expression.location)
249
+ end
250
+ end
251
+ end
252
+
190
253
  class W0726 < W0698
191
254
  private
192
255
  def check(return_statement)
@@ -145,7 +145,7 @@ module C #:nodoc:
145
145
  return unless @current_function
146
146
 
147
147
  FN_STMT(FunctionIdentifier.new(@current_function.identifier.value,
148
- @current_function.signature),
148
+ @current_function.signature.to_s),
149
149
  @current_function.location, @statement_count)
150
150
 
151
151
  @current_function = nil
@@ -302,14 +302,14 @@ module C #:nodoc:
302
302
  def do_prepare(context) end
303
303
  def do_execute(context) end
304
304
 
305
- def enter_function(function_definition)
305
+ def enter_function(function_definition, function)
306
306
  if @fpath == function_definition.location.fpath
307
307
  @current_function = function_definition
308
308
  @variables = {}
309
309
  end
310
310
  end
311
311
 
312
- def leave_function(function_definition)
312
+ def leave_function(function_definition, function)
313
313
  return unless @current_function
314
314
 
315
315
  useless_count = @variables.each_value.reduce(0) { |count, read_count|
@@ -527,9 +527,11 @@ module C #:nodoc:
527
527
  visitor.leave_ansi_function_definition += method(:leave_function)
528
528
  visitor.enter_kandr_function_definition += method(:enter_function)
529
529
  visitor.leave_kandr_function_definition += method(:leave_function)
530
- visitor.enter_if_statement += method(:count_if_statement)
530
+ visitor.enter_if_else_statement += method(:enter_if_else_statement)
531
+ visitor.leave_if_else_statement += method(:leave_if_else_statement)
531
532
  @current_function = nil
532
- @if_statement_count = 0
533
+ @if_else_statement_chain = 0
534
+ @incomplete_if_else_statement_count = 0
533
535
  end
534
536
 
535
537
  private
@@ -539,7 +541,8 @@ module C #:nodoc:
539
541
  def enter_function(function_definition)
540
542
  if @fpath == function_definition.location.fpath
541
543
  @current_function = function_definition
542
- @if_statement_count = 0
544
+ @if_else_statement_chain = 0
545
+ @incomplete_if_else_statement_count = 0
543
546
  end
544
547
  end
545
548
 
@@ -548,17 +551,26 @@ module C #:nodoc:
548
551
 
549
552
  FN_UELS(FunctionIdentifier.new(@current_function.identifier.value,
550
553
  @current_function.signature.to_s),
551
- @current_function.location, @if_statement_count)
554
+ @current_function.location, @incomplete_if_else_statement_count)
552
555
 
553
556
  @current_function = nil
554
- @if_statement_count = 0
557
+ @if_else_statement_chain = 0
558
+ @incomplete_if_else_statement_count = 0
555
559
  end
556
560
 
557
- def count_if_statement(node)
558
- if @current_function
559
- @if_statement_count += 1
561
+ def enter_if_else_statement(node)
562
+ @if_else_statement_chain += 1
563
+
564
+ if @current_function && @if_else_statement_chain > 0
565
+ if node.else_statement.kind_of?(IfStatement)
566
+ @incomplete_if_else_statement_count += 1
567
+ end
560
568
  end
561
569
  end
570
+
571
+ def leave_if_else_statement(node)
572
+ @if_else_statement_chain -= 1
573
+ end
562
574
  end
563
575
 
564
576
  class FN_NEST < MetricMeasurement
@@ -661,7 +673,7 @@ module C #:nodoc:
661
673
  def do_prepare(context) end
662
674
  def do_execute(context) end
663
675
 
664
- def enter_function(function_definition)
676
+ def enter_function(function_definition, function)
665
677
  if @fpath == function_definition.location.fpath
666
678
  @current_function = function_definition
667
679
 
@@ -676,7 +688,7 @@ module C #:nodoc:
676
688
  end
677
689
  end
678
690
 
679
- def leave_function(function_definition)
691
+ def leave_function(function_definition, function)
680
692
  return unless @current_function
681
693
 
682
694
  FN_PATH(FunctionIdentifier.new(@current_function.identifier.value,
@@ -30,6 +30,7 @@
30
30
  #++
31
31
 
32
32
  require "adlint/util"
33
+ require "adlint/c/syntax"
33
34
  require "adlint/c/value"
34
35
  require "adlint/c/scope"
35
36
  require "adlint/c/seqp"
@@ -92,6 +93,29 @@ module C #:nodoc:
92
93
 
93
94
  attr_reader :declarations_and_definitions
94
95
 
96
+ def storage_class_specifiers
97
+ @declarations_and_definitions.map { |decl_or_def|
98
+ decl_or_def.storage_class_specifier
99
+ }.compact
100
+ end
101
+
102
+ def declared_as_extern?
103
+ storage_class_specifiers.empty? ||
104
+ storage_class_specifiers.any? { |sc_spec| sc_spec.type == :EXTERN }
105
+ end
106
+
107
+ def declared_as_static?
108
+ storage_class_specifiers.any? { |sc_spec| sc_spec.type == :STATIC }
109
+ end
110
+
111
+ def declared_as_auto?
112
+ storage_class_specifiers.any? { |sc_spec| sc_spec.type == :AUTO }
113
+ end
114
+
115
+ def declared_as_register?
116
+ storage_class_specifiers.any? { |sc_spec| sc_spec.type == :REGISTER }
117
+ end
118
+
95
119
  def designated_by_lvalue?
96
120
  subclass_responsibility
97
121
  end
@@ -193,6 +217,30 @@ module C #:nodoc:
193
217
  self_value.exist?
194
218
  end
195
219
 
220
+ def enter_value_versioning_group
221
+ value.enter_versioning_group
222
+ end
223
+
224
+ def leave_value_versioning_group(raise_complement)
225
+ value.leave_versioning_group(raise_complement)
226
+ end
227
+
228
+ def begin_value_versioning
229
+ value.begin_versioning
230
+ end
231
+
232
+ def end_value_versioning
233
+ value.end_versioning
234
+ end
235
+
236
+ def rollback_latest_value_version!
237
+ value.rollback_latest_version!
238
+ end
239
+
240
+ def rollback_all_value_versions!
241
+ value.rollback_all_versions!
242
+ end
243
+
196
244
  private
197
245
  def relate_to_memory(memory)
198
246
  bind_to(memory)
@@ -210,6 +258,23 @@ module C #:nodoc:
210
258
  end
211
259
 
212
260
  attr_accessor :scope
261
+
262
+ def declared_as_extern?
263
+ if @scope.global?
264
+ super
265
+ else
266
+ storage_class_specifiers.all? { |sc_spec| sc_spec.type == :EXTERN }
267
+ end
268
+ end
269
+
270
+ def declared_as_auto?
271
+ if @scope.global?
272
+ super
273
+ else
274
+ storage_class_specifiers.empty? ||
275
+ storage_class_specifiers.any? { |sc_spec| sc_spec.type == :AUTO }
276
+ end
277
+ end
213
278
  end
214
279
 
215
280
  class OuterVariable < ScopedVariable
@@ -220,6 +285,60 @@ module C #:nodoc:
220
285
  @inner_variables = create_inner_variables(type, scope)
221
286
  end
222
287
 
288
+ def enter_value_versioning_group
289
+ super
290
+ if @inner_variables
291
+ @inner_variables.each do |inner|
292
+ inner.enter_value_versioning_group
293
+ end
294
+ end
295
+ end
296
+
297
+ def leave_value_versioning_group(raise_complement)
298
+ super
299
+ if @inner_variables
300
+ @inner_variables.each do |inner|
301
+ inner.leave_value_versioning_group(raise_complement)
302
+ end
303
+ end
304
+ end
305
+
306
+ def begin_value_versioning
307
+ super
308
+ if @inner_variables
309
+ @inner_variables.each do |inner|
310
+ inner.begin_value_versioning
311
+ end
312
+ end
313
+ end
314
+
315
+ def end_value_versioning
316
+ super
317
+ if @inner_variables
318
+ @inner_variables.each do |inner|
319
+ inner.end_value_versioning
320
+ end
321
+ end
322
+ end
323
+
324
+ def rollback_latest_value_version!
325
+ super
326
+ if @inner_variables
327
+ @inner_variables.each do |inner|
328
+ inner.rollback_latest_value_version!
329
+ end
330
+ end
331
+ end
332
+
333
+ def rollback_all_value_versions!
334
+ super
335
+ if @inner_variables
336
+ @inner_variables.each do |inner|
337
+ inner.rollback_all_value_versions!
338
+ end
339
+ end
340
+ end
341
+
223
342
  def inner_variable_at(index)
224
343
  if @type.array?
225
344
  # TODO: If linear searching is too slow, use an index of inner
@@ -345,17 +464,40 @@ module C #:nodoc:
345
464
  include Nameable
346
465
 
347
466
  def initialize(memory, outer_variable, type, component_name)
467
+ @owner = outer_variable
468
+ @component_name = component_name
348
469
  self.name = create_qualified_name(outer_variable, component_name)
349
470
 
350
471
  super(memory, nil, type, outer_variable.scope)
351
-
352
- @owner = outer_variable
353
- @component_name = component_name
354
472
  end
355
473
 
356
474
  attr_reader :owner
357
475
  attr_reader :component_name
358
476
 
477
+ def storage_class_specifiers
478
+ @owner.storage_class_specifiers
479
+ end
480
+
481
+ def declared_as_extern?
482
+ @owner.declared_as_extern?
483
+ end
484
+
485
+ def declared_as_static?
486
+ @owner.declared_as_static?
487
+ end
488
+
489
+ def declared_as_auto?
490
+ @owner.declared_as_auto?
491
+ end
492
+
493
+ def declared_as_register?
494
+ @owner.declared_as_register?
495
+ end
496
+
497
+ def named?
498
+ @owner.named?
499
+ end
500
+
359
501
  def temporary?
360
502
  @owner.temporary?
361
503
  end
@@ -437,7 +579,7 @@ module C #:nodoc:
437
579
  @memory_pool.free(variable.binding.memory)
438
580
  end
439
581
  @scope_stack.pop
440
- rollback_all_variables! if current_scope.global?
582
+ rollback_all_global_variables_value! if current_scope.global?
441
583
  end
442
584
 
443
585
  def declare(declaration)
@@ -453,7 +595,14 @@ module C #:nodoc:
453
595
  end
454
596
 
455
597
  def define(definition, init_value = nil)
456
- init_value ||= default_value_of(definition)
598
+ if storage_class_of(definition) == :static
599
+ # NOTE: Value of the global variable should be arbitrary because
600
+ # execution of its accessors are out of order.
601
+ # So, a value of the initializer should be ignored.
602
+ init_value = definition.type.arbitrary_value
603
+ else
604
+ init_value ||= definition.type.undefined_value
605
+ end
457
606
 
458
607
  if variable = lookup(definition.identifier.value)
459
608
  if variable.scope == current_scope
@@ -486,35 +635,35 @@ module C #:nodoc:
486
635
  nil
487
636
  end
488
637
 
489
- def begin_versioning_group
638
+ def enter_variables_value_versioning_group
490
639
  @named_variables.each do |hash|
491
- hash.each_value { |variable| variable.value.begin_versioning_group }
640
+ hash.each_value { |variable| variable.enter_value_versioning_group }
492
641
  end
493
642
  end
494
643
 
495
- def end_versioning_group(raise_complement_values)
644
+ def leave_variables_value_versioning_group(raise_complement)
496
645
  @named_variables.each do |hash|
497
646
  hash.each_value do |variable|
498
- variable.value.end_versioning_group(raise_complement_values)
647
+ variable.leave_value_versioning_group(raise_complement)
499
648
  end
500
649
  end
501
650
  end
502
651
 
503
- def begin_versioning
652
+ def begin_variables_value_versioning
504
653
  @named_variables.each do |hash|
505
- hash.each_value { |variable| variable.value.begin_versioning }
654
+ hash.each_value { |variable| variable.begin_value_versioning }
506
655
  end
507
656
  end
508
657
 
509
- def end_versioning
658
+ def end_variables_value_versioning
510
659
  @named_variables.each do |hash|
511
- hash.each_value { |variable| variable.value.end_versioning }
660
+ hash.each_value { |variable| variable.end_value_versioning }
512
661
  end
513
662
  end
514
663
 
515
- def rollback_latest_version
664
+ def rollback_latest_variables_value_version!
516
665
  @named_variables.each do |hash|
517
- hash.each_value { |variable| variable.value.rollback! }
666
+ hash.each_value { |variable| variable.rollback_latest_value_version! }
518
667
  end
519
668
  end
520
669
 
@@ -541,14 +690,6 @@ module C #:nodoc:
541
690
  end
542
691
  end
543
692
 
544
- def default_value_of(definition)
545
- if storage_class_of(definition) == :static
546
- definition.type.zero_value
547
- else
548
- definition.type.undefined_value
549
- end
550
- end
551
-
552
693
  def storage_class_of(declaration_or_definition)
553
694
  storage_class_specifier =
554
695
  declaration_or_definition.storage_class_specifier
@@ -573,9 +714,9 @@ module C #:nodoc:
573
714
  @scope_stack.last
574
715
  end
575
716
 
576
- def rollback_all_variables!
717
+ def rollback_all_global_variables_value!
577
718
  @named_variables.first.each_value do |variable|
578
- variable.value.rollback_to_original!
719
+ variable.rollback_all_value_versions!
579
720
  end
580
721
  end
581
722
  end
@@ -745,9 +886,7 @@ module C #:nodoc:
745
886
  end
746
887
 
747
888
  def signature
748
- "#{type.return_type.brief_image} #{name}(" +
749
- type.parameter_types.map { |ptype| ptype.brief_image }.join(",") +
750
- (type.have_va_list? ? ",...)" : ")")
889
+ FunctionSignature.new(name, type)
751
890
  end
752
891
  end
753
892
 
@@ -798,9 +937,7 @@ module C #:nodoc:
798
937
  end
799
938
 
800
939
  def signature
801
- "#{type.return_type.brief_image} __adlint__anonymous_func(" +
802
- type.parameter_types.map { |ptype| ptype.brief_image }.join(",") +
803
- (type.have_va_list? ? ",...)" : ")")
940
+ FunctionSignature.new("__adlint__anonymous_func", type)
804
941
  end
805
942
  end
806
943
 
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.4.7
3
+ # This file is automatically generated by Racc 1.4.8
4
4
  # from Racc grammer file "".
5
5
  #
6
6
 
@@ -235,7 +235,7 @@ clist = [
235
235
  '15,16,39,38,18,19,20,21,24,25,22,23,36,37,17,26,27,28,33,34,35,,,,,',
236
236
  ',,,,,,,,32,29,,400,,12,13,14,15,16,39,38,18,19,20,21,24,25,22,23,36',
237
237
  '37,17,26,27,28,33,34,35,,,,,,,,,,,,,,32' ]
238
- racc_action_table = arr = Array.new(4442, nil)
238
+ racc_action_table = arr = ::Array.new(4442, nil)
239
239
  idx = 0
240
240
  clist.each do |str|
241
241
  str.split(',', -1).each do |i|
@@ -417,7 +417,7 @@ clist = [
417
417
  '343,343,,,,,,,,,,,,,,343,346,,343,,346,346,346,346,346,346,346,346,346',
418
418
  '346,346,346,346,346,346,346,346,346,346,346,346,346,346,346,,,,,,,,',
419
419
  ',,,,,346' ]
420
- racc_action_check = arr = Array.new(4442, nil)
420
+ racc_action_check = arr = ::Array.new(4442, nil)
421
421
  idx = 0
422
422
  clist.each do |str|
423
423
  str.split(',', -1).each do |i|
@@ -44,6 +44,15 @@ require "adlint/c/util"
44
44
  module AdLint #:nodoc:
45
45
  module C #:nodoc:
46
46
 
47
+ class Prepare1Phase < Phase
48
+ private
49
+ def do_execute(context)
50
+ monitored_region("pr3") do
51
+ context[:c_visitor] = SyntaxTreeMulticastVisitor.new
52
+ end
53
+ end
54
+ end
55
+
47
56
  class ParsePhase < Phase
48
57
  private
49
58
  def do_execute(context)
@@ -70,12 +79,11 @@ module C #:nodoc:
70
79
  end
71
80
  end
72
81
 
73
- class PreparePhase < Phase
82
+ class Prepare2Phase < Phase
74
83
  private
75
84
  def do_execute(context)
76
- monitored_region("pr2") do
85
+ monitored_region("pr4") do
77
86
  context[:c_interpreter] = Interpreter.new(context[:c_type_table])
78
- context[:c_visitor] = SyntaxTreeMulticastVisitor.new
79
87
 
80
88
  context[:c_commands] = setup_code_extractions(context) +
81
89
  setup_metric_measurements(context) +
@@ -566,6 +574,8 @@ module C #:nodoc:
566
574
  W0600.new(context),
567
575
  W0605.new(context),
568
576
  W0606.new(context),
577
+ W0607.new(context),
578
+ W0608.new(context),
569
579
  W0609.new(context),
570
580
  W0610.new(context),
571
581
  W0611.new(context),
@@ -575,6 +585,7 @@ module C #:nodoc:
575
585
  W0622.new(context),
576
586
  W0623.new(context),
577
587
  W0624.new(context),
588
+ W0625.new(context),
578
589
  W0626.new(context),
579
590
  W0627.new(context),
580
591
  W0629.new(context),
@@ -584,6 +595,7 @@ module C #:nodoc:
584
595
  W0638.new(context),
585
596
  W0639.new(context),
586
597
  W0640.new(context),
598
+ W0642.new(context),
587
599
  W0653.new(context),
588
600
  W0654.new(context),
589
601
  W0655.new(context),
@@ -624,6 +636,11 @@ module C #:nodoc:
624
636
  W0704.new(context),
625
637
  W0705.new(context),
626
638
  W0708.new(context),
639
+ W0711.new(context),
640
+ W0712.new(context),
641
+ W0713.new(context),
642
+ W0714.new(context),
643
+ W0715.new(context),
627
644
  W0720.new(context),
628
645
  W0721.new(context),
629
646
  W0722.new(context),