adlint 2.4.0 → 2.4.6
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +63 -0
- data/MANIFEST +1 -0
- data/NEWS +12 -4
- data/etc/mesg.d/c_builtin/en_US/messages.yml +1 -1
- data/etc/mesg.d/c_builtin/ja_JP/messages.yml +1 -1
- data/etc/mesg.d/core/en_US/messages.yml +1 -1
- data/etc/mesg.d/core/ja_JP/messages.yml +1 -1
- data/features/code_check/W0635.feature +57 -0
- data/features/code_check/W0644.feature +4 -0
- data/features/code_check/W1071.feature +1 -1
- data/features/code_check/W1074.feature +5 -5
- data/lib/adlint/c/branch.rb +1 -1
- data/lib/adlint/c/builtin.rb +1 -1
- data/lib/adlint/c/ctrlexpr.rb +4 -2
- data/lib/adlint/c/format.rb +12 -11
- data/lib/adlint/c/interp.rb +114 -114
- data/lib/adlint/c/object.rb +6 -22
- data/lib/adlint/c/operator.rb +4 -0
- data/lib/adlint/c/option.rb +1 -1
- data/lib/adlint/c/parser.rb +1 -1
- data/lib/adlint/c/parser.y +1 -1
- data/lib/adlint/c/syntax.rb +566 -31
- data/lib/adlint/c/type.rb +21 -1
- data/lib/adlint/c/value.rb +0 -68
- data/lib/adlint/cpp/eval.rb +2 -2
- data/lib/adlint/version.rb +2 -2
- 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 +10 -10
- data/share/doc/users_guide_en.texi +8 -8
- data/share/doc/users_guide_ja.html +10 -10
- data/share/doc/users_guide_ja.texi +8 -8
- data/spec/adlint/c/type_spec.rb +104 -5
- metadata +3 -2
data/lib/adlint/c/interp.rb
CHANGED
@@ -947,6 +947,10 @@ module C #:nodoc:
|
|
947
947
|
|
948
948
|
def initialize(owner)
|
949
949
|
super(owner, Statement)
|
950
|
+
|
951
|
+
# NOTE: All effective controlling expressions in the executing
|
952
|
+
# iteration-statements.
|
953
|
+
@effective_ctrlexpr_stack = []
|
950
954
|
end
|
951
955
|
|
952
956
|
def visit_generic_labeled_statement(node)
|
@@ -1002,25 +1006,29 @@ module C #:nodoc:
|
|
1002
1006
|
checkpoint(node.location)
|
1003
1007
|
|
1004
1008
|
node.executed = true
|
1005
|
-
|
1006
|
-
|
1009
|
+
|
1010
|
+
orig_ctrlexpr = node.expression
|
1011
|
+
if orig_ctrlexpr == effective_ctrlexpr
|
1012
|
+
ctrlexpr_value = ScalarValue.of_arbitrary
|
1013
|
+
ctrlexpr = nil
|
1014
|
+
else
|
1015
|
+
ctrlexpr_value = value_of(interpret(orig_ctrlexpr))
|
1016
|
+
ctrlexpr = orig_ctrlexpr.to_normalized_logical
|
1017
|
+
end
|
1007
1018
|
notify_if_ctrlexpr_evaled(node, ctrlexpr_value)
|
1008
1019
|
|
1009
1020
|
case
|
1010
1021
|
when ctrlexpr_value.must_be_true?
|
1011
|
-
branched_eval(ctrlexpr, NARROWING, FINAL, COMPLETE) do
|
1022
|
+
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
|
1012
1023
|
interpret(node.statement)
|
1013
1024
|
end
|
1014
1025
|
when ctrlexpr_value.may_be_true?
|
1015
|
-
branched_eval(ctrlexpr, NARROWING, FINAL) do
|
1026
|
+
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND) do
|
1016
1027
|
interpret(node.statement)
|
1017
1028
|
end
|
1018
1029
|
else
|
1019
|
-
# NOTE: To
|
1020
|
-
|
1021
|
-
branched_eval(nil, NARROWING, FINAL) do
|
1022
|
-
interpret(ctrlexpr)
|
1023
|
-
end
|
1030
|
+
# NOTE: To end the current branch group of else-if sequence.
|
1031
|
+
branched_eval(nil, NARROWING, FINAL) {}
|
1024
1032
|
end
|
1025
1033
|
end
|
1026
1034
|
|
@@ -1028,23 +1036,27 @@ module C #:nodoc:
|
|
1028
1036
|
checkpoint(node.location)
|
1029
1037
|
|
1030
1038
|
node.executed = true
|
1031
|
-
|
1032
|
-
|
1039
|
+
|
1040
|
+
orig_ctrlexpr = node.expression
|
1041
|
+
if orig_ctrlexpr == effective_ctrlexpr
|
1042
|
+
ctrlexpr_value = ScalarValue.of_arbitrary
|
1043
|
+
ctrlexpr = nil
|
1044
|
+
else
|
1045
|
+
ctrlexpr_value = value_of(interpret(orig_ctrlexpr))
|
1046
|
+
ctrlexpr = orig_ctrlexpr.to_normalized_logical
|
1047
|
+
end
|
1033
1048
|
notify_if_else_ctrlexpr_evaled(node, ctrlexpr_value)
|
1034
1049
|
|
1035
1050
|
case
|
1036
1051
|
when ctrlexpr_value.must_be_true?
|
1037
|
-
branched_eval(ctrlexpr, NARROWING, FINAL, COMPLETE) do
|
1052
|
+
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
|
1038
1053
|
interpret(node.then_statement)
|
1039
1054
|
end
|
1040
1055
|
return
|
1041
1056
|
when ctrlexpr_value.may_be_true?
|
1042
|
-
branched_eval(ctrlexpr, NARROWING) do
|
1057
|
+
branched_eval(ctrlexpr, NARROWING, IMPLICIT_COND) do
|
1043
1058
|
interpret(node.then_statement)
|
1044
1059
|
end
|
1045
|
-
else
|
1046
|
-
# NOTE: To warn about the controlling expression.
|
1047
|
-
interpret(ctrlexpr)
|
1048
1060
|
end
|
1049
1061
|
|
1050
1062
|
case node.else_statement
|
@@ -1064,22 +1076,30 @@ module C #:nodoc:
|
|
1064
1076
|
notify_while_stmt_started(node)
|
1065
1077
|
|
1066
1078
|
widen_varying_variable_value_domain(node)
|
1067
|
-
effective_ctrlexpr = deduct_effective_controlling_expression(node)
|
1068
1079
|
|
1069
|
-
|
1070
|
-
ctrlexpr_value = value_of(interpret(ctrlexpr))
|
1080
|
+
ctrlexpr_value = value_of(interpret(node.expression))
|
1071
1081
|
notify_while_ctrlexpr_evaled(node, ctrlexpr_value)
|
1072
1082
|
|
1083
|
+
orig_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
|
1084
|
+
|
1073
1085
|
case
|
1074
1086
|
when ctrlexpr_value.must_be_true?
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1087
|
+
begin
|
1088
|
+
enter_iteration_statement(orig_ctrlexpr)
|
1089
|
+
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
|
1090
|
+
interpret(node.statement)
|
1091
|
+
end
|
1092
|
+
ensure
|
1093
|
+
leave_iteration_statement(orig_ctrlexpr)
|
1078
1094
|
end
|
1079
1095
|
when ctrlexpr_value.may_be_true?
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1096
|
+
begin
|
1097
|
+
enter_iteration_statement(orig_ctrlexpr)
|
1098
|
+
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND) do
|
1099
|
+
interpret(node.statement)
|
1100
|
+
end
|
1101
|
+
ensure
|
1102
|
+
leave_iteration_statement(orig_ctrlexpr)
|
1083
1103
|
end
|
1084
1104
|
end
|
1085
1105
|
ensure
|
@@ -1093,11 +1113,16 @@ module C #:nodoc:
|
|
1093
1113
|
notify_do_stmt_started(node)
|
1094
1114
|
|
1095
1115
|
widen_varying_variable_value_domain(node)
|
1096
|
-
effective_ctrlexpr = deduct_effective_controlling_expression(node)
|
1097
1116
|
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1117
|
+
orig_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
|
1118
|
+
|
1119
|
+
begin
|
1120
|
+
enter_iteration_statement(orig_ctrlexpr)
|
1121
|
+
branched_eval(ctrlexpr, NARROWING, FINAL, IMPLICIT_COND, COMPLETE) do
|
1122
|
+
interpret(node.statement)
|
1123
|
+
end
|
1124
|
+
ensure
|
1125
|
+
leave_iteration_statement(orig_ctrlexpr)
|
1101
1126
|
end
|
1102
1127
|
|
1103
1128
|
ctrlexpr_value = value_of(interpret(node.expression))
|
@@ -1115,47 +1140,21 @@ module C #:nodoc:
|
|
1115
1140
|
node.initial_statement.accept(self)
|
1116
1141
|
|
1117
1142
|
widen_varying_variable_value_domain(node)
|
1118
|
-
|
1143
|
+
orig_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
|
1119
1144
|
|
1120
1145
|
node.condition_statement.executed = true
|
1121
|
-
if
|
1122
|
-
ctrlexpr_value = value_of(interpret(
|
1146
|
+
if explicit_ctrlexpr = node.condition_statement.expression
|
1147
|
+
ctrlexpr_value = value_of(interpret(explicit_ctrlexpr))
|
1123
1148
|
notify_for_ctrlexpr_evaled(node, ctrlexpr_value)
|
1124
|
-
|
1125
|
-
case
|
1126
|
-
when ctrlexpr_value.must_be_true?
|
1127
|
-
branched_eval(effective_ctrlexpr,
|
1128
|
-
NARROWING, FINAL, IMPLICIT_CONDITION, COMPLETE) do
|
1129
|
-
interpret(node.body_statement)
|
1130
|
-
interpret(node.expression) if node.expression
|
1131
|
-
# NOTE: To avoid that value of the controlling variable is marked
|
1132
|
-
# as updated at end of the for-statement. Value of the
|
1133
|
-
# controlling variable is referred by the controlling
|
1134
|
-
# expression at the last iteration.
|
1135
|
-
# FIXME: This re-interpretation of the controlling expression may
|
1136
|
-
# causes duplicative warning messages.
|
1137
|
-
interpret(ctrlexpr)
|
1138
|
-
end
|
1139
|
-
when ctrlexpr_value.may_be_true?
|
1140
|
-
branched_eval(effective_ctrlexpr,
|
1141
|
-
NARROWING, FINAL, IMPLICIT_CONDITION) do
|
1142
|
-
interpret(node.body_statement)
|
1143
|
-
interpret(node.expression) if node.expression
|
1144
|
-
# NOTE: To avoid that value of the controlling variable is marked
|
1145
|
-
# as updated at end of the for-statement. Value of the
|
1146
|
-
# controlling variable is referred by the controlling
|
1147
|
-
# expression at the last iteration.
|
1148
|
-
# FIXME: This re-interpretation of the controlling expression may
|
1149
|
-
# causes duplicative warning messages.
|
1150
|
-
interpret(ctrlexpr)
|
1151
|
-
end
|
1152
|
-
end
|
1153
1149
|
else
|
1154
|
-
|
1155
|
-
|
1156
|
-
|
1157
|
-
|
1158
|
-
|
1150
|
+
ctrlexpr_value = ScalarValue.of_true
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
case
|
1154
|
+
when ctrlexpr_value.must_be_true?
|
1155
|
+
interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, true)
|
1156
|
+
when ctrlexpr_value.may_be_true?
|
1157
|
+
interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, false)
|
1159
1158
|
end
|
1160
1159
|
ensure
|
1161
1160
|
notify_for_stmt_ended(node)
|
@@ -1171,47 +1170,21 @@ module C #:nodoc:
|
|
1171
1170
|
notify_c99_for_stmt_started(node)
|
1172
1171
|
|
1173
1172
|
widen_varying_variable_value_domain(node)
|
1174
|
-
|
1173
|
+
orig_ctrlexpr, ctrlexpr = node.deduct_controlling_expression
|
1175
1174
|
|
1176
1175
|
node.condition_statement.executed = true
|
1177
|
-
if
|
1178
|
-
ctrlexpr_value = value_of(interpret(
|
1176
|
+
if explicit_ctrlexpr = node.condition_statement.expression
|
1177
|
+
ctrlexpr_value = value_of(interpret(explicit_ctrlexpr))
|
1179
1178
|
notify_c99_for_ctrlexpr_evaled(node, ctrlexpr_value)
|
1180
|
-
|
1181
|
-
case
|
1182
|
-
when ctrlexpr_value.must_be_true?
|
1183
|
-
branched_eval(effective_ctrlexpr,
|
1184
|
-
NARROWING, FINAL, IMPLICIT_CONDITION, COMPLETE) do
|
1185
|
-
interpret(node.body_statement)
|
1186
|
-
interpret(node.expression) if node.expression
|
1187
|
-
# NOTE: To avoid that value of the controlling variable is marked
|
1188
|
-
# as updated at end of the c99-for-statement. Value of the
|
1189
|
-
# controlling variable is referred by the controlling
|
1190
|
-
# expression at the last iteration.
|
1191
|
-
# FIXME: This re-interpretation of the controlling expression may
|
1192
|
-
# causes duplicative warning messages.
|
1193
|
-
interpret(ctrlexpr)
|
1194
|
-
end
|
1195
|
-
when ctrlexpr_value.may_be_true?
|
1196
|
-
branched_eval(effective_ctrlexpr,
|
1197
|
-
NARROWING, FINAL, IMPLICIT_CONDITION) do
|
1198
|
-
interpret(node.body_statement)
|
1199
|
-
interpret(node.expression) if node.expression
|
1200
|
-
# NOTE: To avoid that value of the controlling variable is marked
|
1201
|
-
# as updated at end of the c99-for-statement. Value of the
|
1202
|
-
# controlling variable is referred by the controlling
|
1203
|
-
# expression at the last iteration.
|
1204
|
-
# FIXME: This re-interpretation of the controlling expression may
|
1205
|
-
# causes duplicative warning messages.
|
1206
|
-
interpret(ctrlexpr)
|
1207
|
-
end
|
1208
|
-
end
|
1209
1179
|
else
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1180
|
+
ctrlexpr_value = ScalarValue.of_true
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
case
|
1184
|
+
when ctrlexpr_value.must_be_true?
|
1185
|
+
interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, true)
|
1186
|
+
when ctrlexpr_value.may_be_true?
|
1187
|
+
interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, false)
|
1215
1188
|
end
|
1216
1189
|
end
|
1217
1190
|
ensure
|
@@ -1277,6 +1250,33 @@ module C #:nodoc:
|
|
1277
1250
|
end
|
1278
1251
|
|
1279
1252
|
private
|
1253
|
+
def interpret_for_body_statement(node, orig_ctrlexpr, ctrlexpr, complete)
|
1254
|
+
enter_iteration_statement(orig_ctrlexpr)
|
1255
|
+
|
1256
|
+
if complete
|
1257
|
+
branch_options = [NARROWING, FINAL, IMPLICIT_COND, COMPLETE]
|
1258
|
+
else
|
1259
|
+
branch_options = [NARROWING, FINAL, IMPLICIT_COND]
|
1260
|
+
end
|
1261
|
+
|
1262
|
+
branched_eval(ctrlexpr, *branch_options) do
|
1263
|
+
interpret(node.body_statement)
|
1264
|
+
interpret(node.expression) if node.expression
|
1265
|
+
|
1266
|
+
if explicit_ctrlexpr = node.condition_statement.expression
|
1267
|
+
# NOTE: To avoid that value of the controlling variable is marked
|
1268
|
+
# as updated at end of the for-statement. Value of the
|
1269
|
+
# controlling variable is referred by the controlling
|
1270
|
+
# expression at the last iteration.
|
1271
|
+
# FIXME: This re-interpretation of the controlling expression may
|
1272
|
+
# causes duplicative warning messages.
|
1273
|
+
interpret(explicit_ctrlexpr)
|
1274
|
+
end
|
1275
|
+
end
|
1276
|
+
ensure
|
1277
|
+
leave_iteration_statement(orig_ctrlexpr)
|
1278
|
+
end
|
1279
|
+
|
1280
1280
|
def uninitialize_block_local_variables(generic_labeled_statement)
|
1281
1281
|
related_goto_statements = generic_labeled_statement.referrers
|
1282
1282
|
return if related_goto_statements.empty?
|
@@ -1388,16 +1388,16 @@ module C #:nodoc:
|
|
1388
1388
|
end
|
1389
1389
|
end
|
1390
1390
|
|
1391
|
-
def
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
|
1397
|
-
|
1398
|
-
|
1399
|
-
|
1400
|
-
|
1391
|
+
def effective_ctrlexpr
|
1392
|
+
@effective_ctrlexpr_stack.last
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
def enter_iteration_statement(effective_ctrlexpr)
|
1396
|
+
@effective_ctrlexpr_stack.push(effective_ctrlexpr)
|
1397
|
+
end
|
1398
|
+
|
1399
|
+
def leave_iteration_statement(effective_ctrlexpr)
|
1400
|
+
@effective_ctrlexpr_stack.pop
|
1401
1401
|
end
|
1402
1402
|
end
|
1403
1403
|
|
@@ -1440,7 +1440,7 @@ module C #:nodoc:
|
|
1440
1440
|
end
|
1441
1441
|
|
1442
1442
|
def execute_switch_branches(variable, block_items)
|
1443
|
-
base_options = [SMOTHER_BREAK,
|
1443
|
+
base_options = [SMOTHER_BREAK, IMPLICIT_COND, NARROWING]
|
1444
1444
|
base_options.push(COMPLETE) if complete?(block_items)
|
1445
1445
|
|
1446
1446
|
index = 0
|
data/lib/adlint/c/object.rb
CHANGED
@@ -219,23 +219,15 @@ module C #:nodoc:
|
|
219
219
|
end
|
220
220
|
|
221
221
|
def narrow_value_domain!(operator, value)
|
222
|
-
unless
|
223
|
-
|
224
|
-
|
225
|
-
end
|
226
|
-
|
227
|
-
self_value.narrow_domain!(operator, value.coerce_to(type))
|
228
|
-
self_value.exist?
|
222
|
+
assign!(type.arbitrary_value) unless self.value
|
223
|
+
self.value.narrow_domain!(operator, value.coerce_to(type))
|
224
|
+
self.value.exist?
|
229
225
|
end
|
230
226
|
|
231
227
|
def widen_value_domain!(operator, value)
|
232
|
-
unless
|
233
|
-
|
234
|
-
|
235
|
-
end
|
236
|
-
|
237
|
-
self_value.widen_domain!(operator, value.coerce_to(type))
|
238
|
-
self_value.exist?
|
228
|
+
assign!(type.nil_value) unless self.value
|
229
|
+
self.value.widen_domain!(operator, value.coerce_to(type))
|
230
|
+
self.value.exist?
|
239
231
|
end
|
240
232
|
|
241
233
|
def enter_value_versioning_group
|
@@ -266,10 +258,6 @@ module C #:nodoc:
|
|
266
258
|
def relate_to_memory(memory)
|
267
259
|
bind_to(memory)
|
268
260
|
end
|
269
|
-
|
270
|
-
def modifiable_value
|
271
|
-
binding.memory.read_modifiable
|
272
|
-
end
|
273
261
|
end
|
274
262
|
|
275
263
|
class ScopedVariable < Variable
|
@@ -1081,10 +1069,6 @@ module C #:nodoc:
|
|
1081
1069
|
end
|
1082
1070
|
|
1083
1071
|
def read
|
1084
|
-
@value ? @frozen_value ||= FrozenValue.new(@value) : nil
|
1085
|
-
end
|
1086
|
-
|
1087
|
-
def read_modifiable
|
1088
1072
|
@value
|
1089
1073
|
end
|
1090
1074
|
|
data/lib/adlint/c/operator.rb
CHANGED
data/lib/adlint/c/option.rb
CHANGED
data/lib/adlint/c/parser.rb
CHANGED
@@ -2796,7 +2796,7 @@ module_eval(<<'.,.,', 'parser.y', 1229)
|
|
2796
2796
|
def _reduce_166(val, _values, result)
|
2797
2797
|
checkpoint(val[0].location)
|
2798
2798
|
|
2799
|
-
val[
|
2799
|
+
val[4].full = true
|
2800
2800
|
result = ArrayDeclarator.new(val[0], val[4])
|
2801
2801
|
result.head_token = val[0].head_token
|
2802
2802
|
result.tail_token = val[5]
|
data/lib/adlint/c/parser.y
CHANGED