adlint 1.16.0 → 1.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/ChangeLog +471 -0
  2. data/MANIFEST +35 -8
  3. data/NEWS +50 -4
  4. data/bin/adlint +7 -7
  5. data/bin/adlint_chk +7 -7
  6. data/bin/adlint_cma +7 -7
  7. data/bin/adlint_sma +7 -7
  8. data/bin/adlintize +5 -5
  9. data/etc/mesg.d/en_US/messages.yml +3 -3
  10. data/etc/mesg.d/ja_JP/messages.yml +3 -3
  11. data/features/message_detection/E0013.feature +34 -0
  12. data/features/message_detection/W0007.feature +2 -0
  13. data/features/message_detection/W0583.feature +1 -2
  14. data/features/message_detection/W0641.feature +132 -0
  15. data/features/message_detection/W0643.feature +1 -1
  16. data/features/message_detection/W0644.feature +529 -0
  17. data/features/message_detection/W0645.feature +1 -1
  18. data/features/message_detection/W0649.feature +277 -0
  19. data/features/message_detection/W0650.feature +208 -0
  20. data/features/message_detection/W0697.feature +6 -0
  21. data/features/message_detection/W0705.feature +350 -0
  22. data/features/message_detection/W0707.feature +223 -0
  23. data/features/message_detection/W0711.feature +113 -0
  24. data/features/message_detection/W0712.feature +113 -0
  25. data/features/message_detection/W0713.feature +110 -0
  26. data/features/message_detection/W0714.feature +118 -0
  27. data/features/message_detection/W0715.feature +118 -0
  28. data/features/message_detection/W0716.feature +1 -0
  29. data/features/message_detection/W0717.feature +1 -0
  30. data/features/message_detection/W0718.feature +1 -0
  31. data/features/message_detection/W0719.feature +154 -0
  32. data/features/message_detection/W0723.feature +1 -2
  33. data/features/message_detection/W0732.feature +3 -0
  34. data/features/message_detection/W0733.feature +3 -0
  35. data/features/message_detection/W0734.feature +4 -0
  36. data/features/message_detection/W0735.feature +4 -0
  37. data/features/message_detection/W0745.feature +132 -0
  38. data/features/message_detection/W0780.feature +68 -0
  39. data/features/message_detection/W0783.feature +95 -0
  40. data/features/message_detection/W0792.feature +124 -0
  41. data/features/message_detection/W0793.feature +153 -0
  42. data/features/message_detection/W0794.feature +90 -0
  43. data/features/message_detection/W0830.feature +65 -0
  44. data/features/message_detection/W0833.feature +220 -0
  45. data/features/message_detection/W0834.feature +189 -0
  46. data/features/message_detection/W1026.feature +105 -0
  47. data/features/message_detection/W1031.feature +17 -34
  48. data/features/message_detection/W1039.feature +268 -0
  49. data/features/message_detection/W1047.feature +163 -0
  50. data/features/message_detection/W1066.feature +1 -0
  51. data/features/message_detection/W1067.feature +1 -0
  52. data/features/message_detection/W1068.feature +1 -0
  53. data/features/message_detection/W1069.feature +5 -0
  54. data/features/message_detection/W1070.feature +5 -0
  55. data/features/message_detection/W1071.feature +83 -0
  56. data/features/message_detection/W1073.feature +3 -2
  57. data/features/message_detection/W9003.feature +7 -12
  58. data/features/step_definitions/message_detection_steps.rb +4 -31
  59. data/features/support/env.rb +117 -2
  60. data/lib/adlint/c/branch.rb +0 -2
  61. data/lib/adlint/c/ctrlexpr.rb +33 -0
  62. data/lib/adlint/c/expr.rb +119 -31
  63. data/lib/adlint/c/interp.rb +44 -3
  64. data/lib/adlint/c/message.rb +1411 -29
  65. data/lib/adlint/c/object.rb +16 -2
  66. data/lib/adlint/c/option.rb +1 -0
  67. data/lib/adlint/c/parser.rb +101 -100
  68. data/lib/adlint/c/parser.y +3 -2
  69. data/lib/adlint/c/phase.rb +18 -0
  70. data/lib/adlint/c/resolver.rb +23 -0
  71. data/lib/adlint/c/syntax.rb +90 -4
  72. data/lib/adlint/c/type.rb +177 -110
  73. data/lib/adlint/cpp/macro.rb +4 -4
  74. data/lib/adlint/version.rb +2 -2
  75. data/share/demo/bad_include/test/"1/".h +0 -0
  76. data/share/doc/developers_guide_ja.html +3 -3
  77. data/share/doc/developers_guide_ja.texi +1 -1
  78. data/share/doc/users_guide_en.html +467 -506
  79. data/share/doc/users_guide_en.texi +95 -125
  80. data/share/doc/users_guide_ja.html +471 -518
  81. data/share/doc/users_guide_ja.texi +95 -133
  82. data/spec/spec_helper.rb +6 -0
  83. metadata +37 -10
