adlint 1.4.0 → 1.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +413 -5
- data/MANIFEST +6 -0
- data/NEWS +43 -4
- data/etc/mesg.d/en_US/messages.yml +1 -1
- data/etc/mesg.d/ja_JP/messages.yml +1 -1
- data/lib/adlint/c.rb +1 -0
- data/lib/adlint/c/enum.rb +52 -0
- data/lib/adlint/c/expr.rb +43 -102
- data/lib/adlint/c/interp.rb +1 -1
- data/lib/adlint/c/mediator.rb +1 -0
- data/lib/adlint/c/message.rb +831 -49
- data/lib/adlint/c/message_shima.rb +236 -0
- data/lib/adlint/c/metric.rb +9 -0
- data/lib/adlint/c/object.rb +37 -32
- data/lib/adlint/c/parser.rb +7 -7
- data/lib/adlint/c/parser.y +7 -7
- data/lib/adlint/c/phase.rb +21 -0
- data/lib/adlint/c/syntax.rb +11 -4
- data/lib/adlint/c/type.rb +1 -1
- data/lib/adlint/cpp.rb +1 -0
- data/lib/adlint/cpp/asm.rb +73 -0
- data/lib/adlint/cpp/message.rb +13 -0
- data/lib/adlint/cpp/message_shima.rb +36 -0
- data/lib/adlint/cpp/phase.rb +3 -0
- data/lib/adlint/cpp/source.rb +9 -0
- data/lib/adlint/version.rb +3 -3
- data/share/demo/Makefile +4 -0
- data/share/demo/bad_conv/bad_conv.c +12 -0
- data/share/demo/bad_enum/bad_enum.c +48 -2
- data/share/demo/bad_label/bad_label.c +26 -0
- data/share/demo/bad_macro/bad_macro.c +3 -0
- data/share/demo/implicit_conv/implicit_conv.c +1 -0
- data/share/demo/inline_asm/inline_asm.c +18 -0
- data/share/demo/invalid_call/invalid_call.c +5 -0
- data/share/demo/multi_decl/multi_decl_1.c +30 -0
- data/share/demo/overflow/overflow.c +3 -3
- data/share/demo/redundant_select/redundant_select.c +25 -0
- data/share/demo/reserved_ident/reserved_ident.c +98 -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 +234 -126
- data/share/doc/users_guide_en.texi +207 -98
- data/share/doc/users_guide_ja.html +247 -156
- data/share/doc/users_guide_ja.texi +221 -130
- data/share/sample/vim-7.3/adlint/xxd/adlint_traits.yml +1 -1
- metadata +8 -2
data/lib/adlint/c/interp.rb
CHANGED
@@ -127,7 +127,7 @@ module C #:nodoc:
|
|
127
127
|
|
128
128
|
# NOTE: Notified when the interpreter evaluates an expression which results
|
129
129
|
# a named variable.
|
130
|
-
def_plugin_and_notifier :variable_referred, :
|
130
|
+
def_plugin_and_notifier :variable_referred, :expression, :variable
|
131
131
|
|
132
132
|
# NOTE: Notified when the interpreter evaluates an expression which results
|
133
133
|
# a constant temporary variable.
|
data/lib/adlint/c/mediator.rb
CHANGED
data/lib/adlint/c/message.rb
CHANGED
@@ -440,6 +440,9 @@ module C #:nodoc:
|
|
440
440
|
private
|
441
441
|
def check_comparison(binary_expression,
|
442
442
|
lhs_variable, rhs_variable, result)
|
443
|
+
return if binary_expression.lhs_operand.kind_of?(NullConstantSpecifier)
|
444
|
+
return if binary_expression.rhs_operand.kind_of?(NullConstantSpecifier)
|
445
|
+
|
443
446
|
if lhs_variable.type.pointer? || rhs_variable.type.pointer?
|
444
447
|
W(:W0027, binary_expression.location)
|
445
448
|
end
|
@@ -453,11 +456,12 @@ module C #:nodoc:
|
|
453
456
|
interp.on_indirection_expr_evaled += method(:check_indirection)
|
454
457
|
interp.on_member_access_expr_evaled += method(:check_member_access)
|
455
458
|
interp.on_array_subscript_expr_evaled += method(:check_array_subscript)
|
459
|
+
@enum_tbl = interp.environment.enumerator_table
|
456
460
|
end
|
457
461
|
|
458
462
|
private
|
459
463
|
def check_indirection(indirection_expression, variable, dereferenced)
|
460
|
-
return unless indirection_expression.operand.constant?
|
464
|
+
return unless indirection_expression.operand.constant?(@enum_tbl)
|
461
465
|
|
462
466
|
if variable.value.scalar? &&
|
463
467
|
variable.value.must_be_equal_to?(ScalarValue.of(0))
|
@@ -468,7 +472,7 @@ module C #:nodoc:
|
|
468
472
|
def check_member_access(member_access_expression,
|
469
473
|
outer_variable, member_variable)
|
470
474
|
return unless outer_variable.type.pointer?
|
471
|
-
return unless member_access_expression.expression.constant?
|
475
|
+
return unless member_access_expression.expression.constant?(@enum_tbl)
|
472
476
|
if outer_variable.value.scalar? &&
|
473
477
|
outer_variable.value.must_be_equal_to?(ScalarValue.of(0))
|
474
478
|
W(:W0028, member_access_expression.location)
|
@@ -479,7 +483,7 @@ module C #:nodoc:
|
|
479
483
|
pointer_variable, subscript_variable,
|
480
484
|
array_variable, result_variable)
|
481
485
|
return unless pointer_variable.type.pointer?
|
482
|
-
return unless array_subscript_expression.expression.constant?
|
486
|
+
return unless array_subscript_expression.expression.constant?(@enum_tbl)
|
483
487
|
if pointer_variable.value.scalar? &&
|
484
488
|
pointer_variable.value.must_be_equal_to?(ScalarValue.of(0))
|
485
489
|
W(:W0028, array_subscript_expression.location)
|
@@ -501,6 +505,7 @@ module C #:nodoc:
|
|
501
505
|
interp.on_postfix_increment_expr_evaled += method(:check_unary_postfix)
|
502
506
|
interp.on_prefix_decrement_expr_evaled += method(:check_unary_prefix)
|
503
507
|
interp.on_postfix_decrement_expr_evaled += method(:check_unary_postfix)
|
508
|
+
@enum_tbl = interp.environment.enumerator_table
|
504
509
|
end
|
505
510
|
|
506
511
|
private
|
@@ -508,12 +513,12 @@ module C #:nodoc:
|
|
508
513
|
lhs_type, lhs_value = lhs_variable.type, lhs_variable.value
|
509
514
|
rhs_type, rhs_value = rhs_variable.type, rhs_variable.value
|
510
515
|
|
511
|
-
if binary_expression.lhs_operand.constant? &&
|
516
|
+
if binary_expression.lhs_operand.constant?(@enum_tbl) &&
|
512
517
|
lhs_type.pointer? && lhs_value.must_be_equal_to?(ScalarValue.of(0))
|
513
518
|
W(:W0030, binary_expression.lhs_operand.location)
|
514
519
|
end
|
515
520
|
|
516
|
-
if binary_expression.rhs_operand.constant? &&
|
521
|
+
if binary_expression.rhs_operand.constant?(@enum_tbl) &&
|
517
522
|
rhs_type.pointer? && rhs_value.must_be_equal_to?(ScalarValue.of(0))
|
518
523
|
W(:W0030, binary_expression.rhs_operand.location)
|
519
524
|
end
|
@@ -522,7 +527,7 @@ module C #:nodoc:
|
|
522
527
|
def check_unary_prefix(unary_expression, operand_variable, original_value)
|
523
528
|
type, value = operand_variable.type, original_value
|
524
529
|
|
525
|
-
if unary_expression.operand.constant? &&
|
530
|
+
if unary_expression.operand.constant?(@enum_tbl) &&
|
526
531
|
type.pointer? && value.must_be_equal_to?(ScalarValue.of(0))
|
527
532
|
W(:W0030, unary_expression.operand.location)
|
528
533
|
end
|
@@ -532,7 +537,7 @@ module C #:nodoc:
|
|
532
537
|
operand_variable, result_variable)
|
533
538
|
type, value = operand_variable.type, operand_variable.value
|
534
539
|
|
535
|
-
if postfix_expression.operand.constant? &&
|
540
|
+
if postfix_expression.operand.constant?(@enum_tbl) &&
|
536
541
|
type.pointer? && value.must_be_equal_to?(ScalarValue.of(0))
|
537
542
|
W(:W0030, postfix_expression.operand.location)
|
538
543
|
end
|
@@ -546,6 +551,7 @@ module C #:nodoc:
|
|
546
551
|
interp.on_function_started += method(:start_function)
|
547
552
|
interp.on_parameter_defined += method(:add_parameter)
|
548
553
|
interp.on_variable_referred += method(:use_parameter)
|
554
|
+
interp.on_variable_value_referred += method(:use_parameter)
|
549
555
|
interp.on_function_ended += method(:check_unused_parameter)
|
550
556
|
@parameters = nil
|
551
557
|
end
|
@@ -563,7 +569,7 @@ module C #:nodoc:
|
|
563
569
|
end
|
564
570
|
end
|
565
571
|
|
566
|
-
def use_parameter(
|
572
|
+
def use_parameter(expression, variable)
|
567
573
|
return unless @parameters
|
568
574
|
|
569
575
|
if variable.named?
|
@@ -1773,12 +1779,13 @@ module C #:nodoc:
|
|
1773
1779
|
super
|
1774
1780
|
interp = context[:c_interpreter]
|
1775
1781
|
interp.on_multiplicative_expr_evaled += method(:check)
|
1782
|
+
@enum_tbl = interp.environment.enumerator_table
|
1776
1783
|
end
|
1777
1784
|
|
1778
1785
|
private
|
1779
1786
|
def check(multiplicative_expression, lhs_variable, rhs_variable, result)
|
1780
1787
|
return if multiplicative_expression.operator.type == "*"
|
1781
|
-
return if multiplicative_expression.rhs_operand.constant?
|
1788
|
+
return if multiplicative_expression.rhs_operand.constant?(@enum_tbl)
|
1782
1789
|
|
1783
1790
|
return unless rhs_variable.type.scalar? && rhs_variable.value.scalar?
|
1784
1791
|
return if rhs_variable.value.must_be_equal_to?(ScalarValue.of(0))
|
@@ -1794,12 +1801,13 @@ module C #:nodoc:
|
|
1794
1801
|
super
|
1795
1802
|
interp = context[:c_interpreter]
|
1796
1803
|
interp.on_multiplicative_expr_evaled += method(:check)
|
1804
|
+
@enum_tbl = interp.environment.enumerator_table
|
1797
1805
|
end
|
1798
1806
|
|
1799
1807
|
private
|
1800
1808
|
def check(multiplicative_expression, lhs_variable, rhs_variable, result)
|
1801
1809
|
return if multiplicative_expression.operator.type == "*"
|
1802
|
-
return unless multiplicative_expression.rhs_operand.constant?
|
1810
|
+
return unless multiplicative_expression.rhs_operand.constant?(@enum_tbl)
|
1803
1811
|
|
1804
1812
|
return unless rhs_variable.type.scalar? && rhs_variable.value.scalar?
|
1805
1813
|
|
@@ -1814,12 +1822,13 @@ module C #:nodoc:
|
|
1814
1822
|
super
|
1815
1823
|
interp = context[:c_interpreter]
|
1816
1824
|
interp.on_multiplicative_expr_evaled += method(:check)
|
1825
|
+
@enum_tbl = interp.environment.enumerator_table
|
1817
1826
|
end
|
1818
1827
|
|
1819
1828
|
private
|
1820
1829
|
def check(multiplicative_expression, lhs_variable, rhs_variable, result)
|
1821
1830
|
return if multiplicative_expression.operator.type == "*"
|
1822
|
-
return if multiplicative_expression.rhs_operand.constant?
|
1831
|
+
return if multiplicative_expression.rhs_operand.constant?(@enum_tbl)
|
1823
1832
|
|
1824
1833
|
return unless rhs_variable.type.scalar? && rhs_variable.value.scalar?
|
1825
1834
|
|
@@ -2059,6 +2068,8 @@ module C #:nodoc:
|
|
2059
2068
|
|
2060
2069
|
@parameters.each do |name, (written, variable, location)|
|
2061
2070
|
next if variable.type.const?
|
2071
|
+
next if variable.type.array? && variable.type.base_type.const?
|
2072
|
+
|
2062
2073
|
W(:W0104, location, name) unless written
|
2063
2074
|
end
|
2064
2075
|
|
@@ -6041,11 +6052,12 @@ module C #:nodoc:
|
|
6041
6052
|
interp.on_indirection_expr_evaled += method(:check_indirection)
|
6042
6053
|
interp.on_member_access_expr_evaled += method(:check_member_access)
|
6043
6054
|
interp.on_array_subscript_expr_evaled += method(:check_array_subscript)
|
6055
|
+
@enum_tbl = interp.environment.enumerator_table
|
6044
6056
|
end
|
6045
6057
|
|
6046
6058
|
private
|
6047
6059
|
def check_indirection(indirection_expression, variable, dereferenced)
|
6048
|
-
return if indirection_expression.operand.constant?
|
6060
|
+
return if indirection_expression.operand.constant?(@enum_tbl)
|
6049
6061
|
if variable.value.scalar? &&
|
6050
6062
|
variable.value.must_be_equal_to?(ScalarValue.of(0))
|
6051
6063
|
W(:W0421, indirection_expression.location)
|
@@ -6055,7 +6067,7 @@ module C #:nodoc:
|
|
6055
6067
|
def check_member_access(member_access_expression,
|
6056
6068
|
outer_variable, member_variable)
|
6057
6069
|
return unless outer_variable.type.pointer?
|
6058
|
-
return if member_access_expression.expression.constant?
|
6070
|
+
return if member_access_expression.expression.constant?(@enum_tbl)
|
6059
6071
|
if outer_variable.value.scalar? &&
|
6060
6072
|
outer_variable.value.must_be_equal_to?(ScalarValue.of(0))
|
6061
6073
|
W(:W0421, member_access_expression.location)
|
@@ -6066,7 +6078,7 @@ module C #:nodoc:
|
|
6066
6078
|
pointer_variable, subscript_variable,
|
6067
6079
|
array_variable, result_variable)
|
6068
6080
|
return unless pointer_variable.type.pointer?
|
6069
|
-
return if array_subscript_expression.expression.constant?
|
6081
|
+
return if array_subscript_expression.expression.constant?(@enum_tbl)
|
6070
6082
|
if pointer_variable.value.scalar? &&
|
6071
6083
|
pointer_variable.value.must_be_equal_to?(ScalarValue.of(0))
|
6072
6084
|
W(:W0421, array_subscript_expression.location)
|
@@ -6081,11 +6093,12 @@ module C #:nodoc:
|
|
6081
6093
|
interp.on_indirection_expr_evaled += method(:check_indirection)
|
6082
6094
|
interp.on_member_access_expr_evaled += method(:check_member_access)
|
6083
6095
|
interp.on_array_subscript_expr_evaled += method(:check_array_subscript)
|
6096
|
+
@enum_tbl = interp.environment.enumerator_table
|
6084
6097
|
end
|
6085
6098
|
|
6086
6099
|
private
|
6087
6100
|
def check_indirection(indirection_expression, variable, dereferenced)
|
6088
|
-
return if indirection_expression.operand.constant?
|
6101
|
+
return if indirection_expression.operand.constant?(@enum_tbl)
|
6089
6102
|
return unless variable.value.scalar?
|
6090
6103
|
|
6091
6104
|
if !variable.value.must_be_equal_to?(ScalarValue.of(0)) &&
|
@@ -6097,7 +6110,7 @@ module C #:nodoc:
|
|
6097
6110
|
def check_member_access(member_access_expression,
|
6098
6111
|
outer_variable, member_variable)
|
6099
6112
|
return unless outer_variable.type.pointer?
|
6100
|
-
return if member_access_expression.expression.constant?
|
6113
|
+
return if member_access_expression.expression.constant?(@enum_tbl)
|
6101
6114
|
return unless outer_variable.value.scalar?
|
6102
6115
|
|
6103
6116
|
if !outer_variable.value.must_be_equal_to?(ScalarValue.of(0)) &&
|
@@ -6110,7 +6123,7 @@ module C #:nodoc:
|
|
6110
6123
|
pointer_variable, subscript_variable,
|
6111
6124
|
array_variable, result_variable)
|
6112
6125
|
return unless pointer_variable.type.pointer?
|
6113
|
-
return if array_subscript_expression.expression.constant?
|
6126
|
+
return if array_subscript_expression.expression.constant?(@enum_tbl)
|
6114
6127
|
return unless pointer_variable.value.scalar?
|
6115
6128
|
|
6116
6129
|
if !pointer_variable.value.must_be_equal_to?(ScalarValue.of(0)) &&
|
@@ -7029,7 +7042,7 @@ module C #:nodoc:
|
|
7029
7042
|
base_type = type.unqualify.base_type
|
7030
7043
|
next unless !base_type.function? && base_type.const?
|
7031
7044
|
|
7032
|
-
if pointee = @interp.pointee_of(arg)
|
7045
|
+
if pointee = @interp.pointee_of(arg) and pointee.variable?
|
7033
7046
|
if pointee.value.must_be_undefined?
|
7034
7047
|
W(:W0461,
|
7035
7048
|
function_call_expression.argument_expressions[index].location)
|
@@ -7055,7 +7068,7 @@ module C #:nodoc:
|
|
7055
7068
|
next unless type && type.pointer?
|
7056
7069
|
next unless type.unqualify.base_type.const?
|
7057
7070
|
|
7058
|
-
if pointee = @interp.pointee_of(arg)
|
7071
|
+
if pointee = @interp.pointee_of(arg) and pointee.variable?
|
7059
7072
|
next if pointee.value.must_be_undefined?
|
7060
7073
|
if pointee.value.may_be_undefined?
|
7061
7074
|
W(:W0462,
|
@@ -10048,6 +10061,7 @@ module C #:nodoc:
|
|
10048
10061
|
super
|
10049
10062
|
interp = context[:c_interpreter]
|
10050
10063
|
interp.on_shift_expr_evaled += method(:check)
|
10064
|
+
@enum_tbl = interp.environment.enumerator_table
|
10051
10065
|
end
|
10052
10066
|
|
10053
10067
|
private
|
@@ -10055,7 +10069,7 @@ module C #:nodoc:
|
|
10055
10069
|
operator = shift_expression.operator.type
|
10056
10070
|
return unless operator == "<<" || operator == "<<="
|
10057
10071
|
|
10058
|
-
return unless shift_expression.lhs_operand.constant?
|
10072
|
+
return unless shift_expression.lhs_operand.constant?(@enum_tbl)
|
10059
10073
|
return unless lhs_variable.type.signed?
|
10060
10074
|
|
10061
10075
|
if lhs_variable.value.must_be_less_than?(ScalarValue.of(0)) or
|
@@ -10076,6 +10090,7 @@ module C #:nodoc:
|
|
10076
10090
|
super
|
10077
10091
|
interp = context[:c_interpreter]
|
10078
10092
|
interp.on_shift_expr_evaled += method(:check)
|
10093
|
+
@enum_tbl = interp.environment.enumerator_table
|
10079
10094
|
end
|
10080
10095
|
|
10081
10096
|
private
|
@@ -10083,7 +10098,7 @@ module C #:nodoc:
|
|
10083
10098
|
operator = shift_expression.operator.type
|
10084
10099
|
return unless operator == "<<" || operator == "<<="
|
10085
10100
|
|
10086
|
-
return if shift_expression.lhs_operand.constant?
|
10101
|
+
return if shift_expression.lhs_operand.constant?(@enum_tbl)
|
10087
10102
|
return unless lhs_variable.type.signed?
|
10088
10103
|
|
10089
10104
|
if lhs_variable.value.must_be_less_than?(ScalarValue.of(0)) or
|
@@ -10104,6 +10119,7 @@ module C #:nodoc:
|
|
10104
10119
|
super
|
10105
10120
|
interp = context[:c_interpreter]
|
10106
10121
|
interp.on_shift_expr_evaled += method(:check)
|
10122
|
+
@enum_tbl = interp.environment.enumerator_table
|
10107
10123
|
end
|
10108
10124
|
|
10109
10125
|
private
|
@@ -10111,7 +10127,7 @@ module C #:nodoc:
|
|
10111
10127
|
operator = shift_expression.operator.type
|
10112
10128
|
return unless operator == "<<" || operator == "<<="
|
10113
10129
|
|
10114
|
-
return if shift_expression.lhs_operand.constant?
|
10130
|
+
return if shift_expression.lhs_operand.constant?(@enum_tbl)
|
10115
10131
|
return unless lhs_variable.type.signed?
|
10116
10132
|
|
10117
10133
|
if !lhs_variable.value.must_be_less_than?(ScalarValue.of(0)) &&
|
@@ -10211,7 +10227,7 @@ module C #:nodoc:
|
|
10211
10227
|
if src_type.integer_conversion_rank < dst_type.integer_conversion_rank
|
10212
10228
|
case @rvalues[original_variable]
|
10213
10229
|
when UnaryArithmeticExpression, ShiftExpression,
|
10214
|
-
|
10230
|
+
AdditiveExpression, MultiplicativeExpression
|
10215
10231
|
W(:W0578, initializer_or_expression.location)
|
10216
10232
|
end
|
10217
10233
|
end
|
@@ -10249,6 +10265,68 @@ module C #:nodoc:
|
|
10249
10265
|
end
|
10250
10266
|
end
|
10251
10267
|
|
10268
|
+
class W0579 < PassiveMessageDetection
|
10269
|
+
def initialize(context)
|
10270
|
+
super
|
10271
|
+
interp = context[:c_interpreter]
|
10272
|
+
interp.on_explicit_conv_performed += method(:check)
|
10273
|
+
interp.on_function_started += method(:clear_rvalues)
|
10274
|
+
interp.on_unary_arithmetic_expr_evaled += method(:handle_unary)
|
10275
|
+
interp.on_shift_expr_evaled += method(:handle_shift)
|
10276
|
+
interp.on_additive_expr_evaled += method(:handle_additive)
|
10277
|
+
interp.on_multiplicative_expr_evaled += method(:handle_multiplicative)
|
10278
|
+
@rvalues = nil
|
10279
|
+
end
|
10280
|
+
|
10281
|
+
private
|
10282
|
+
def check(cast_expression, original_variable, result_variable)
|
10283
|
+
return unless @rvalues
|
10284
|
+
return unless original_variable.type.integer?
|
10285
|
+
|
10286
|
+
src_type = original_variable.type
|
10287
|
+
dst_type = result_variable.type
|
10288
|
+
|
10289
|
+
if src_type.integer_conversion_rank < dst_type.integer_conversion_rank
|
10290
|
+
case @rvalues[original_variable]
|
10291
|
+
when UnaryArithmeticExpression, ShiftExpression,
|
10292
|
+
AdditiveExpression, MultiplicativeExpression
|
10293
|
+
W(:W0579, cast_expression.location)
|
10294
|
+
end
|
10295
|
+
end
|
10296
|
+
end
|
10297
|
+
|
10298
|
+
def clear_rvalues(function_definition)
|
10299
|
+
@rvalues = {}
|
10300
|
+
end
|
10301
|
+
|
10302
|
+
def handle_unary(unary_arithmetic_expression,
|
10303
|
+
operand_variable, result_variable)
|
10304
|
+
return unless unary_arithmetic_expression.operator == "~"
|
10305
|
+
memorize_rvalue_derivation(result_variable, unary_arithmetic_expression)
|
10306
|
+
end
|
10307
|
+
|
10308
|
+
def handle_shift(shift_expression,
|
10309
|
+
lhs_variable, rhs_variable, result_variable)
|
10310
|
+
return unless shift_expression.operator.type == "<<"
|
10311
|
+
memorize_rvalue_derivation(result_variable, shift_expression)
|
10312
|
+
end
|
10313
|
+
|
10314
|
+
def handle_additive(additive_expression,
|
10315
|
+
lhs_variable, rhs_variable, result_variable)
|
10316
|
+
memorize_rvalue_derivation(result_variable, additive_expression)
|
10317
|
+
end
|
10318
|
+
|
10319
|
+
def handle_multiplicative(multiplicative_expression,
|
10320
|
+
lhs_variable, rhs_variable, result_variable)
|
10321
|
+
return if multiplicative_expression.operator.type == "%"
|
10322
|
+
memorize_rvalue_derivation(result_variable, multiplicative_expression)
|
10323
|
+
end
|
10324
|
+
|
10325
|
+
def memorize_rvalue_derivation(rvalue_holder, expression)
|
10326
|
+
@rvalues[rvalue_holder] = expression if @rvalues
|
10327
|
+
end
|
10328
|
+
end
|
10329
|
+
|
10252
10330
|
class W0580 < PassiveMessageDetection
|
10253
10331
|
def initialize(context)
|
10254
10332
|
super
|
@@ -10767,6 +10845,7 @@ module C #:nodoc:
|
|
10767
10845
|
interp.on_do_stmt_ended += method(:check)
|
10768
10846
|
interp.on_for_stmt_ended += method(:check)
|
10769
10847
|
interp.on_c99_for_stmt_ended += method(:check)
|
10848
|
+
@enum_tbl = interp.environment.enumerator_table
|
10770
10849
|
@iteration_stmts = []
|
10771
10850
|
end
|
10772
10851
|
|
@@ -10820,12 +10899,14 @@ module C #:nodoc:
|
|
10820
10899
|
end
|
10821
10900
|
|
10822
10901
|
def check(iteration_statement)
|
10823
|
-
if ctrlexpr = @iteration_stmts.last.ctrlexpr
|
10824
|
-
|
10825
|
-
|
10826
|
-
|
10827
|
-
|
10828
|
-
|
10902
|
+
if ctrlexpr = @iteration_stmts.last.ctrlexpr
|
10903
|
+
unless ctrlexpr.constant?(@enum_tbl)
|
10904
|
+
ctrlexpr_value = @iteration_stmts.last.ctrlexpr_value
|
10905
|
+
ctrl_vars = @iteration_stmts.last.ctrl_vars
|
10906
|
+
if ctrlexpr_value && ctrlexpr_value.must_be_true? and
|
10907
|
+
ctrl_vars && ctrl_vars.values.none?
|
10908
|
+
W(:W0611, ctrlexpr.location)
|
10909
|
+
end
|
10829
10910
|
end
|
10830
10911
|
end
|
10831
10912
|
@iteration_stmts.pop
|
@@ -10838,13 +10919,14 @@ module C #:nodoc:
|
|
10838
10919
|
interp = context[:c_interpreter]
|
10839
10920
|
interp.on_if_ctrlexpr_evaled += method(:check)
|
10840
10921
|
interp.on_if_else_ctrlexpr_evaled += method(:check)
|
10922
|
+
@enum_tbl = interp.environment.enumerator_table
|
10841
10923
|
end
|
10842
10924
|
|
10843
10925
|
private
|
10844
10926
|
def check(selection_statement, ctrlexpr_value)
|
10845
|
-
if ctrlexpr = selection_statement.expression
|
10846
|
-
|
10847
|
-
W(:W0612, ctrlexpr.location)
|
10927
|
+
if ctrlexpr = selection_statement.expression
|
10928
|
+
unless ctrlexpr.constant?(@enum_tbl)
|
10929
|
+
W(:W0612, ctrlexpr.location) if ctrlexpr_value.must_be_true?
|
10848
10930
|
end
|
10849
10931
|
end
|
10850
10932
|
end
|
@@ -10902,11 +10984,12 @@ module C #:nodoc:
|
|
10902
10984
|
super
|
10903
10985
|
interp = context[:c_interpreter]
|
10904
10986
|
interp.on_do_ctrlexpr_evaled += method(:check)
|
10987
|
+
@enum_tbl = interp.environment.enumerator_table
|
10905
10988
|
end
|
10906
10989
|
|
10907
10990
|
private
|
10908
10991
|
def check(do_statement, ctrlexpr_value)
|
10909
|
-
unless do_statement.expression.constant?
|
10992
|
+
unless do_statement.expression.constant?(@enum_tbl)
|
10910
10993
|
if ctrlexpr_value.must_be_false?
|
10911
10994
|
W(:W0614, do_statement.expression.location)
|
10912
10995
|
end
|
@@ -12406,7 +12489,8 @@ module C #:nodoc:
|
|
12406
12489
|
|
12407
12490
|
value = original_variable.value.unique_sample
|
12408
12491
|
|
12409
|
-
|
12492
|
+
enumerators = result_variable.type.enumerators
|
12493
|
+
unless enumerators.any? { |enum| value == enum.value }
|
12410
12494
|
W(:W0727, initializer_or_expression.location)
|
12411
12495
|
end
|
12412
12496
|
end
|
@@ -12417,6 +12501,7 @@ module C #:nodoc:
|
|
12417
12501
|
super
|
12418
12502
|
interp = context[:c_interpreter]
|
12419
12503
|
interp.on_function_call_expr_evaled += method(:check)
|
12504
|
+
@enum_tbl = interp.environment.enumerator_table
|
12420
12505
|
end
|
12421
12506
|
|
12422
12507
|
private
|
@@ -12425,9 +12510,12 @@ module C #:nodoc:
|
|
12425
12510
|
args.each_with_index do |(arg_variable, param_type), index|
|
12426
12511
|
next unless param_type && param_type.enum?
|
12427
12512
|
|
12513
|
+
arg_expr = expression.argument_expressions[index]
|
12514
|
+
next unless arg_expr.constant?(@enum_tbl)
|
12515
|
+
|
12428
12516
|
if arg_variable.type.enum?
|
12429
12517
|
unless arg_variable.type.same_as?(param_type)
|
12430
|
-
W(:W0728,
|
12518
|
+
W(:W0728, arg_expr.location)
|
12431
12519
|
end
|
12432
12520
|
end
|
12433
12521
|
end
|
@@ -12439,11 +12527,13 @@ module C #:nodoc:
|
|
12439
12527
|
super
|
12440
12528
|
interp = context[:c_interpreter]
|
12441
12529
|
interp.on_assignment_expr_evaled += method(:check)
|
12530
|
+
@enum_tbl = interp.environment.enumerator_table
|
12442
12531
|
end
|
12443
12532
|
|
12444
12533
|
private
|
12445
12534
|
def check(expression, lhs_variable, rhs_variable)
|
12446
12535
|
return unless lhs_variable.type.enum?
|
12536
|
+
return unless expression.rhs_operand.constant?(@enum_tbl)
|
12447
12537
|
|
12448
12538
|
if rhs_variable.type.enum?
|
12449
12539
|
unless lhs_variable.type.same_as?(rhs_variable.type)
|
@@ -12460,6 +12550,7 @@ module C #:nodoc:
|
|
12460
12550
|
interp.on_function_started += method(:start_function)
|
12461
12551
|
interp.on_function_ended += method(:end_function)
|
12462
12552
|
interp.on_return_stmt_evaled += method(:check)
|
12553
|
+
@enum_tbl = interp.environment.enumerator_table
|
12463
12554
|
@current_function = nil
|
12464
12555
|
end
|
12465
12556
|
|
@@ -12477,6 +12568,7 @@ module C #:nodoc:
|
|
12477
12568
|
|
12478
12569
|
return unless return_type = @current_function.type.return_type
|
12479
12570
|
return unless return_type.enum?
|
12571
|
+
return unless return_statement.expression.constant?(@enum_tbl)
|
12480
12572
|
|
12481
12573
|
if result_variable.type.enum?
|
12482
12574
|
unless return_type.same_as?(result_variable.type)
|
@@ -12593,6 +12685,7 @@ module C #:nodoc:
|
|
12593
12685
|
super
|
12594
12686
|
interp = context[:c_interpreter]
|
12595
12687
|
interp.on_implicit_conv_performed += method(:check)
|
12688
|
+
@enum_tbl = interp.environment.enumerator_table
|
12596
12689
|
end
|
12597
12690
|
|
12598
12691
|
private
|
@@ -12606,7 +12699,7 @@ module C #:nodoc:
|
|
12606
12699
|
expression = initializer_or_expression
|
12607
12700
|
end
|
12608
12701
|
|
12609
|
-
return unless expression.constant?
|
12702
|
+
return unless expression.constant?(@enum_tbl)
|
12610
12703
|
|
12611
12704
|
orig_type = original_variable.type
|
12612
12705
|
conv_type = result_variable.type
|
@@ -12630,14 +12723,15 @@ module C #:nodoc:
|
|
12630
12723
|
super
|
12631
12724
|
interp = context[:c_interpreter]
|
12632
12725
|
interp.on_additive_expr_evaled += method(:check)
|
12726
|
+
@enum_tbl = interp.environment.enumerator_table
|
12633
12727
|
end
|
12634
12728
|
|
12635
12729
|
private
|
12636
12730
|
def check(additive_expression, lhs_variable, rhs_variable, result_variable)
|
12637
12731
|
return unless additive_expression.operator.type == "-"
|
12638
12732
|
|
12639
|
-
return unless additive_expression.lhs_operand.constant?
|
12640
|
-
return unless additive_expression.rhs_operand.constant?
|
12733
|
+
return unless additive_expression.lhs_operand.constant?(@enum_tbl)
|
12734
|
+
return unless additive_expression.rhs_operand.constant?(@enum_tbl)
|
12641
12735
|
|
12642
12736
|
return unless lhs_variable.type.scalar? && lhs_variable.type.unsigned?
|
12643
12737
|
return unless rhs_variable.type.scalar? && rhs_variable.type.unsigned?
|
@@ -12658,14 +12752,15 @@ module C #:nodoc:
|
|
12658
12752
|
super
|
12659
12753
|
interp = context[:c_interpreter]
|
12660
12754
|
interp.on_additive_expr_evaled += method(:check)
|
12755
|
+
@enum_tbl = interp.environment.enumerator_table
|
12661
12756
|
end
|
12662
12757
|
|
12663
12758
|
private
|
12664
12759
|
def check(additive_expression, lhs_variable, rhs_variable, result_variable)
|
12665
12760
|
return unless additive_expression.operator.type == "+"
|
12666
12761
|
|
12667
|
-
return unless additive_expression.lhs_operand.constant?
|
12668
|
-
return unless additive_expression.rhs_operand.constant?
|
12762
|
+
return unless additive_expression.lhs_operand.constant?(@enum_tbl)
|
12763
|
+
return unless additive_expression.rhs_operand.constant?(@enum_tbl)
|
12669
12764
|
|
12670
12765
|
return unless lhs_variable.type.scalar? && lhs_variable.type.unsigned?
|
12671
12766
|
return unless rhs_variable.type.scalar? && rhs_variable.type.unsigned?
|
@@ -12686,6 +12781,7 @@ module C #:nodoc:
|
|
12686
12781
|
super
|
12687
12782
|
interp = context[:c_interpreter]
|
12688
12783
|
interp.on_multiplicative_expr_evaled += method(:check)
|
12784
|
+
@enum_tbl = interp.environment.enumerator_table
|
12689
12785
|
end
|
12690
12786
|
|
12691
12787
|
private
|
@@ -12693,8 +12789,8 @@ module C #:nodoc:
|
|
12693
12789
|
result_variable)
|
12694
12790
|
return unless multiplicative_expression.operator.type == "*"
|
12695
12791
|
|
12696
|
-
return unless multiplicative_expression.lhs_operand.constant?
|
12697
|
-
return unless multiplicative_expression.rhs_operand.constant?
|
12792
|
+
return unless multiplicative_expression.lhs_operand.constant?(@enum_tbl)
|
12793
|
+
return unless multiplicative_expression.rhs_operand.constant?(@enum_tbl)
|
12698
12794
|
|
12699
12795
|
return unless lhs_variable.type.scalar? && lhs_variable.type.unsigned?
|
12700
12796
|
return unless rhs_variable.type.scalar? && rhs_variable.type.unsigned?
|
@@ -12715,6 +12811,7 @@ module C #:nodoc:
|
|
12715
12811
|
super
|
12716
12812
|
interp = context[:c_interpreter]
|
12717
12813
|
interp.on_implicit_conv_performed += method(:check)
|
12814
|
+
@enum_tbl = interp.environment.enumerator_table
|
12718
12815
|
end
|
12719
12816
|
|
12720
12817
|
private
|
@@ -12730,7 +12827,7 @@ module C #:nodoc:
|
|
12730
12827
|
expression = initializer_or_expression
|
12731
12828
|
end
|
12732
12829
|
|
12733
|
-
if expression && expression.constant? &&
|
12830
|
+
if expression && expression.constant?(@enum_tbl) &&
|
12734
12831
|
original_variable.value.must_be_less_than?(ScalarValue.of(0))
|
12735
12832
|
W(:W0742, expression.location)
|
12736
12833
|
end
|
@@ -12742,6 +12839,7 @@ module C #:nodoc:
|
|
12742
12839
|
super
|
12743
12840
|
interp = context[:c_interpreter]
|
12744
12841
|
interp.on_implicit_conv_performed += method(:check)
|
12842
|
+
@enum_tbl = interp.environment.enumerator_table
|
12745
12843
|
end
|
12746
12844
|
|
12747
12845
|
private
|
@@ -12755,7 +12853,7 @@ module C #:nodoc:
|
|
12755
12853
|
expression = initializer_or_expression
|
12756
12854
|
end
|
12757
12855
|
|
12758
|
-
return unless expression.constant?
|
12856
|
+
return unless expression.constant?(@enum_tbl)
|
12759
12857
|
|
12760
12858
|
orig_type = original_variable.type
|
12761
12859
|
conv_type = result_variable.type
|
@@ -12786,40 +12884,41 @@ module C #:nodoc:
|
|
12786
12884
|
interp.on_while_ctrlexpr_evaled += method(:check_while_statement)
|
12787
12885
|
interp.on_for_ctrlexpr_evaled += method(:check_for_statement)
|
12788
12886
|
interp.on_c99_for_ctrlexpr_evaled += method(:check_c99_for_statement)
|
12887
|
+
@enum_tbl = interp.environment.enumerator_table
|
12789
12888
|
end
|
12790
12889
|
|
12791
12890
|
private
|
12792
12891
|
def check_if_statement(if_statement, ctrlexpr_value)
|
12793
12892
|
ctrlexpr = if_statement.expression
|
12794
|
-
if ctrlexpr.constant? && ctrlexpr_value.must_be_false?
|
12893
|
+
if ctrlexpr.constant?(@enum_tbl) && ctrlexpr_value.must_be_false?
|
12795
12894
|
W(:W0744, ctrlexpr.location)
|
12796
12895
|
end
|
12797
12896
|
end
|
12798
12897
|
|
12799
12898
|
def check_if_else_statement(if_else_statement, ctrlexpr_value)
|
12800
12899
|
ctrlexpr = if_else_statement.expression
|
12801
|
-
if ctrlexpr.constant? && ctrlexpr_value.must_be_false?
|
12900
|
+
if ctrlexpr.constant?(@enum_tbl) && ctrlexpr_value.must_be_false?
|
12802
12901
|
W(:W0744, ctrlexpr.location)
|
12803
12902
|
end
|
12804
12903
|
end
|
12805
12904
|
|
12806
12905
|
def check_while_statement(while_statement, ctrlexpr_value)
|
12807
12906
|
ctrlexpr = while_statement.expression
|
12808
|
-
if ctrlexpr.constant? && ctrlexpr_value.must_be_false?
|
12907
|
+
if ctrlexpr.constant?(@enum_tbl) && ctrlexpr_value.must_be_false?
|
12809
12908
|
W(:W0744, ctrlexpr.location)
|
12810
12909
|
end
|
12811
12910
|
end
|
12812
12911
|
|
12813
12912
|
def check_for_statement(for_statement, ctrlexpr_value)
|
12814
12913
|
ctrlexpr = for_statement.condition_statement.expression
|
12815
|
-
if ctrlexpr.constant? && ctrlexpr_value.must_be_false?
|
12914
|
+
if ctrlexpr.constant?(@enum_tbl) && ctrlexpr_value.must_be_false?
|
12816
12915
|
W(:W0744, ctrlexpr.location)
|
12817
12916
|
end
|
12818
12917
|
end
|
12819
12918
|
|
12820
12919
|
def check_c99_for_statement(c99_for_statement, ctrlexpr_value)
|
12821
12920
|
ctrlexpr = c99_for_statement.condition_statement.expression
|
12822
|
-
if ctrlexpr.constant? && ctrlexpr_value.must_be_false?
|
12921
|
+
if ctrlexpr.constant?(@enum_tbl) && ctrlexpr_value.must_be_false?
|
12823
12922
|
W(:W0744, ctrlexpr.location)
|
12824
12923
|
end
|
12825
12924
|
end
|
@@ -13338,6 +13437,413 @@ module C #:nodoc:
|
|
13338
13437
|
end
|
13339
13438
|
end
|
13340
13439
|
|
13440
|
+
class W0787 < PassiveMessageDetection
|
13441
|
+
def initialize(context)
|
13442
|
+
super
|
13443
|
+
interp = context[:c_interpreter]
|
13444
|
+
interp.on_variable_declared += method(:check_object_declaration)
|
13445
|
+
interp.on_variable_defined += method(:check_object_declaration)
|
13446
|
+
interp.on_function_declared += method(:check_object_declaration)
|
13447
|
+
interp.on_function_started += method(:check_object_declaration)
|
13448
|
+
interp.on_typedef_declared += method(:check_typedef_declaration)
|
13449
|
+
interp.on_enum_declared += method(:check_enum_declaration)
|
13450
|
+
interp.on_block_started += method(:start_block)
|
13451
|
+
interp.on_block_ended += method(:end_block)
|
13452
|
+
|
13453
|
+
@object_decls_stack = [Hash.new { |hash, key| hash[key] = [] }]
|
13454
|
+
@typedef_decls_stack = [Hash.new { |hash, key| hash[key] = [] }]
|
13455
|
+
@enumerators_stack = [Hash.new(0)]
|
13456
|
+
|
13457
|
+
@object_decls_in_other_scope = Hash.new { |hash, key| hash[key] = [] }
|
13458
|
+
@typedef_decls_in_other_scope = Hash.new { |hash, key| hash[key] = [] }
|
13459
|
+
@enumerators_in_other_scope = Hash.new(0)
|
13460
|
+
end
|
13461
|
+
|
13462
|
+
private
|
13463
|
+
def check_object_declaration(declaration_or_definition, *)
|
13464
|
+
name = declaration_or_definition.identifier.value
|
13465
|
+
type = declaration_or_definition.type
|
13466
|
+
|
13467
|
+
same_name_object_decls = @object_decls_in_other_scope[name]
|
13468
|
+
unless same_name_object_decls.all? { |decl| decl.type == type }
|
13469
|
+
W(:W0787, declaration_or_definition.location, name)
|
13470
|
+
return
|
13471
|
+
end
|
13472
|
+
|
13473
|
+
same_name_typedef_decls = @typedef_decls_in_other_scope[name]
|
13474
|
+
unless same_name_typedef_decls.empty?
|
13475
|
+
W(:W0787, declaration_or_definition.location, name)
|
13476
|
+
return
|
13477
|
+
end
|
13478
|
+
|
13479
|
+
same_name_enumerators = @enumerators_in_other_scope[name]
|
13480
|
+
unless same_name_enumerators == 0
|
13481
|
+
W(:W0787, declaration_or_definition.location, name)
|
13482
|
+
return
|
13483
|
+
end
|
13484
|
+
ensure
|
13485
|
+
unless @object_decls_stack.empty?
|
13486
|
+
@object_decls_stack.last[name].push(declaration_or_definition)
|
13487
|
+
end
|
13488
|
+
end
|
13489
|
+
|
13490
|
+
def check_typedef_declaration(typedef_declaration)
|
13491
|
+
name = typedef_declaration.identifier.value
|
13492
|
+
type = typedef_declaration.type
|
13493
|
+
|
13494
|
+
same_name_object_decls = @object_decls_in_other_scope[name]
|
13495
|
+
unless same_name_object_decls.empty?
|
13496
|
+
W(:W0787, typedef_declaration.location, name)
|
13497
|
+
return
|
13498
|
+
end
|
13499
|
+
|
13500
|
+
same_name_typedef_decls = @typedef_decls_in_other_scope[name]
|
13501
|
+
unless same_name_typedef_decls.all? { |decl| decl.type == type }
|
13502
|
+
W(:W0787, typedef_declaration.location, name)
|
13503
|
+
return
|
13504
|
+
end
|
13505
|
+
|
13506
|
+
same_name_enumerators = @enumerators_in_other_scope[name]
|
13507
|
+
unless same_name_enumerators == 0
|
13508
|
+
W(:W0787, typedef_declaration.location, name)
|
13509
|
+
return
|
13510
|
+
end
|
13511
|
+
ensure
|
13512
|
+
unless @typedef_decls_stack.empty?
|
13513
|
+
@typedef_decls_stack.last[name].push(typedef_declaration)
|
13514
|
+
end
|
13515
|
+
end
|
13516
|
+
|
13517
|
+
def check_enum_declaration(enum_type_declaration)
|
13518
|
+
enum_type_declaration.enumerators.each { |enum| check_enumerator(enum) }
|
13519
|
+
end
|
13520
|
+
|
13521
|
+
def check_enumerator(enumerator)
|
13522
|
+
name = enumerator.identifier.value
|
13523
|
+
|
13524
|
+
same_name_object_decls = @object_decls_in_other_scope[name]
|
13525
|
+
unless same_name_object_decls.empty?
|
13526
|
+
W(:W0787, enumerator.location, name)
|
13527
|
+
return
|
13528
|
+
end
|
13529
|
+
|
13530
|
+
same_name_typedef_decls = @typedef_decls_in_other_scope[name]
|
13531
|
+
unless same_name_typedef_decls.empty?
|
13532
|
+
W(:W0787, enumerator.location, name)
|
13533
|
+
return
|
13534
|
+
end
|
13535
|
+
|
13536
|
+
same_name_enumerators = @enumerators_in_other_scope[name]
|
13537
|
+
unless same_name_enumerators == 0
|
13538
|
+
W(:W0787, enumerator.location, name)
|
13539
|
+
return
|
13540
|
+
end
|
13541
|
+
ensure
|
13542
|
+
unless @enumerators_stack.empty?
|
13543
|
+
@enumerators_stack.last[name] += 1
|
13544
|
+
end
|
13545
|
+
end
|
13546
|
+
|
13547
|
+
def start_block(compound_statement)
|
13548
|
+
@object_decls_stack.push(Hash.new { |hash, key| hash[key] = [] })
|
13549
|
+
@typedef_decls_stack.push(Hash.new { |hash, key| hash[key] = [] })
|
13550
|
+
@enumerators_stack.push(Hash.new(0))
|
13551
|
+
end
|
13552
|
+
|
13553
|
+
def end_block(compound_statement)
|
13554
|
+
unless @object_decls_stack.empty?
|
13555
|
+
@object_decls_stack.last.each do |name, decls|
|
13556
|
+
@object_decls_in_other_scope[name].concat(decls)
|
13557
|
+
end
|
13558
|
+
@object_decls_stack.pop
|
13559
|
+
end
|
13560
|
+
|
13561
|
+
unless @typedef_decls_stack.empty?
|
13562
|
+
@typedef_decls_stack.last.each do |name, decls|
|
13563
|
+
@typedef_decls_in_other_scope[name].concat(decls)
|
13564
|
+
end
|
13565
|
+
@typedef_decls_stack.pop
|
13566
|
+
end
|
13567
|
+
|
13568
|
+
unless @enumerators_stack.empty?
|
13569
|
+
@enumerators_stack.last.each do |name, decl_num|
|
13570
|
+
@enumerators_in_other_scope[name] += decl_num
|
13571
|
+
end
|
13572
|
+
end
|
13573
|
+
end
|
13574
|
+
end
|
13575
|
+
|
13576
|
+
class W0788 < PassiveMessageDetection
|
13577
|
+
def initialize(context)
|
13578
|
+
super
|
13579
|
+
interp = context[:c_interpreter]
|
13580
|
+
interp.on_variable_declared += method(:check_object_declaration)
|
13581
|
+
interp.on_variable_defined += method(:check_object_declaration)
|
13582
|
+
interp.on_function_declared += method(:check_object_declaration)
|
13583
|
+
interp.on_function_started += method(:check_object_declaration)
|
13584
|
+
interp.on_typedef_declared += method(:check_typedef_declaration)
|
13585
|
+
interp.on_enum_declared += method(:check_enum_declaration)
|
13586
|
+
interp.on_block_started += method(:start_block)
|
13587
|
+
interp.on_block_ended += method(:end_block)
|
13588
|
+
|
13589
|
+
@object_decls_stack = [Hash.new { |hash, key| hash[key] = [] }]
|
13590
|
+
@typedef_decls_stack = [Hash.new { |hash, key| hash[key] = [] }]
|
13591
|
+
@enumerators_stack = [Hash.new(0)]
|
13592
|
+
end
|
13593
|
+
|
13594
|
+
private
|
13595
|
+
def check_object_declaration(declaration_or_definition, *)
|
13596
|
+
name = declaration_or_definition.identifier.value
|
13597
|
+
type = declaration_or_definition.type
|
13598
|
+
|
13599
|
+
unless @object_decls_stack.empty?
|
13600
|
+
same_name_object_decls = @object_decls_stack.last[name]
|
13601
|
+
unless same_name_object_decls.all? { |decl| decl.type == type }
|
13602
|
+
W(:W0788, declaration_or_definition.location, name)
|
13603
|
+
return
|
13604
|
+
end
|
13605
|
+
end
|
13606
|
+
|
13607
|
+
unless @typedef_decls_stack.empty?
|
13608
|
+
same_name_typedef_decls = @typedef_decls_stack.last[name]
|
13609
|
+
unless same_name_typedef_decls.empty?
|
13610
|
+
W(:W0788, declaration_or_definition.location, name)
|
13611
|
+
return
|
13612
|
+
end
|
13613
|
+
end
|
13614
|
+
|
13615
|
+
unless @enumerators_stack.empty?
|
13616
|
+
same_name_enumerators = @enumerators_stack.last[name]
|
13617
|
+
unless same_name_enumerators == 0
|
13618
|
+
W(:W0788, declaration_or_definition.location, name)
|
13619
|
+
return
|
13620
|
+
end
|
13621
|
+
end
|
13622
|
+
ensure
|
13623
|
+
unless @object_decls_stack.empty?
|
13624
|
+
@object_decls_stack.last[name].push(declaration_or_definition)
|
13625
|
+
end
|
13626
|
+
end
|
13627
|
+
|
13628
|
+
def check_typedef_declaration(typedef_declaration)
|
13629
|
+
name = typedef_declaration.identifier.value
|
13630
|
+
type = typedef_declaration.type
|
13631
|
+
|
13632
|
+
unless @object_decls_stack.empty?
|
13633
|
+
same_name_object_decls = @object_decls_stack.last[name]
|
13634
|
+
unless same_name_object_decls.empty?
|
13635
|
+
W(:W0788, typedef_declaration.location, name)
|
13636
|
+
return
|
13637
|
+
end
|
13638
|
+
end
|
13639
|
+
|
13640
|
+
unless @typedef_decls_stack.empty?
|
13641
|
+
same_name_typedef_decls = @typedef_decls_stack.last[name]
|
13642
|
+
unless same_name_typedef_decls.all? { |decl| decl.type == type }
|
13643
|
+
W(:W0788, typedef_declaration.location, name)
|
13644
|
+
return
|
13645
|
+
end
|
13646
|
+
end
|
13647
|
+
|
13648
|
+
unless @enumerators_stack.empty?
|
13649
|
+
same_name_enumerators = @enumerators_stack.last[name]
|
13650
|
+
unless same_name_enumerators == 0
|
13651
|
+
W(:W0788, typedef_declaration.location, name)
|
13652
|
+
return
|
13653
|
+
end
|
13654
|
+
end
|
13655
|
+
ensure
|
13656
|
+
unless @typedef_decls_stack.empty?
|
13657
|
+
@typedef_decls_stack.last[name].push(typedef_declaration)
|
13658
|
+
end
|
13659
|
+
end
|
13660
|
+
|
13661
|
+
def check_enum_declaration(enum_type_declaration)
|
13662
|
+
enum_type_declaration.enumerators.each { |enum| check_enumerator(enum) }
|
13663
|
+
end
|
13664
|
+
|
13665
|
+
def check_enumerator(enumerator)
|
13666
|
+
name = enumerator.identifier.value
|
13667
|
+
|
13668
|
+
unless @object_decls_stack.empty?
|
13669
|
+
same_name_object_decls = @object_decls_stack.last[name]
|
13670
|
+
unless same_name_object_decls.empty?
|
13671
|
+
W(:W0788, enumerator.location, name)
|
13672
|
+
return
|
13673
|
+
end
|
13674
|
+
end
|
13675
|
+
|
13676
|
+
unless @typedef_decls_stack.empty?
|
13677
|
+
same_name_typedef_decls = @typedef_decls_stack.last[name]
|
13678
|
+
unless same_name_typedef_decls.empty?
|
13679
|
+
W(:W0788, enumerator.location, name)
|
13680
|
+
return
|
13681
|
+
end
|
13682
|
+
end
|
13683
|
+
|
13684
|
+
unless @enumerators_stack.empty?
|
13685
|
+
same_name_enumerators = @enumerators_stack.last[name]
|
13686
|
+
unless same_name_enumerators == 0
|
13687
|
+
W(:W0788, enumerator.location, name)
|
13688
|
+
return
|
13689
|
+
end
|
13690
|
+
end
|
13691
|
+
ensure
|
13692
|
+
unless @enumerators_stack.empty?
|
13693
|
+
@enumerators_stack.last[name] += 1
|
13694
|
+
end
|
13695
|
+
end
|
13696
|
+
|
13697
|
+
def start_block(compound_statement)
|
13698
|
+
@object_decls_stack.push(Hash.new { |hash, key| hash[key] = [] })
|
13699
|
+
@typedef_decls_stack.push(Hash.new { |hash, key| hash[key] = [] })
|
13700
|
+
@enumerators_stack.push(Hash.new(0))
|
13701
|
+
end
|
13702
|
+
|
13703
|
+
def end_block(compound_statement)
|
13704
|
+
@object_decls_stack.pop
|
13705
|
+
@typedef_decls_stack.pop
|
13706
|
+
@enumerators_stack.pop
|
13707
|
+
end
|
13708
|
+
end
|
13709
|
+
|
13710
|
+
class W0789 < PassiveMessageDetection
|
13711
|
+
def initialize(context)
|
13712
|
+
super
|
13713
|
+
interp = context[:c_interpreter]
|
13714
|
+
interp.on_variable_declared += method(:check_object_declaration)
|
13715
|
+
interp.on_variable_defined += method(:check_object_declaration)
|
13716
|
+
interp.on_function_declared += method(:check_object_declaration)
|
13717
|
+
interp.on_function_started += method(:check_object_declaration)
|
13718
|
+
interp.on_typedef_declared += method(:check_typedef_declaration)
|
13719
|
+
interp.on_enum_declared += method(:check_enum_declaration)
|
13720
|
+
interp.on_block_started += method(:start_block)
|
13721
|
+
interp.on_block_ended += method(:end_block)
|
13722
|
+
|
13723
|
+
@object_decls_stack = [Hash.new { |hash, key| hash[key] = [] }]
|
13724
|
+
@typedef_decls_stack = [Hash.new { |hash, key| hash[key] = [] }]
|
13725
|
+
@enumerators_stack = [Hash.new(0)]
|
13726
|
+
end
|
13727
|
+
|
13728
|
+
private
|
13729
|
+
def check_object_declaration(declaration_or_definition, *)
|
13730
|
+
name = declaration_or_definition.identifier.value
|
13731
|
+
type = declaration_or_definition.type
|
13732
|
+
|
13733
|
+
same_name_object_decls =
|
13734
|
+
merge_same_name_object_decls(name, @object_decls_stack[0..-2])
|
13735
|
+
unless same_name_object_decls.all? { |decl| decl.type == type }
|
13736
|
+
W(:W0789, declaration_or_definition.location, name)
|
13737
|
+
return
|
13738
|
+
end
|
13739
|
+
|
13740
|
+
same_name_typedef_decls =
|
13741
|
+
merge_same_name_typedef_decls(name, @typedef_decls_stack[0..-2])
|
13742
|
+
unless same_name_typedef_decls.empty?
|
13743
|
+
W(:W0789, declaration_or_definition.location, name)
|
13744
|
+
return
|
13745
|
+
end
|
13746
|
+
|
13747
|
+
same_name_enumerators =
|
13748
|
+
merge_same_name_enumerators(name, @enumerators_stack[0..-2])
|
13749
|
+
unless same_name_enumerators == 0
|
13750
|
+
W(:W0789, declaration_or_definition.location, name)
|
13751
|
+
return
|
13752
|
+
end
|
13753
|
+
ensure
|
13754
|
+
unless @object_decls_stack.empty?
|
13755
|
+
@object_decls_stack.last[name].push(declaration_or_definition)
|
13756
|
+
end
|
13757
|
+
end
|
13758
|
+
|
13759
|
+
def check_typedef_declaration(typedef_declaration)
|
13760
|
+
name = typedef_declaration.identifier.value
|
13761
|
+
type = typedef_declaration.type
|
13762
|
+
|
13763
|
+
same_name_object_decls =
|
13764
|
+
merge_same_name_object_decls(name, @object_decls_stack[0..-2])
|
13765
|
+
unless same_name_object_decls.empty?
|
13766
|
+
W(:W0789, typedef_declaration.location, name)
|
13767
|
+
return
|
13768
|
+
end
|
13769
|
+
|
13770
|
+
same_name_typedef_decls =
|
13771
|
+
merge_same_name_typedef_decls(name, @typedef_decls_stack[0..-2])
|
13772
|
+
unless same_name_typedef_decls.all? { |decl| decl.type == type }
|
13773
|
+
W(:W0789, typedef_declaration.location, name)
|
13774
|
+
return
|
13775
|
+
end
|
13776
|
+
|
13777
|
+
same_name_enumerators =
|
13778
|
+
merge_same_name_enumerators(name, @enumerators_stack[0..-2])
|
13779
|
+
unless same_name_enumerators == 0
|
13780
|
+
W(:W0789, typedef_declaration.location, name)
|
13781
|
+
return
|
13782
|
+
end
|
13783
|
+
ensure
|
13784
|
+
unless @typedef_decls_stack.empty?
|
13785
|
+
@typedef_decls_stack.last[name].push(typedef_declaration)
|
13786
|
+
end
|
13787
|
+
end
|
13788
|
+
|
13789
|
+
def check_enum_declaration(enum_type_declaration)
|
13790
|
+
enum_type_declaration.enumerators.each { |enum| check_enumerator(enum) }
|
13791
|
+
end
|
13792
|
+
|
13793
|
+
def check_enumerator(enumerator)
|
13794
|
+
name = enumerator.identifier.value
|
13795
|
+
|
13796
|
+
same_name_object_decls =
|
13797
|
+
merge_same_name_object_decls(name, @object_decls_stack[0..-2])
|
13798
|
+
unless same_name_object_decls.empty?
|
13799
|
+
W(:W0789, enumerator.location, name)
|
13800
|
+
return
|
13801
|
+
end
|
13802
|
+
|
13803
|
+
same_name_typedef_decls =
|
13804
|
+
merge_same_name_typedef_decls(name, @typedef_decls_stack[0..-2])
|
13805
|
+
unless same_name_typedef_decls.empty?
|
13806
|
+
W(:W0789, enumerator.location, name)
|
13807
|
+
return
|
13808
|
+
end
|
13809
|
+
|
13810
|
+
same_name_enumerators =
|
13811
|
+
merge_same_name_enumerators(name, @enumerators_stack[0..-2])
|
13812
|
+
unless same_name_enumerators == 0
|
13813
|
+
W(:W0789, enumerator.location, name)
|
13814
|
+
return
|
13815
|
+
end
|
13816
|
+
ensure
|
13817
|
+
unless @enumerators_stack.empty?
|
13818
|
+
@enumerators_stack.last[name] += 1
|
13819
|
+
end
|
13820
|
+
end
|
13821
|
+
|
13822
|
+
def start_block(compound_statement)
|
13823
|
+
@object_decls_stack.push(Hash.new { |hash, key| hash[key] = [] })
|
13824
|
+
@typedef_decls_stack.push(Hash.new { |hash, key| hash[key] = [] })
|
13825
|
+
@enumerators_stack.push(Hash.new(0))
|
13826
|
+
end
|
13827
|
+
|
13828
|
+
def end_block(compound_statement)
|
13829
|
+
@object_decls_stack.pop
|
13830
|
+
@typedef_decls_stack.pop
|
13831
|
+
@enumerators_stack.pop
|
13832
|
+
end
|
13833
|
+
|
13834
|
+
def merge_same_name_object_decls(name, scopes)
|
13835
|
+
scopes.each_with_object([]) { |hash, result| result.concat(hash[name]) }
|
13836
|
+
end
|
13837
|
+
|
13838
|
+
def merge_same_name_typedef_decls(name, scopes)
|
13839
|
+
scopes.each_with_object([]) { |hash, result| result.concat(hash[name]) }
|
13840
|
+
end
|
13841
|
+
|
13842
|
+
def merge_same_name_enumerators(name, scopes)
|
13843
|
+
scopes.reduce(0) { |result, hash| result + hash[name] }
|
13844
|
+
end
|
13845
|
+
end
|
13846
|
+
|
13341
13847
|
class W0790 < PassiveMessageDetection
|
13342
13848
|
def initialize(context)
|
13343
13849
|
super
|
@@ -14136,6 +14642,282 @@ module C #:nodoc:
|
|
14136
14642
|
end
|
14137
14643
|
end
|
14138
14644
|
|
14645
|
+
class W1053 < PassiveMessageDetection
|
14646
|
+
def initialize(context)
|
14647
|
+
super
|
14648
|
+
interp = context[:c_interpreter]
|
14649
|
+
interp.on_function_call_expr_evaled += method(:check)
|
14650
|
+
@enum_tbl = interp.environment.enumerator_table
|
14651
|
+
end
|
14652
|
+
|
14653
|
+
private
|
14654
|
+
def check(expression, function, arg_variables, result_variable)
|
14655
|
+
args = arg_variables.zip(function.type.parameter_types)
|
14656
|
+
args.each_with_index do |(arg_variable, param_type), index|
|
14657
|
+
next unless param_type && param_type.enum?
|
14658
|
+
|
14659
|
+
arg_expr = expression.argument_expressions[index]
|
14660
|
+
next unless arg_expr.constant?(@enum_tbl)
|
14661
|
+
|
14662
|
+
unless arg_variable.type.enum?
|
14663
|
+
W(:W1053, arg_expr.location)
|
14664
|
+
end
|
14665
|
+
end
|
14666
|
+
end
|
14667
|
+
end
|
14668
|
+
|
14669
|
+
class W1054 < PassiveMessageDetection
|
14670
|
+
def initialize(context)
|
14671
|
+
super
|
14672
|
+
interp = context[:c_interpreter]
|
14673
|
+
interp.on_assignment_expr_evaled += method(:check)
|
14674
|
+
end
|
14675
|
+
|
14676
|
+
private
|
14677
|
+
def check(expression, lhs_variable, rhs_variable)
|
14678
|
+
return unless lhs_variable.type.enum?
|
14679
|
+
W(:W1054, expression.location) unless rhs_variable.type.enum?
|
14680
|
+
end
|
14681
|
+
end
|
14682
|
+
|
14683
|
+
class W1055 < PassiveMessageDetection
|
14684
|
+
def initialize(context)
|
14685
|
+
super
|
14686
|
+
interp = context[:c_interpreter]
|
14687
|
+
interp.on_function_started += method(:start_function)
|
14688
|
+
interp.on_function_ended += method(:end_function)
|
14689
|
+
interp.on_return_stmt_evaled += method(:check)
|
14690
|
+
@current_function = nil
|
14691
|
+
end
|
14692
|
+
|
14693
|
+
private
|
14694
|
+
def start_function(function_definition)
|
14695
|
+
@current_function = function_definition
|
14696
|
+
end
|
14697
|
+
|
14698
|
+
def end_function(function_definition)
|
14699
|
+
@current_function = nil
|
14700
|
+
end
|
14701
|
+
|
14702
|
+
def check(return_statement, result_variable)
|
14703
|
+
return unless @current_function && result_variable
|
14704
|
+
|
14705
|
+
return unless return_type = @current_function.type.return_type
|
14706
|
+
return unless return_type.enum?
|
14707
|
+
|
14708
|
+
unless result_variable.type.enum?
|
14709
|
+
W(:W1055, return_statement.expression.location)
|
14710
|
+
end
|
14711
|
+
end
|
14712
|
+
end
|
14713
|
+
|
14714
|
+
class W1056 < PassiveMessageDetection
|
14715
|
+
def initialize(context)
|
14716
|
+
super
|
14717
|
+
interp = context[:c_interpreter]
|
14718
|
+
interp.on_function_call_expr_evaled += method(:check)
|
14719
|
+
@enum_tbl = interp.environment.enumerator_table
|
14720
|
+
end
|
14721
|
+
|
14722
|
+
private
|
14723
|
+
def check(expression, function, arg_variables, result_variable)
|
14724
|
+
args = arg_variables.zip(function.type.parameter_types)
|
14725
|
+
args.each_with_index do |(arg_variable, param_type), index|
|
14726
|
+
next unless param_type && param_type.enum?
|
14727
|
+
|
14728
|
+
arg_expr = expression.argument_expressions[index]
|
14729
|
+
next if arg_expr.constant?(@enum_tbl)
|
14730
|
+
|
14731
|
+
if arg_variable.type.enum?
|
14732
|
+
unless arg_variable.type.same_as?(param_type)
|
14733
|
+
W(:W1056, arg_expr.location)
|
14734
|
+
end
|
14735
|
+
end
|
14736
|
+
end
|
14737
|
+
end
|
14738
|
+
end
|
14739
|
+
|
14740
|
+
class W1057 < PassiveMessageDetection
|
14741
|
+
def initialize(context)
|
14742
|
+
super
|
14743
|
+
interp = context[:c_interpreter]
|
14744
|
+
interp.on_assignment_expr_evaled += method(:check)
|
14745
|
+
@enum_tbl = interp.environment.enumerator_table
|
14746
|
+
end
|
14747
|
+
|
14748
|
+
private
|
14749
|
+
def check(expression, lhs_variable, rhs_variable)
|
14750
|
+
return unless lhs_variable.type.enum?
|
14751
|
+
return if expression.rhs_operand.constant?(@enum_tbl)
|
14752
|
+
|
14753
|
+
if rhs_variable.type.enum?
|
14754
|
+
unless lhs_variable.type.same_as?(rhs_variable.type)
|
14755
|
+
W(:W1057, expression.location)
|
14756
|
+
end
|
14757
|
+
end
|
14758
|
+
end
|
14759
|
+
end
|
14760
|
+
|
14761
|
+
class W1058 < PassiveMessageDetection
|
14762
|
+
def initialize(context)
|
14763
|
+
super
|
14764
|
+
interp = context[:c_interpreter]
|
14765
|
+
interp.on_function_started += method(:start_function)
|
14766
|
+
interp.on_function_ended += method(:end_function)
|
14767
|
+
interp.on_return_stmt_evaled += method(:check)
|
14768
|
+
@enum_tbl = interp.environment.enumerator_table
|
14769
|
+
@current_function = nil
|
14770
|
+
end
|
14771
|
+
|
14772
|
+
private
|
14773
|
+
def start_function(function_definition)
|
14774
|
+
@current_function = function_definition
|
14775
|
+
end
|
14776
|
+
|
14777
|
+
def end_function(function_definition)
|
14778
|
+
@current_function = nil
|
14779
|
+
end
|
14780
|
+
|
14781
|
+
def check(return_statement, result_variable)
|
14782
|
+
return unless @current_function && result_variable
|
14783
|
+
|
14784
|
+
return unless return_type = @current_function.type.return_type
|
14785
|
+
return unless return_type.enum?
|
14786
|
+
return if return_statement.expression.constant?(@enum_tbl)
|
14787
|
+
|
14788
|
+
if result_variable.type.enum?
|
14789
|
+
unless return_type.same_as?(result_variable.type)
|
14790
|
+
W(:W1058, return_statement.expression.location)
|
14791
|
+
end
|
14792
|
+
end
|
14793
|
+
end
|
14794
|
+
end
|
14795
|
+
|
14796
|
+
class W1059 < PassiveMessageDetection
|
14797
|
+
def initialize(context)
|
14798
|
+
super
|
14799
|
+
interp = context[:c_interpreter]
|
14800
|
+
interp.on_function_call_expr_evaled += method(:check)
|
14801
|
+
@enum_tbl = interp.environment.enumerator_table
|
14802
|
+
end
|
14803
|
+
|
14804
|
+
private
|
14805
|
+
def check(expression, function, arg_variables, result_variable)
|
14806
|
+
args = arg_variables.zip(function.type.parameter_types)
|
14807
|
+
args.each_with_index do |(arg_variable, param_type), index|
|
14808
|
+
next if param_type.nil? || param_type.enum?
|
14809
|
+
|
14810
|
+
if arg_variable.type.enum?
|
14811
|
+
W(:W1059, expression.argument_expressions[index].location)
|
14812
|
+
end
|
14813
|
+
end
|
14814
|
+
end
|
14815
|
+
end
|
14816
|
+
|
14817
|
+
class W1060 < PassiveMessageDetection
|
14818
|
+
def initialize(context)
|
14819
|
+
super
|
14820
|
+
interp = context[:c_interpreter]
|
14821
|
+
interp.on_function_started += method(:start_function)
|
14822
|
+
interp.on_function_ended += method(:end_function)
|
14823
|
+
interp.on_return_stmt_evaled += method(:check)
|
14824
|
+
@enum_tbl = interp.environment.enumerator_table
|
14825
|
+
@current_function = nil
|
14826
|
+
end
|
14827
|
+
|
14828
|
+
private
|
14829
|
+
def start_function(function_definition)
|
14830
|
+
@current_function = function_definition
|
14831
|
+
end
|
14832
|
+
|
14833
|
+
def end_function(function_definition)
|
14834
|
+
@current_function = nil
|
14835
|
+
end
|
14836
|
+
|
14837
|
+
def check(return_statement, result_variable)
|
14838
|
+
return unless @current_function && result_variable
|
14839
|
+
|
14840
|
+
return unless return_type = @current_function.type.return_type
|
14841
|
+
return if return_type.enum?
|
14842
|
+
|
14843
|
+
if result_variable.type.enum?
|
14844
|
+
W(:W1060, return_statement.expression.location)
|
14845
|
+
end
|
14846
|
+
end
|
14847
|
+
end
|
14848
|
+
|
14849
|
+
class W1061 < PassiveMessageDetection
|
14850
|
+
def initialize(context)
|
14851
|
+
super
|
14852
|
+
interp = context[:c_interpreter]
|
14853
|
+
interp.on_function_call_expr_evaled += method(:check)
|
14854
|
+
@enum_tbl = interp.environment.enumerator_table
|
14855
|
+
end
|
14856
|
+
|
14857
|
+
private
|
14858
|
+
def check(expression, function, arg_variables, result_variable)
|
14859
|
+
args = arg_variables.zip(function.type.parameter_types)
|
14860
|
+
args.each_with_index do |(arg_variable, param_type), index|
|
14861
|
+
next unless param_type && param_type.enum?
|
14862
|
+
|
14863
|
+
arg_expr = expression.argument_expressions[index]
|
14864
|
+
next if arg_expr.constant?(@enum_tbl)
|
14865
|
+
|
14866
|
+
W(:W1061, arg_expr.location) unless arg_variable.type.enum?
|
14867
|
+
end
|
14868
|
+
end
|
14869
|
+
end
|
14870
|
+
|
14871
|
+
class W1062 < PassiveMessageDetection
|
14872
|
+
def initialize(context)
|
14873
|
+
super
|
14874
|
+
interp = context[:c_interpreter]
|
14875
|
+
interp.on_assignment_expr_evaled += method(:check)
|
14876
|
+
@enum_tbl = interp.environment.enumerator_table
|
14877
|
+
end
|
14878
|
+
|
14879
|
+
private
|
14880
|
+
def check(expression, lhs_variable, rhs_variable)
|
14881
|
+
return unless lhs_variable.type.enum?
|
14882
|
+
return if expression.rhs_operand.constant?(@enum_tbl)
|
14883
|
+
|
14884
|
+
W(:W1062, expression.location) unless rhs_variable.type.enum?
|
14885
|
+
end
|
14886
|
+
end
|
14887
|
+
|
14888
|
+
class W1063 < PassiveMessageDetection
|
14889
|
+
def initialize(context)
|
14890
|
+
super
|
14891
|
+
interp = context[:c_interpreter]
|
14892
|
+
interp.on_function_started += method(:start_function)
|
14893
|
+
interp.on_function_ended += method(:end_function)
|
14894
|
+
interp.on_return_stmt_evaled += method(:check)
|
14895
|
+
@enum_tbl = interp.environment.enumerator_table
|
14896
|
+
@current_function = nil
|
14897
|
+
end
|
14898
|
+
|
14899
|
+
private
|
14900
|
+
def start_function(function_definition)
|
14901
|
+
@current_function = function_definition
|
14902
|
+
end
|
14903
|
+
|
14904
|
+
def end_function(function_definition)
|
14905
|
+
@current_function = nil
|
14906
|
+
end
|
14907
|
+
|
14908
|
+
def check(return_statement, result_variable)
|
14909
|
+
return unless @current_function && result_variable
|
14910
|
+
|
14911
|
+
return unless return_type = @current_function.type.return_type
|
14912
|
+
return unless return_type.enum?
|
14913
|
+
return if return_statement.expression.constant?(@enum_tbl)
|
14914
|
+
|
14915
|
+
unless result_variable.type.enum?
|
14916
|
+
W(:W1063, return_statement.expression.location)
|
14917
|
+
end
|
14918
|
+
end
|
14919
|
+
end
|
14920
|
+
|
14139
14921
|
class W1064 < W0731
|
14140
14922
|
private
|
14141
14923
|
def check(case_labeled_statement, ctrlexpr_result)
|