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
@@ -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),