@@ -1,5 +1,3 @@
1
- require "aruba/cucumber"
2
-
3
1
  NOARCH_TRAITS = <<EOF
4
2
  version: "1.0.0"
5
3
 
@@ -38,9 +36,24 @@ compiler_traits:
38
36
  data_ptr_alignment: 32
39
37
  char_as_unsigned_char: true
40
38
  include_path:
39
+ - "."
41
40
  arithmetic:
42
41
  logical_right_shift: true
43
42
  extension_substitution:
43
+ "pascal": ""
44
+ "__pascal": ""
45
+ "fortran": ""
46
+ "__fortran": ""
47
+ "cdecl": ""
48
+ "__cdecl": ""
49
+ "near": ""
50
+ "__near": ""
51
+ "far": ""
52
+ "__far": ""
53
+ "huge": ""
54
+ "__huge": ""
55
+ "__extension__": ""
56
+ "__attribute__(__adlint__any)": ""
44
57
  arbitrary_substitution:
45
58
  "typeof": "__typeof__"
46
59
  "__typeof": "__typeof__"
@@ -56,3 +69,105 @@ message_traits:
56
69
  language: "ja_JP"
57
70
  change_list:
58
71
  EOF
72
+
73
+ DUMMY_STDIO_H = <<EOF
74
+ #if !defined(DUMMY_STDIO_H)
75
+ #define DUMMY_STDIO_H
76
+
77
+ extern int printf(const char *, ...);
78
+ extern int scanf(const char *, ...);
79
+
80
+ typedef int FILE;
81
+ extern FILE *stdin;
82
+ extern FILE *stdout;
83
+ extern FILE *stderr;
84
+
85
+ extern int fprintf(FILE *, const char *, ...);
86
+ extern int fscanf(FILE *, const char *, ...);
87
+
88
+ #endif
89
+ EOF
90
+
91
+ DUMMY_MATH_H = <<EOF
92
+ #if !defined(DUMMY_MATH_H)
93
+ #define DUMMY_MATH_H
94
+ #endif
95
+ EOF
96
+
97
+ DUMMY_ASSERT_H = <<EOF
98
+ #if !defined(DUMMY_ASSERT_H)
99
+ #define DUMMY_ASSERT_H
100
+
101
+ #define assert(expr) (0)
102
+
103
+ #endif
104
+ EOF
105
+
106
+ require "pathname"
107
+ require "stringio"
108
+
109
+ if ENV["ADLINT_COV"] =~ /1|on|true/
110
+ require "simplecov"
111
+ require "simplecov-html"
112
+ SimpleCov.start
113
+ end
114
+
115
+ $envdir = Pathname.new(__FILE__).realpath.dirname
116
+ $prefix = Pathname.new("../..").expand_path($envdir)
117
+ $bindir = Pathname.new("bin").expand_path($prefix)
118
+ $tmpdir = Pathname.new("cucumber-tmp").expand_path($prefix)
119
+
120
+ module Kernel
121
+ def exit(status)
122
+ # NOTE: To avoid terminating cucumber process.
123
+ end
124
+ end
125
+
126
+ def run_adlint(cmd, *args)
127
+ create_adlint_files
128
+ cd_to_tmpdir { $all_output = exec(cmd, *args) }
129
+ end
130
+
131
+ def cd_to_tmpdir(&block)
132
+ orig_wd = Dir.getwd
133
+ Dir.mkdir($tmpdir) unless Dir.exist?($tmpdir)
134
+ Dir.chdir($tmpdir)
135
+ yield
136
+ ensure
137
+ Dir.chdir(orig_wd)
138
+ end
139
+
140
+ def exec(cmd, *args)
141
+ ARGV.replace(args)
142
+ orig_stdout = $stdout.dup
143
+ orig_stderr = $stderr.dup
144
+ File.open("all_output", "w") do |io|
145
+ $stdout.reopen(io)
146
+ $stderr.reopen(io)
147
+ load "#{$bindir}/#{cmd}"
148
+ $stdout.flush
149
+ $stderr.flush
150
+ end
151
+ $stdout.reopen(orig_stdout)
152
+ $stderr.reopen(orig_stderr)
153
+ File.read("all_output")
154
+ end
155
+
156
+ def create_src_file(fpath, content)
157
+ cd_to_tmpdir { create_file(fpath, content) }
158
+ end
159
+
160
+ def create_adlint_files
161
+ cd_to_tmpdir do
162
+ create_file("noarch_traits.yml", NOARCH_TRAITS)
163
+ create_file("empty_pinit.h")
164
+ create_file("empty_cinit.h")
165
+ create_file("stdio.h", DUMMY_STDIO_H)
166
+ create_file("math.h", DUMMY_MATH_H)
167
+ create_file("assert.h", DUMMY_ASSERT_H)
168
+ end
169
+ end
170
+
171
+ def create_file(fname, content = "")
172
+ File.open(fname, "w") { |io| io.puts content }
173
+ end
@@ -125,8 +125,6 @@ module C #:nodoc:
125
125
  controlling_expression.ensure_true_by_narrowing(expression).commit!
