adlint 1.16.0 → 1.18.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 (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.