adlint 2.4.0 → 2.4.6
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.
- 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