126
126
  when widening?
127
127
  controlling_expression.ensure_true_by_widening(expression).commit!
128
- else
129
- raise "branch must be for narrowing or widening."
130
128
  end
131
129
  @group.all_controlling_variables_value_exist?
132
130
  end
@@ -35,6 +35,7 @@ require "adlint/c/mediator"
35
35
  require "adlint/c/expr"
36
36
  require "adlint/c/conv"
37
37
  require "adlint/c/operator"
38
+ require "adlint/c/seqp"
38
39
 
39
40
  module AdLint #:nodoc:
40
41
  module C #:nodoc:
@@ -825,13 +826,29 @@ module C #:nodoc:
825
826
  @lhs_narrowing.ensure_result_equal_to(ScalarValue.of_true)
826
827
  lhs_variable = object_to_variable(@lhs_narrowing.result)
827
828
 
829
+ # NOTE: The ISO C99 standard saids;
830
+ #
831
+ # 6.5.13 Logical AND operator
832
+ #
833
+ # Semantics
834
+ #
835
+ # 4 Unlike the bitwise binary & operator, the && operator guarantees
836
+ # left-to-right evaluation; there is a sequence point after the
837
+ # evaluation of the first operand. If the first operand compares equal
838
+ # to 0, the second operand is not evaluated.
839
+ notify_sequence_point_reached(SequencePoint.new(@node.lhs_operand))
840
+
828
841
  # TODO: Must look about the short-circuit evaluation.
829
842
  @rhs_narrowing.load_original_values!(@lhs_narrowing)
