adlint 1.4.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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)
|