adlint 1.16.0 → 1.18.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +471 -0
- data/MANIFEST +35 -8
- data/NEWS +50 -4
- data/bin/adlint +7 -7
- data/bin/adlint_chk +7 -7
- data/bin/adlint_cma +7 -7
- data/bin/adlint_sma +7 -7
- data/bin/adlintize +5 -5
- data/etc/mesg.d/en_US/messages.yml +3 -3
- data/etc/mesg.d/ja_JP/messages.yml +3 -3
- data/features/message_detection/E0013.feature +34 -0
- data/features/message_detection/W0007.feature +2 -0
- data/features/message_detection/W0583.feature +1 -2
- data/features/message_detection/W0641.feature +132 -0
- data/features/message_detection/W0643.feature +1 -1
- data/features/message_detection/W0644.feature +529 -0
- data/features/message_detection/W0645.feature +1 -1
- data/features/message_detection/W0649.feature +277 -0
- data/features/message_detection/W0650.feature +208 -0
- data/features/message_detection/W0697.feature +6 -0
- data/features/message_detection/W0705.feature +350 -0
- data/features/message_detection/W0707.feature +223 -0
- data/features/message_detection/W0711.feature +113 -0
- data/features/message_detection/W0712.feature +113 -0
- data/features/message_detection/W0713.feature +110 -0
- data/features/message_detection/W0714.feature +118 -0
- data/features/message_detection/W0715.feature +118 -0
- data/features/message_detection/W0716.feature +1 -0
- data/features/message_detection/W0717.feature +1 -0
- data/features/message_detection/W0718.feature +1 -0
- data/features/message_detection/W0719.feature +154 -0
- data/features/message_detection/W0723.feature +1 -2
- data/features/message_detection/W0732.feature +3 -0
- data/features/message_detection/W0733.feature +3 -0
- data/features/message_detection/W0734.feature +4 -0
- data/features/message_detection/W0735.feature +4 -0
- data/features/message_detection/W0745.feature +132 -0
- data/features/message_detection/W0780.feature +68 -0
- data/features/message_detection/W0783.feature +95 -0
- data/features/message_detection/W0792.feature +124 -0
- data/features/message_detection/W0793.feature +153 -0
- data/features/message_detection/W0794.feature +90 -0
- data/features/message_detection/W0830.feature +65 -0
- data/features/message_detection/W0833.feature +220 -0
- data/features/message_detection/W0834.feature +189 -0
- data/features/message_detection/W1026.feature +105 -0
- data/features/message_detection/W1031.feature +17 -34
- data/features/message_detection/W1039.feature +268 -0
- data/features/message_detection/W1047.feature +163 -0
- data/features/message_detection/W1066.feature +1 -0
- data/features/message_detection/W1067.feature +1 -0
- data/features/message_detection/W1068.feature +1 -0
- data/features/message_detection/W1069.feature +5 -0
- data/features/message_detection/W1070.feature +5 -0
- data/features/message_detection/W1071.feature +83 -0
- data/features/message_detection/W1073.feature +3 -2
- data/features/message_detection/W9003.feature +7 -12
- data/features/step_definitions/message_detection_steps.rb +4 -31
- data/features/support/env.rb +117 -2
- data/lib/adlint/c/branch.rb +0 -2
- data/lib/adlint/c/ctrlexpr.rb +33 -0
- data/lib/adlint/c/expr.rb +119 -31
- data/lib/adlint/c/interp.rb +44 -3
- data/lib/adlint/c/message.rb +1411 -29
- data/lib/adlint/c/object.rb +16 -2
- data/lib/adlint/c/option.rb +1 -0
- data/lib/adlint/c/parser.rb +101 -100
- data/lib/adlint/c/parser.y +3 -2
- data/lib/adlint/c/phase.rb +18 -0
- data/lib/adlint/c/resolver.rb +23 -0
- data/lib/adlint/c/syntax.rb +90 -4
- data/lib/adlint/c/type.rb +177 -110
- data/lib/adlint/cpp/macro.rb +4 -4
- data/lib/adlint/version.rb +2 -2
- data/share/demo/bad_include/test/"1/".h +0 -0
- data/share/doc/developers_guide_ja.html +3 -3
- data/share/doc/developers_guide_ja.texi +1 -1
- data/share/doc/users_guide_en.html +467 -506
- data/share/doc/users_guide_en.texi +95 -125
- data/share/doc/users_guide_ja.html +471 -518
- data/share/doc/users_guide_ja.texi +95 -133
- data/spec/spec_helper.rb +6 -0
- metadata +37 -10
data/features/support/env.rb
CHANGED
@@ -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
|
data/lib/adlint/c/branch.rb
CHANGED
@@ -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
|
data/lib/adlint/c/ctrlexpr.rb
CHANGED
@@ -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?
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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,
|
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,
|
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
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
|
1424
|
-
|
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.
|