830
843
  @rhs_narrowing.execute!
831
844
  @rhs_narrowing.ensure_result_equal_to(ScalarValue.of_true)
832
845
  rhs_variable = object_to_variable(@rhs_narrowing.result)
833
846
 
847
+ notify_sequence_point_reached(SequencePoint.new(@node.rhs_operand))
848
+
834
849
  narrowing_merge!(@lhs_narrowing, @rhs_narrowing)
850
+ notify_variable_value_referred(@node, lhs_variable)
851
+ notify_variable_value_referred(@node, rhs_variable)
835
852
 
836
853
  unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
837
854
  return temporary_variable(int_type)
@@ -865,6 +882,18 @@ module C #:nodoc:
865
882
  @lhs_narrowing.ensure_result_equal_to(ScalarValue.of_true)
866
883
  lhs_variable = object_to_variable(@lhs_narrowing.result)
867
884
 
885
+ # NOTE: The ISO C99 standard saids;
886
+ #
887
+ # 6.5.14 Logical OR operator
888
+ #
889
+ # Semantics
890
+ #
891
+ # 4 Unlike the bitwise | operator, the || operator guarantees
892
+ # left-to-right evaluation; there is a sequence point after the
893
+ # evaluation of the first operand. If the first operand compares
894
+ # unequal to 0, the second operand is not evaluated.
895
+ notify_sequence_point_reached(SequencePoint.new(@node.lhs_operand))
896
+
868
897
  # TODO: Must look about the short-circuit evaluation.
869
898
  # FIXME: Base value of the RHS narrowing should be updated to ensure that
870
899
  # the LHS condition is false.
@@ -872,7 +901,11 @@ module C #:nodoc:
872
901
  @rhs_narrowing.ensure_result_equal_to(ScalarValue.of_true)
873
902
  rhs_variable = object_to_variable(@rhs_narrowing.result)
874
903
 
904
+ notify_sequence_point_reached(SequencePoint.new(@node.rhs_operand))
905
+
875
906
  widening_merge!(@lhs_narrowing, @rhs_narrowing)
907
+ notify_variable_value_referred(@node, lhs_variable)
908
+ notify_variable_value_referred(@node, rhs_variable)
876
909
 
877
910
  unless lhs_variable.type.scalar? && rhs_variable.type.scalar?
878
911
  return temporary_variable(int_type)
data/lib/adlint/c/expr.rb CHANGED
@@ -32,6 +32,7 @@
32
32
  require "adlint/c/mediator"
33
33
  require "adlint/c/const"
34
34
  require "adlint/c/conv"
35
+ require "adlint/c/seqp"
35
36
 
36
37
  module AdLint #:nodoc:
37
38
  module C #:nodoc:
@@ -91,8 +92,10 @@ module C #:nodoc:
91
92
  _notify_variable_value_referred(node, array_or_pointer)
92
93
  end
93
94
 
94
- unless subscript.variable? && subscript.value.scalar? &&
95
- subscript.value.exist?
95
+ unless subscript.variable? and
96
+ subscript.value.scalar? && subscript.value.exist? or
97
+ subscript.type.void?
98
+ # NOTE: To detect bad value reference of `void' expressions.
96
99
  return temporary_variable(result_type)
97
100
  end
98
101
  _notify_variable_value_referred(node, subscript)
@@ -284,7 +287,7 @@ module C #:nodoc:
284
287
 
285
288
  notify_prefix_increment_expr_evaled(node, variable, original_value)
286
289
 
287
- variable
290
+ temporary_variable(variable.type, variable.value)
288
291
  end
289
292
 
290
293
  def execute_prefix_decrement_expression(node, object)
@@ -305,7 +308,7 @@ module C #:nodoc:
305
308
 
306
309
  notify_prefix_decrement_expr_evaled(node, variable, original_value)
307
310
 
308
- variable
311
+ temporary_variable(variable.type, variable.value)
309
312
  end
310
313
 
311
314
  def execute_address_expression(node, object)
@@ -358,7 +361,10 @@ module C #:nodoc:
358
361
 
359
362
  def execute_unary_arithmetic_expression(node, object)
360
363
  variable = object_to_variable(object)
361
- return temporary_variable unless variable.type.scalar?
364
+ unless variable.type.scalar? || variable.type.void?
365
+ # NOTE: To detect bad value reference of `void' expressions.
366
+ return temporary_variable
367
+ end
362
368
 
363
369
  unless variable == object
364
370
  notify_implicit_conv_performed(node.operand, object, variable)
@@ -393,12 +399,21 @@ module C #:nodoc:
393
399
 
394
400
  notify_explicit_conv_performed(node, variable, converted)
395
401
 
402
+ # NOTE: A cast-expression does not refer a source value essentially.
403
+ # But, to avoid misunderstand that a return value of a function is
404
+ # discarded when the return value is casted before assigning to a
405
+ # variable.
406
+ _notify_variable_value_referred(node, variable)
407
+
396
408
  converted
397
409
  end
398
410
 
399
411
  def execute_multiplicative_expression(node, lhs_object, rhs_object)
400
412
  lhs_variable = object_to_variable(lhs_object)
401
- return temporary_variable unless lhs_variable.type.scalar?
413
+ unless lhs_variable.type.scalar? || lhs_variable.type.void?
414
+ # NOTE: To detect bad value reference of `void' expressions.
415
+ return temporary_variable
416
+ end
402
417
 
403
418
  unless lhs_variable == lhs_object
404
419
  notify_implicit_conv_performed(node.lhs_operand,
@@ -406,7 +421,10 @@ module C #:nodoc:
406
421
  end
407
422
 
408
423
  rhs_variable = object_to_variable(rhs_object)
409
- return temporary_variable unless rhs_variable.type.scalar?
424
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
425
+ # NOTE: To detect bad value reference of `void' expressions.
426
+ return temporary_variable
427
+ end
410
428
 
411
429
  unless rhs_variable == rhs_object
412
430
  notify_implicit_conv_performed(node.rhs_operand,
@@ -457,7 +475,10 @@ module C #:nodoc:
457
475
 
458
476
  def execute_additive_expression(node, lhs_object, rhs_object)
459
477
  lhs_variable = object_to_variable(lhs_object)
460
- return temporary_variable unless lhs_variable.type.scalar?
478
+ unless lhs_variable.type.scalar? || lhs_variable.type.void?
479
+ # NOTE: To detect bad value reference of `void' expressions.
480
+ return temporary_variable
481
+ end
461
482
 
462
483
  unless lhs_variable == lhs_object
463
484
  notify_implicit_conv_performed(node.lhs_operand,
@@ -465,7 +486,10 @@ module C #:nodoc:
465
486
  end
466
487
 
467
488
  rhs_variable = object_to_variable(rhs_object)
468
- return temporary_variable unless rhs_variable.type.scalar?
489
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
490
+ # NOTE: To detect bad value reference of `void' expressions.
491
+ return temporary_variable
492
+ end
469
493
 
470
494
  unless rhs_variable == rhs_object
471
495
  notify_implicit_conv_performed(node.rhs_operand,
@@ -509,7 +533,10 @@ module C #:nodoc:
509
533
 
510
534
  def execute_shift_expression(node, lhs_object, rhs_object)
511
535
  lhs_variable = object_to_variable(lhs_object)
512
- return temporary_variable unless lhs_variable.type.scalar?
536
+ unless lhs_variable.type.scalar? || lhs_variable.type.void?
537
+ # NOTE: To detect bad value reference of `void' expressions.
538
+ return temporary_variable
539
+ end
513
540
 
514
541
  unless lhs_variable == lhs_object
515
542
  notify_implicit_conv_performed(node.lhs_operand,
@@ -517,7 +544,10 @@ module C #:nodoc:
517
544
  end
518
545
 
519
546
  rhs_variable = object_to_variable(rhs_object)
520
- return temporary_variable unless rhs_variable.type.scalar?
547
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
548
+ # NOTE: To detect bad value reference of `void' expressions.
549
+ return temporary_variable
550
+ end
521
551
 
522
552
  unless rhs_variable == rhs_object
523
553
  notify_implicit_conv_performed(node.rhs_operand,
@@ -569,7 +599,8 @@ module C #:nodoc:
569
599
 
570
600
  def execute_relational_expression(node, lhs_object, rhs_object)
571
601
  lhs_variable = object_to_variable(lhs_object)
572
- unless lhs_variable.type.scalar?
602
+ unless lhs_variable.type.scalar? || lhs_variable.type.void?
603
+ # NOTE: To detect bad value reference of `void' expressions.
573
604
  return temporary_variable(int_type, ScalarValue.of_arbitrary)
574
605
  end
575
606
 
@@ -579,7 +610,8 @@ module C #:nodoc:
579
610
  end
580
611
 
581
612
  rhs_variable = object_to_variable(rhs_object)
582
- unless rhs_variable.type.scalar?
613
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
614
+ # NOTE: To detect bad value reference of `void' expressions.
583
615
  return temporary_variable(int_type, ScalarValue.of_arbitrary)
584
616
  end
585
617
 
@@ -627,7 +659,8 @@ module C #:nodoc:
627
659
 
628
660
  def execute_equality_expression(node, lhs_object, rhs_object)
629
661
  lhs_variable = object_to_variable(lhs_object)
630
- unless lhs_variable.type.scalar?
662
+ unless lhs_variable.type.scalar? || lhs_variable.type.void?
663
+ # NOTE: To detect bad value reference of `void' expressions.
631
664
  return temporary_variable(int_type, ScalarValue.of_arbitrary)
632
665
  end
633
666
 
@@ -637,7 +670,8 @@ module C #:nodoc:
637
670
  end
638
671
 
639
672
  rhs_variable = object_to_variable(rhs_object)
640
- unless rhs_variable.type.scalar?
673
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
674
+ # NOTE: To detect bad value reference of `void' expressions.
641
675
  return temporary_variable(int_type, ScalarValue.of_arbitrary)
642
676
  end
643
677
 
@@ -679,7 +713,10 @@ module C #:nodoc:
679
713
 
680
714
  def execute_and_expression(node, lhs_object, rhs_object)
681
715
  lhs_variable = object_to_variable(lhs_object)
682
- return temporary_variable unless lhs_variable.type.scalar?
716
+ unless lhs_variable.type.scalar? || lhs_variable.type.void?
717
+ # NOTE: To detect bad value reference of `void' expressions.
718
+ return temporary_variable
719
+ end
683
720
 
684
721
  unless lhs_variable == lhs_object
685
722
  notify_implicit_conv_performed(node.lhs_operand,
@@ -687,7 +724,10 @@ module C #:nodoc:
687
724
  end
688
725
 
689
726
  rhs_variable = object_to_variable(rhs_object)
690
- return temporary_variable unless rhs_variable.type.scalar?
727
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
728
+ # NOTE: To detect bad value reference of `void' expressions.
729
+ return temporary_variable
730
+ end
691
731
 
692
732
  unless rhs_variable == rhs_object
693
733
  notify_implicit_conv_performed(node.rhs_operand,
@@ -721,7 +761,10 @@ module C #:nodoc:
721
761
 
722
762
  def execute_exclusive_or_expression(node, lhs_object, rhs_object)
723
763
  lhs_variable = object_to_variable(lhs_object)
724
- return temporary_variable unless lhs_variable.type.scalar?
764
+ unless lhs_variable.type.scalar? || lhs_variable.type.void?
765
+ # NOTE: To detect bad value reference of `void' expressions.
766
+ return temporary_variable
767
+ end
725
768
 
726
769
  unless lhs_variable == lhs_object
727
770
  notify_implicit_conv_performed(node.lhs_operand,
@@ -729,7 +772,10 @@ module C #:nodoc:
729
772
  end
730
773
 
731
774
  rhs_variable = object_to_variable(rhs_object)
732
- return temporary_variable unless rhs_variable.type.scalar?
775
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
776
+ # NOTE: To detect bad value reference of `void' expressions.
777
+ return temporary_variable
778
+ end
733
779
 
734
780
  unless rhs_variable == rhs_object
735
781
  notify_implicit_conv_performed(node.rhs_operand,
@@ -763,7 +809,10 @@ module C #:nodoc:
763
809
 
764
810
  def execute_inclusive_or_expression(node, lhs_object, rhs_object)
765
811
  lhs_variable = object_to_variable(lhs_object)
766
- return temporary_variable unless lhs_variable.type.scalar?
812
+ unless lhs_variable.type.scalar? || lhs_variable.type.void?
813
+ # NOTE: To detect bad value reference of `void' expressions.
814
+ return temporary_variable
815
+ end
767
816
 
768
817
  unless lhs_variable == lhs_object
769
818
  notify_implicit_conv_performed(node.lhs_operand,
@@ -771,7 +820,10 @@ module C #:nodoc:
771
820
  end
772
821
 
773
822
  rhs_variable = object_to_variable(rhs_object)
774
- return temporary_variable unless rhs_variable.type.scalar?
823
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
824
+ # NOTE: To detect bad value reference of `void' expressions.
825
+ return temporary_variable
826
+ end
775
827
 
776
828
  unless rhs_variable == rhs_object
777
829
  notify_implicit_conv_performed(node.rhs_operand,
@@ -844,7 +896,10 @@ module C #:nodoc:
844
896
  lhs_variable = lhs_object
845
897
 
846
898
  rhs_variable = object_to_variable(rhs_object)
847
- return temporary_variable unless rhs_variable.type.scalar?
899
+ unless rhs_variable.type.scalar? || rhs_variable.type.void?
900
+ # NOTE: To detect bad value reference of `void' expressions.
901
+ return temporary_variable
902
+ end
848
903
 
849
904
  unless rhs_variable == rhs_object
850
905
  notify_implicit_conv_performed(node.rhs_operand,
@@ -1166,7 +1221,7 @@ module C #:nodoc:
1166
1221
 
1167
1222
  result_variable = temporary_variable(lhs_converted.type, result_value)
1168
1223
 
1169
- notify_shift_expr_evaled(node, lhs_converted, rhs_converted,
1224
+ notify_shift_expr_evaled(node, lhs_variable, rhs_variable,
1170
1225
  result_variable)
1171
1226
 
1172
1227
  if result_variable.type.same_as?(lhs_variable.type)
@@ -1224,7 +1279,7 @@ module C #:nodoc:
1224
1279
 
1225
1280
  result_variable = temporary_variable(lhs_converted.type, result_value)
1226
1281
 
1227
- notify_shift_expr_evaled(node, lhs_converted, rhs_converted,
1282
+ notify_shift_expr_evaled(node, lhs_variable, rhs_variable,
1228
1283
  result_variable)
1229
1284
 
1230
1285
  if result_variable.type.same_as?(lhs_variable.type)
@@ -1416,13 +1471,12 @@ module C #:nodoc:
1416
1471
  def _notify_variable_value_updated(node, object)
1417
1472
  if object.variable?
1418
1473
  interpreter.notify_variable_value_updated(node, object)
1419
- end
1420
-
1421
- if object.kind_of?(InnerVariable)
1422
- # NOTE: When a value of the inner-variable of array or composite object
1423
- # is updated, the outer variable's value should also be notified
1424
- # to be updated.
1425
- _notify_variable_value_updated(node, object.owner)
1474
+ if object.inner?
1475
+ # NOTE: When a value of the inner-variable of array or composite
1476
+ # object is updated, the outer variable's value should also be
1477
+ # notified to be updated.
1478
+ _notify_variable_value_updated(node, object.owner)
1479
+ end
1426
1480
  end
1427
1481
  end
1428
1482
 
@@ -1743,8 +1797,22 @@ module C #:nodoc:
1743
1797
  return temporary_variable(int_type) unless lhs_object.variable?
1744
1798
 
1745
1799
  lhs_variable = lhs_object
1800
+
1801
+ # NOTE: The ISO C99 standard saids;
1802
+ #
1803
+ # 6.5.13 Logical AND operator
1804
+ #
1805
+ # Semantics
1806
+ #
1807
+ # 4 Unlike the bitwise binary & operator, the && operator guarantees
1808
+ # left-to-right evaluation; there is a sequence point after the
1809
+ # evaluation of the first operand. If the first operand compares equal
1810
+ # to 0, the second operand is not evaluated.
1811
+ notify_sequence_point_reached(SequencePoint.new(node.lhs_operand))
1812
+
1746
1813
  if lhs_variable.value.scalar? && lhs_variable.value.must_be_false?
1747
1814
  # NOTE: Doing the short-circuit evaluation.
1815
+ notify_variable_value_referred(node, lhs_variable)
1748
1816
  return temporary_variable(int_type, ScalarValue.of_false)
1749
1817
  end
1750
1818
 
@@ -1752,6 +1820,9 @@ module C #:nodoc:
1752
1820
  return temporary_variable(int_type) unless rhs_object.variable?
1753
1821
 
1754
1822
  rhs_variable = rhs_object
1823
+ notify_sequence_point_reached(SequencePoint.new(node.rhs_operand))
1824
+ notify_variable_value_referred(node, lhs_variable)
1825
+ notify_variable_value_referred(node, rhs_variable)
1755
1826
 
1756
1827
  if lhs_variable.value.scalar? && rhs_variable.value.scalar?
1757
1828
  # NOTE: No usual-arithmetic-conversion.
@@ -1772,8 +1843,22 @@ module C #:nodoc:
1772
1843
  return temporary_variable(int_type) unless lhs_object.variable?
1773
1844
 
1774
1845
  lhs_variable = lhs_object
1846
+
1847
+ # NOTE: The ISO C99 standard saids;
1848
+ #
1849
+ # 6.5.14 Logical OR operator
1850
+ #
1851
+ # Semantics
1852
+ #
1853
+ # 4 Unlike the bitwise | operator, the || operator guarantees
1854
+ # left-to-right evaluation; there is a sequence point after the
1855
+ # evaluation of the first operand. If the first operand compares
1856
+ # unequal to 0, the second operand is not evaluated.
1857
+ notify_sequence_point_reached(SequencePoint.new(node.lhs_operand))
1858
+
1775
1859
  if lhs_variable.value.scalar? && lhs_variable.value.must_be_true?
1776
1860
  # NOTE: Doing the short-circuit evaluation.
1861
+ notify_variable_value_referred(node, lhs_variable)
1777
1862
  return temporary_variable(int_type, ScalarValue.of_true)
1778
1863
  end
1779
1864
 
@@ -1781,6 +1866,9 @@ module C #:nodoc:
1781
1866
  return temporary_variable(int_type) unless rhs_object.variable?
1782
1867
 
1783
1868
  rhs_variable = rhs_object
1869
+ notify_sequence_point_reached(SequencePoint.new(node.rhs_operand))
1870
+ notify_variable_value_referred(node, lhs_variable)
1871
+ notify_variable_value_referred(node, rhs_variable)
1784
1872
 
1785
1873
  if lhs_variable.value.scalar? && rhs_variable.value.scalar?
1786
1874
  # NOTE: No usual-arithmetic-conversion.