adlint 1.8.2 → 1.8.10
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 +192 -0
- data/MANIFEST +1 -0
- data/NEWS +40 -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/code.rb +88 -124
- data/lib/adlint/c/conv.rb +4 -4
- data/lib/adlint/c/ctrlexpr.rb +8 -2
- data/lib/adlint/c/domain.rb +405 -5
- data/lib/adlint/c/format.rb +6 -6
- data/lib/adlint/c/message.rb +227 -350
- data/lib/adlint/c/message_shima.rb +1 -2
- data/lib/adlint/c/object.rb +1 -1
- data/lib/adlint/c/type.rb +43 -1
- data/lib/adlint/cpp/util.rb +29 -0
- data/lib/adlint/version.rb +2 -2
- data/share/demo/Makefile +1 -0
- data/share/demo/integer_promotion/integer_promotion.c +17 -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 +3 -3
- data/share/doc/users_guide_en.texi +1 -1
- data/share/doc/users_guide_ja.html +3 -3
- data/share/doc/users_guide_ja.texi +1 -1
- metadata +3 -2
data/lib/adlint/c/format.rb
CHANGED
@@ -765,15 +765,15 @@ module C #:nodoc:
|
|
765
765
|
# Boolean -- True if types of arguments match this directive.
|
766
766
|
def acceptable?
|
767
767
|
if @field_width_argument
|
768
|
-
unless @field_width_argument.type
|
769
|
-
@field_width_argument.type
|
768
|
+
unless signed_int_type.same_as?(@field_width_argument.type) ||
|
769
|
+
unsigned_int_type.same_as?(@field_width_argument.type)
|
770
770
|
return false
|
771
771
|
end
|
772
772
|
end
|
773
773
|
|
774
774
|
if @precision_argument
|
775
|
-
unless @precision_argument.type
|
776
|
-
@precision_argument.type
|
775
|
+
unless signed_int_type.same_as?(@precision_argument.type) ||
|
776
|
+
unsigned_int_type.same_as?(@precision_argument.type)
|
777
777
|
return false
|
778
778
|
end
|
779
779
|
end
|
@@ -781,7 +781,7 @@ module C #:nodoc:
|
|
781
781
|
if @conversion_argument
|
782
782
|
if argument_types
|
783
783
|
argument_types.any? do |arg_type|
|
784
|
-
@conversion_argument.type
|
784
|
+
arg_type.same_as?(@conversion_argument.type)
|
785
785
|
end
|
786
786
|
else
|
787
787
|
true
|
@@ -2502,7 +2502,7 @@ module C #:nodoc:
|
|
2502
2502
|
if @conversion_argument
|
2503
2503
|
if argument_types
|
2504
2504
|
argument_types.any? do |arg_type|
|
2505
|
-
@conversion_argument.type
|
2505
|
+
arg_type.same_as?(@conversion_argument.type)
|
2506
2506
|
end
|
2507
2507
|
else
|
2508
2508
|
true
|
data/lib/adlint/c/message.rb
CHANGED
@@ -1156,72 +1156,31 @@ module C #:nodoc:
|
|
1156
1156
|
class W0051 < PassiveMessageDetection
|
1157
1157
|
def initialize(context)
|
1158
1158
|
super
|
1159
|
-
|
1160
|
-
|
1161
|
-
|
1162
|
-
|
1163
|
-
|
1164
|
-
|
1165
|
-
visitor.enter_ansi_function_definition += method(:add_function_def)
|
1166
|
-
visitor.enter_kandr_function_definition += method(:add_function_def)
|
1167
|
-
visitor.leave_translation_unit += method(:check)
|
1168
|
-
@block_level = 0
|
1159
|
+
interp = context[:c_interpreter]
|
1160
|
+
interp.on_variable_declared += method(:add_variable)
|
1161
|
+
interp.on_variable_defined += method(:add_variable)
|
1162
|
+
interp.on_function_declared += method(:add_function)
|
1163
|
+
interp.on_function_started += method(:add_function)
|
1164
|
+
interp.on_translation_unit_ended += method(:check)
|
1169
1165
|
@identifiers = Hash.new { |hash, key| hash[key] = [] }
|
1170
1166
|
end
|
1171
1167
|
|
1172
1168
|
private
|
1173
|
-
def
|
1174
|
-
|
1175
|
-
|
1176
|
-
|
1177
|
-
def leave_compound_statement(node)
|
1178
|
-
@block_level -= 1
|
1179
|
-
end
|
1180
|
-
|
1181
|
-
def add_variable_decl(node)
|
1182
|
-
if @block_level == 0 && node.storage_class_specifier &&
|
1183
|
-
node.storage_class_specifier.type == :EXTERN
|
1184
|
-
@identifiers[mangle(node.identifier.value)].push(
|
1185
|
-
[node.identifier, true])
|
1186
|
-
else
|
1187
|
-
@identifiers[mangle(node.identifier.value)].push(
|
1188
|
-
[node.identifier, false])
|
1189
|
-
end
|
1190
|
-
end
|
1191
|
-
|
1192
|
-
def add_variable_def(node)
|
1193
|
-
if @block_level == 0 && node.storage_class_specifier.nil?
|
1194
|
-
@identifiers[mangle(node.identifier.value)].push(
|
1195
|
-
[node.identifier, true])
|
1196
|
-
else
|
1197
|
-
@identifiers[mangle(node.identifier.value)].push(
|
1198
|
-
[node.identifier, false])
|
1199
|
-
end
|
1200
|
-
end
|
1201
|
-
|
1202
|
-
def add_function_decl(node)
|
1203
|
-
if node.storage_class_specifier.nil? ||
|
1204
|
-
node.storage_class_specifier.type == :EXTERN
|
1205
|
-
@identifiers[mangle(node.identifier.value)].push(
|
1206
|
-
[node.identifier, true])
|
1207
|
-
else
|
1208
|
-
@identifiers[mangle(node.identifier.value)].push(
|
1209
|
-
[node.identifier, false])
|
1169
|
+
def add_variable(decl_or_def, variable)
|
1170
|
+
if variable.named?
|
1171
|
+
@identifiers[mangle(variable.name)].push(
|
1172
|
+
[decl_or_def.identifier, variable.declared_as_extern?])
|
1210
1173
|
end
|
1211
1174
|
end
|
1212
1175
|
|
1213
|
-
def
|
1214
|
-
if
|
1215
|
-
|
1216
|
-
|
1217
|
-
[node.identifier, true])
|
1218
|
-
else
|
1219
|
-
@identifiers[mangle(node.identifier.value)].push(
|
1220
|
-
[node.identifier, false])
|
1176
|
+
def add_function(decl_or_def, function)
|
1177
|
+
if function.named?
|
1178
|
+
@identifiers[mangle(function.name)].push(
|
1179
|
+
[decl_or_def.identifier, function.declared_as_extern?])
|
1221
1180
|
end
|
1222
1181
|
end
|
1223
1182
|
|
1224
|
-
def check(
|
1183
|
+
def check(*)
|
1225
1184
|
@identifiers.each do |key, id_array|
|
1226
1185
|
id_array.uniq! { |id| id[0].value }
|
1227
1186
|
if id_array.size > 1
|
@@ -1578,30 +1537,29 @@ module C #:nodoc:
|
|
1578
1537
|
class W0080 < PassiveMessageDetection
|
1579
1538
|
def initialize(context)
|
1580
1539
|
super
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1540
|
+
interp = context[:c_interpreter]
|
1541
|
+
interp.on_variable_defined += method(:check)
|
1542
|
+
interp.on_block_started += method(:enter_block)
|
1543
|
+
interp.on_block_ended += method(:leave_block)
|
1585
1544
|
@block_level = 0
|
1586
1545
|
end
|
1587
1546
|
|
1588
1547
|
private
|
1589
|
-
def check(
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
W(:W0080, node.location) unless node.initializer
|
1548
|
+
def check(variable_definition, variable)
|
1549
|
+
if @block_level == 0
|
1550
|
+
if variable.declared_as_extern? || variable.declared_as_static?
|
1551
|
+
if variable.type.const? && variable_definition.initializer.nil?
|
1552
|
+
W(:W0080, variable_definition.location)
|
1553
|
+
end
|
1554
|
+
end
|
1597
1555
|
end
|
1598
1556
|
end
|
1599
1557
|
|
1600
|
-
def enter_block(
|
1558
|
+
def enter_block(*)
|
1601
1559
|
@block_level += 1
|
1602
1560
|
end
|
1603
1561
|
|
1604
|
-
def leave_block(
|
1562
|
+
def leave_block(*)
|
1605
1563
|
@block_level -= 1
|
1606
1564
|
end
|
1607
1565
|
end
|
@@ -1916,8 +1874,13 @@ module C #:nodoc:
|
|
1916
1874
|
return unless lhs_variable.type.pointer? && rhs_variable.type.pointer?
|
1917
1875
|
|
1918
1876
|
if rhs_pointee = @interp.pointee_of(rhs_variable)
|
1919
|
-
if rhs_pointee.variable? && rhs_pointee.named?
|
1920
|
-
|
1877
|
+
if rhs_pointee.variable? && rhs_pointee.named?
|
1878
|
+
return unless rhs_pointee.binding.memory.dynamic?
|
1879
|
+
# NOTE: An array typed parameter can be considerd as an alias of the
|
1880
|
+
# corresponding argument. So, it is safe to return an address
|
1881
|
+
# of the argument.
|
1882
|
+
return if rhs_pointee.type.parameter? && rhs_pointee.type.array?
|
1883
|
+
|
1921
1884
|
case
|
1922
1885
|
when lhs_variable.binding.memory.static?
|
1923
1886
|
W(:W0101, assignment_expression.location)
|
@@ -1978,8 +1941,12 @@ module C #:nodoc:
|
|
1978
1941
|
end
|
1979
1942
|
|
1980
1943
|
if rhs_pointee = @interp.pointee_of(rhs_variable)
|
1981
|
-
if rhs_pointee.variable? && rhs_pointee.named?
|
1982
|
-
|
1944
|
+
if rhs_pointee.variable? && rhs_pointee.named?
|
1945
|
+
return unless rhs_pointee.binding.memory.dynamic?
|
1946
|
+
# NOTE: An array typed parameter can be considerd as an alias of the
|
1947
|
+
# corresponding argument. So, it is safe to return an address
|
1948
|
+
# of the argument.
|
1949
|
+
return if rhs_pointee.type.parameter? && rhs_pointee.type.array?
|
1983
1950
|
W(:W0102, assignment_expression.location)
|
1984
1951
|
end
|
1985
1952
|
end
|
@@ -2022,6 +1989,10 @@ module C #:nodoc:
|
|
2022
1989
|
|
2023
1990
|
if pointee = @interp.pointee_of(result_variable)
|
2024
1991
|
if pointee.variable? && pointee.named?
|
1992
|
+
# NOTE: An array typed parameter can be considerd as an alias of the
|
1993
|
+
# corresponding argument. So, it is safe to return an address
|
1994
|
+
# of the argument.
|
1995
|
+
return if pointee.type.parameter? && pointee.type.array?
|
2025
1996
|
if @local_variables.include?(pointee.name)
|
2026
1997
|
W(:W0103, return_statement.location)
|
2027
1998
|
end
|
@@ -2161,9 +2132,13 @@ module C #:nodoc:
|
|
2161
2132
|
|
2162
2133
|
if rhs_pointee = @interp.pointee_of(rhs_variable)
|
2163
2134
|
if rhs_pointee.variable? && rhs_pointee.named?
|
2164
|
-
|
2165
|
-
|
2166
|
-
|
2135
|
+
return unless rhs_pointee.binding.memory.dynamic?
|
2136
|
+
# NOTE: An array typed parameter can be considerd as an alias of the
|
2137
|
+
# corresponding argument. So, it is safe to return an address
|
2138
|
+
# of the argument.
|
2139
|
+
return if rhs_pointee.type.parameter? && rhs_pointee.type.array?
|
2140
|
+
|
2141
|
+
if lhs_variable.scope.local? && lhs_variable.binding.memory.static?
|
2167
2142
|
W(:W0107, assignment_expression.location)
|
2168
2143
|
end
|
2169
2144
|
end
|
@@ -2515,114 +2490,85 @@ module C #:nodoc:
|
|
2515
2490
|
class W0117 < PassiveMessageDetection
|
2516
2491
|
def initialize(context)
|
2517
2492
|
super
|
2518
|
-
|
2519
|
-
|
2520
|
-
|
2521
|
-
|
2522
|
-
|
2523
|
-
visitor.enter_variable_definition += method(:check_variable)
|
2524
|
-
visitor.enter_compound_statement += method(:enter_block)
|
2525
|
-
visitor.leave_compound_statement += method(:leave_block)
|
2493
|
+
interp = context[:c_interpreter]
|
2494
|
+
interp.on_function_declared += method(:declare_function)
|
2495
|
+
interp.on_variable_declared += method(:declare_variable)
|
2496
|
+
interp.on_function_started += method(:check_function)
|
2497
|
+
interp.on_variable_defined += method(:check_variable)
|
2526
2498
|
@target_fpath = context[:sources].first.fpath
|
2527
2499
|
@external_symbols = Set.new
|
2528
|
-
@scope_depth = 0
|
2529
2500
|
end
|
2530
2501
|
|
2531
2502
|
private
|
2532
|
-
def declare_function(
|
2533
|
-
if
|
2534
|
-
|
2535
|
-
@external_symbols.add(node.identifier.value)
|
2536
|
-
end
|
2503
|
+
def declare_function(function_declaration, function)
|
2504
|
+
if function.named? && function.declared_as_extern?
|
2505
|
+
@external_symbols.add(function.name)
|
2537
2506
|
end
|
2538
2507
|
end
|
2539
2508
|
|
2540
|
-
def declare_variable(
|
2541
|
-
if
|
2542
|
-
|
2543
|
-
@external_symbols.add(node.identifier.value)
|
2544
|
-
end
|
2509
|
+
def declare_variable(variable_declaration, variable)
|
2510
|
+
if variable.named? && variable.declared_as_extern?
|
2511
|
+
@external_symbols.add(variable.name)
|
2545
2512
|
end
|
2546
2513
|
end
|
2547
2514
|
|
2548
|
-
def check_function(
|
2549
|
-
|
2550
|
-
|
2551
|
-
|
2552
|
-
|
2553
|
-
|
2515
|
+
def check_function(function_definition, function)
|
2516
|
+
if function.named? && function.declared_as_extern?
|
2517
|
+
return if function.name == "main"
|
2518
|
+
|
2519
|
+
unless @external_symbols.include?(function.name)
|
2520
|
+
if function_definition.location.fpath == @target_fpath
|
2521
|
+
W(:W0117, function_definition.location, function.name)
|
2554
2522
|
end
|
2555
2523
|
end
|
2556
2524
|
end
|
2557
2525
|
end
|
2558
2526
|
|
2559
|
-
def check_variable(
|
2560
|
-
if
|
2561
|
-
unless @external_symbols.include?(
|
2562
|
-
if
|
2563
|
-
W(:W0117,
|
2527
|
+
def check_variable(variable_definition, variable)
|
2528
|
+
if variable.named? && variable.declared_as_extern?
|
2529
|
+
unless @external_symbols.include?(variable.name)
|
2530
|
+
if variable_definition.location.fpath == @target_fpath
|
2531
|
+
W(:W0117, variable_definition.location, variable.name)
|
2564
2532
|
end
|
2565
2533
|
end
|
2566
2534
|
end
|
2567
2535
|
end
|
2568
|
-
|
2569
|
-
def enter_block(node)
|
2570
|
-
@scope_depth += 1
|
2571
|
-
end
|
2572
|
-
|
2573
|
-
def leave_block(node)
|
2574
|
-
@scope_depth -= 1
|
2575
|
-
end
|
2576
|
-
|
2577
|
-
def external_declaration?(node)
|
2578
|
-
node.storage_class_specifier &&
|
2579
|
-
node.storage_class_specifier.type == :EXTERN
|
2580
|
-
end
|
2581
|
-
|
2582
|
-
def external_definition?(node)
|
2583
|
-
(@scope_depth == 0 && node.storage_class_specifier.nil?) ||
|
2584
|
-
(node.storage_class_specifier &&
|
2585
|
-
node.storage_class_specifier.type == :EXTERN)
|
2586
|
-
end
|
2587
2536
|
end
|
2588
2537
|
|
2589
2538
|
class W0118 < PassiveMessageDetection
|
2590
2539
|
def initialize(context)
|
2591
2540
|
super
|
2592
|
-
|
2593
|
-
|
2594
|
-
|
2541
|
+
interp = context[:c_interpreter]
|
2542
|
+
interp.on_function_declared += method(:check_function)
|
2543
|
+
interp.on_variable_declared += method(:check_variable)
|
2595
2544
|
@target_fpath = context[:sources].first.fpath
|
2596
2545
|
@external_symbols = Set.new
|
2597
2546
|
end
|
2598
2547
|
|
2599
2548
|
private
|
2600
|
-
def check_function(
|
2601
|
-
if
|
2602
|
-
unless @external_symbols.include?(
|
2603
|
-
if
|
2604
|
-
W(:W0118,
|
2549
|
+
def check_function(function_declaration, function)
|
2550
|
+
if function.named? && function.declared_as_extern?
|
2551
|
+
unless @external_symbols.include?(function.name)
|
2552
|
+
if function_declaration.location.fpath == @target_fpath
|
2553
|
+
W(:W0118, function_declaration.location, function.name)
|
2554
|
+
else
|
2555
|
+
@external_symbols.add(function.name)
|
2605
2556
|
end
|
2606
|
-
@external_symbols.add(node.identifier.value)
|
2607
2557
|
end
|
2608
2558
|
end
|
2609
2559
|
end
|
2610
2560
|
|
2611
|
-
def check_variable(
|
2612
|
-
if
|
2613
|
-
unless @external_symbols.include?(
|
2614
|
-
if
|
2615
|
-
W(:W0118,
|
2561
|
+
def check_variable(variable_declaration, variable)
|
2562
|
+
if variable.named? && variable.declared_as_extern?
|
2563
|
+
unless @external_symbols.include?(variable.name)
|
2564
|
+
if variable_declaration.location.fpath == @target_fpath
|
2565
|
+
W(:W0118, variable_declaration.location, variable.name)
|
2566
|
+
else
|
2567
|
+
@external_symbols.add(variable.name)
|
2616
2568
|
end
|
2617
|
-
@external_symbols.add(node.identifier.value)
|
2618
2569
|
end
|
2619
2570
|
end
|
2620
2571
|
end
|
2621
|
-
|
2622
|
-
def external?(node)
|
2623
|
-
node.storage_class_specifier &&
|
2624
|
-
node.storage_class_specifier.type == :EXTERN
|
2625
|
-
end
|
2626
2572
|
end
|
2627
2573
|
|
2628
2574
|
class W0119 < PassiveMessageDetection
|
@@ -6920,42 +6866,28 @@ module C #:nodoc:
|
|
6920
6866
|
class W0456 < PassiveMessageDetection
|
6921
6867
|
def initialize(context)
|
6922
6868
|
super
|
6923
|
-
|
6924
|
-
|
6925
|
-
|
6926
|
-
visitor.enter_kandr_function_definition += method(:check_function)
|
6927
|
-
visitor.enter_compound_statement += method(:enter_block)
|
6928
|
-
visitor.leave_compound_statement += method(:leave_block)
|
6869
|
+
interp = context[:c_interpreter]
|
6870
|
+
interp.on_variable_defined += method(:check_variable)
|
6871
|
+
interp.on_function_started += method(:check_function)
|
6929
6872
|
@target_fpath = context[:sources].first.fpath
|
6930
|
-
@scope_depth = 0
|
6931
6873
|
end
|
6932
6874
|
|
6933
6875
|
private
|
6934
|
-
def check_variable(
|
6935
|
-
if
|
6936
|
-
|
6876
|
+
def check_variable(variable_definition, variable)
|
6877
|
+
if variable.declared_as_extern?
|
6878
|
+
unless variable_definition.location.fpath == @target_fpath
|
6879
|
+
W(:W0456, variable_definition.location, variable.name)
|
6880
|
+
end
|
6937
6881
|
end
|
6938
6882
|
end
|
6939
6883
|
|
6940
|
-
def check_function(
|
6941
|
-
if
|
6942
|
-
|
6884
|
+
def check_function(function_definition, function)
|
6885
|
+
if function.declared_as_extern?
|
6886
|
+
unless function_definition.location.fpath == @target_fpath
|
6887
|
+
W(:W0456, function_definition.location, function.name)
|
6888
|
+
end
|
6943
6889
|
end
|
6944
6890
|
end
|
6945
|
-
|
6946
|
-
def enter_block(node)
|
6947
|
-
@scope_depth += 1
|
6948
|
-
end
|
6949
|
-
|
6950
|
-
def leave_block(node)
|
6951
|
-
@scope_depth -= 1
|
6952
|
-
end
|
6953
|
-
|
6954
|
-
def external?(node)
|
6955
|
-
(@scope_depth == 0 && node.storage_class_specifier.nil?) ||
|
6956
|
-
(node.storage_class_specifier &&
|
6957
|
-
node.storage_class_specifier.type == :EXTERN)
|
6958
|
-
end
|
6959
6891
|
end
|
6960
6892
|
|
6961
6893
|
class W0457 < PassiveMessageDetection
|
@@ -11109,62 +11041,52 @@ module C #:nodoc:
|
|
11109
11041
|
class W0622 < PassiveMessageDetection
|
11110
11042
|
def initialize(context)
|
11111
11043
|
super
|
11112
|
-
|
11113
|
-
|
11114
|
-
|
11115
|
-
|
11116
|
-
@
|
11044
|
+
interp = context[:c_interpreter]
|
11045
|
+
interp.on_function_declared += method(:check)
|
11046
|
+
interp.on_block_started += method(:enter_block)
|
11047
|
+
interp.on_block_ended += method(:leave_block)
|
11048
|
+
@block_level = 0
|
11117
11049
|
end
|
11118
11050
|
|
11119
11051
|
private
|
11120
|
-
def check(function_declaration)
|
11121
|
-
if @
|
11052
|
+
def check(function_declaration, function)
|
11053
|
+
if @block_level > 0 && function.declared_as_extern?
|
11122
11054
|
W(:W0622, function_declaration.location)
|
11123
11055
|
end
|
11124
11056
|
end
|
11125
11057
|
|
11126
|
-
def enter_block(
|
11127
|
-
@
|
11128
|
-
end
|
11129
|
-
|
11130
|
-
def leave_block(node)
|
11131
|
-
@block_depth -= 1
|
11058
|
+
def enter_block(*)
|
11059
|
+
@block_level += 1
|
11132
11060
|
end
|
11133
11061
|
|
11134
|
-
def
|
11135
|
-
|
11136
|
-
node.storage_class_specifier.type == :EXTERN
|
11062
|
+
def leave_block(*)
|
11063
|
+
@block_level -= 1
|
11137
11064
|
end
|
11138
11065
|
end
|
11139
11066
|
|
11140
11067
|
class W0623 < PassiveMessageDetection
|
11141
11068
|
def initialize(context)
|
11142
11069
|
super
|
11143
|
-
|
11144
|
-
|
11145
|
-
|
11146
|
-
|
11147
|
-
@
|
11070
|
+
interp = context[:c_interpreter]
|
11071
|
+
interp.on_variable_declared += method(:check)
|
11072
|
+
interp.on_block_started += method(:enter_block)
|
11073
|
+
interp.on_block_ended += method(:leave_block)
|
11074
|
+
@block_level = 0
|
11148
11075
|
end
|
11149
11076
|
|
11150
11077
|
private
|
11151
|
-
def check(variable_declaration)
|
11152
|
-
if @
|
11078
|
+
def check(variable_declaration, variable)
|
11079
|
+
if @block_level > 0 && variable.declared_as_extern?
|
11153
11080
|
W(:W0623, variable_declaration.location)
|
11154
11081
|
end
|
11155
11082
|
end
|
11156
11083
|
|
11157
|
-
def enter_block(
|
11158
|
-
@
|
11159
|
-
end
|
11160
|
-
|
11161
|
-
def leave_block(node)
|
11162
|
-
@block_depth -= 1
|
11084
|
+
def enter_block(*)
|
11085
|
+
@block_level += 1
|
11163
11086
|
end
|
11164
11087
|
|
11165
|
-
def
|
11166
|
-
|
11167
|
-
node.storage_class_specifier.type == :EXTERN
|
11088
|
+
def leave_block(*)
|
11089
|
+
@block_level -= 1
|
11168
11090
|
end
|
11169
11091
|
end
|
11170
11092
|
|
@@ -12805,10 +12727,8 @@ module C #:nodoc:
|
|
12805
12727
|
def define_variable(variable_definition, variable)
|
12806
12728
|
return unless @functions.empty?
|
12807
12729
|
|
12808
|
-
if
|
12809
|
-
|
12810
|
-
@static_variables[variable] = [variable_definition, Set.new]
|
12811
|
-
end
|
12730
|
+
if variable.declared_as_static?
|
12731
|
+
@static_variables[variable] = [variable_definition, Set.new]
|
12812
12732
|
end
|
12813
12733
|
end
|
12814
12734
|
|
@@ -13381,42 +13301,46 @@ module C #:nodoc:
|
|
13381
13301
|
class W0771 < PassiveMessageDetection
|
13382
13302
|
def initialize(context)
|
13383
13303
|
super
|
13384
|
-
|
13385
|
-
|
13386
|
-
|
13387
|
-
|
13304
|
+
interp = context[:c_interpreter]
|
13305
|
+
interp.on_variable_declared += method(:declare_variable)
|
13306
|
+
interp.on_function_declared += method(:declare_function)
|
13307
|
+
interp.on_translation_unit_ended += method(:check)
|
13388
13308
|
@variable_declarations = Hash.new { |hash, key| hash[key] = [] }
|
13389
13309
|
@function_declarations = Hash.new { |hash, key| hash[key] = [] }
|
13390
13310
|
end
|
13391
13311
|
|
13392
13312
|
private
|
13393
|
-
def
|
13394
|
-
if
|
13395
|
-
|
13396
|
-
@variable_declarations[declaration.identifier.value].push(declaration)
|
13313
|
+
def declare_variable(variable_declaration, variable)
|
13314
|
+
if variable.named? && variable.declared_as_extern?
|
13315
|
+
@variable_declarations[variable.name].push(variable_declaration)
|
13397
13316
|
end
|
13398
13317
|
end
|
13399
13318
|
|
13400
|
-
def
|
13401
|
-
if
|
13402
|
-
|
13403
|
-
@function_declarations[declaration.identifier.value].push(declaration)
|
13319
|
+
def declare_function(function_declaration, function)
|
13320
|
+
if function.named? && function.declared_as_extern?
|
13321
|
+
@function_declarations[function.name].push(function_declaration)
|
13404
13322
|
end
|
13405
13323
|
end
|
13406
13324
|
|
13407
|
-
def check(
|
13325
|
+
def check(*)
|
13408
13326
|
@variable_declarations.each_value do |declarations|
|
13409
|
-
|
13410
|
-
|
13411
|
-
|
13327
|
+
decl_locations = declarations.map { |decl|
|
13328
|
+
decl.location
|
13329
|
+
}.uniq { |location| location.fpath }
|
13330
|
+
if decl_locations.size > 1
|
13331
|
+
decl_locations.each do |location|
|
13332
|
+
W(:W0771, location, declarations.first.identifier.value)
|
13412
13333
|
end
|
13413
13334
|
end
|
13414
13335
|
end
|
13415
13336
|
|
13416
13337
|
@function_declarations.each_value do |declarations|
|
13417
|
-
|
13418
|
-
|
13419
|
-
|
13338
|
+
decl_locations = declarations.map { |decl|
|
13339
|
+
decl.location
|
13340
|
+
}.uniq { |location| location.fpath }
|
13341
|
+
if decl_locations.size > 1
|
13342
|
+
decl_locations.each do |location|
|
13343
|
+
W(:W0771, location, declarations.first.identifier.value)
|
13420
13344
|
end
|
13421
13345
|
end
|
13422
13346
|
end
|
@@ -14022,20 +13946,19 @@ module C #:nodoc:
|
|
14022
13946
|
class W0790 < PassiveMessageDetection
|
14023
13947
|
def initialize(context)
|
14024
13948
|
super
|
14025
|
-
|
14026
|
-
|
14027
|
-
|
14028
|
-
|
14029
|
-
|
14030
|
-
visitor.leave_compound_statement += method(:leave_block)
|
13949
|
+
interp = context[:c_interpreter]
|
13950
|
+
interp.on_variable_defined += method(:check_variable)
|
13951
|
+
interp.on_function_started += method(:check_function)
|
13952
|
+
interp.on_block_started += method(:enter_block)
|
13953
|
+
interp.on_block_ended += method(:leave_block)
|
14031
13954
|
@global_var_names = Set.new
|
14032
13955
|
@global_fun_names = Set.new
|
14033
13956
|
@block_level = 0
|
14034
13957
|
end
|
14035
13958
|
|
14036
13959
|
private
|
14037
|
-
def check_variable(variable_definition)
|
14038
|
-
return unless
|
13960
|
+
def check_variable(variable_definition, variable)
|
13961
|
+
return unless @block_level == 0 && variable.declared_as_extern?
|
14039
13962
|
|
14040
13963
|
name = variable_definition.identifier.value
|
14041
13964
|
if @global_var_names.include?(name) || @global_fun_names.include?(name)
|
@@ -14045,8 +13968,8 @@ module C #:nodoc:
|
|
14045
13968
|
end
|
14046
13969
|
end
|
14047
13970
|
|
14048
|
-
def check_function(function_definition)
|
14049
|
-
return unless
|
13971
|
+
def check_function(function_definition, function)
|
13972
|
+
return unless @block_level == 0 && function.declared_as_extern?
|
14050
13973
|
|
14051
13974
|
name = function_definition.identifier.value
|
14052
13975
|
if @global_var_names.include?(name) || @global_fun_names.include?(name)
|
@@ -14056,25 +13979,13 @@ module C #:nodoc:
|
|
14056
13979
|
end
|
14057
13980
|
end
|
14058
13981
|
|
14059
|
-
def enter_block(
|
13982
|
+
def enter_block(*)
|
14060
13983
|
@block_level += 1
|
14061
13984
|
end
|
14062
13985
|
|
14063
|
-
def leave_block(
|
13986
|
+
def leave_block(*)
|
14064
13987
|
@block_level -= 1
|
14065
13988
|
end
|
14066
|
-
|
14067
|
-
def global?(definition)
|
14068
|
-
return false if @block_level > 0
|
14069
|
-
|
14070
|
-
if declaration_specifiers = definition.declaration_specifiers
|
14071
|
-
if declaration_specifiers.storage_class_specifier &&
|
14072
|
-
declaration_specifiers.storage_class_specifier.type == :STATIC
|
14073
|
-
return false
|
14074
|
-
end
|
14075
|
-
end
|
14076
|
-
true
|
14077
|
-
end
|
14078
13989
|
end
|
14079
13990
|
|
14080
13991
|
class W0795 < PassiveMessageDetection
|
@@ -14256,27 +14167,16 @@ module C #:nodoc:
|
|
14256
14167
|
super
|
14257
14168
|
interp = context[:c_interpreter]
|
14258
14169
|
interp.on_variable_defined += method(:check)
|
14259
|
-
interp.on_block_started += method(:enter_block)
|
14260
|
-
interp.on_block_ended += method(:leave_block)
|
14261
|
-
@block_depth = 0
|
14262
14170
|
end
|
14263
14171
|
|
14264
14172
|
private
|
14265
14173
|
def check(variable_definition, variable)
|
14266
|
-
unless
|
14174
|
+
unless variable.declared_as_extern?
|
14267
14175
|
if variable.type.incomplete?
|
14268
14176
|
W(:W0800, variable_definition.location, variable.name)
|
14269
14177
|
end
|
14270
14178
|
end
|
14271
14179
|
end
|
14272
|
-
|
14273
|
-
def enter_block(compound_statement)
|
14274
|
-
@block_depth += 1
|
14275
|
-
end
|
14276
|
-
|
14277
|
-
def leave_block(compound_statement)
|
14278
|
-
@block_depth -= 1
|
14279
|
-
end
|
14280
14180
|
end
|
14281
14181
|
|
14282
14182
|
class W0810 < PassiveMessageDetection
|
@@ -14373,7 +14273,8 @@ module C #:nodoc:
|
|
14373
14273
|
def check(type, initializer)
|
14374
14274
|
return unless initializer
|
14375
14275
|
|
14376
|
-
|
14276
|
+
case
|
14277
|
+
when initializers = initializer.initializers
|
14377
14278
|
case
|
14378
14279
|
when type.array?
|
14379
14280
|
check(type.base_type, initializers.first)
|
@@ -14382,6 +14283,7 @@ module C #:nodoc:
|
|
14382
14283
|
check(memb.type, init) if init
|
14383
14284
|
end
|
14384
14285
|
end
|
14286
|
+
when initializer.expression.kind_of?(StringLiteralSpecifier)
|
14385
14287
|
else
|
14386
14288
|
W(:W0828, initializer.location) if type.array?
|
14387
14289
|
end
|
@@ -14548,110 +14450,94 @@ module C #:nodoc:
|
|
14548
14450
|
visitor.enter_kandr_function_definition += method(:define_function)
|
14549
14451
|
visitor.enter_compound_statement += method(:enter_block)
|
14550
14452
|
visitor.leave_compound_statement += method(:leave_block)
|
14551
|
-
@
|
14453
|
+
@block_level = 0
|
14552
14454
|
@global_objects = {}
|
14553
14455
|
end
|
14554
14456
|
|
14555
14457
|
private
|
14556
14458
|
def declare_variable(variable_declaration)
|
14557
|
-
|
14558
|
-
|
14559
|
-
|
14560
|
-
|
14561
|
-
|
14562
|
-
|
14563
|
-
|
14564
|
-
|
14565
|
-
@global_objects[name] = linkage
|
14566
|
-
end
|
14459
|
+
name = variable_declaration.identifier.value
|
14460
|
+
linkage = linkage_of(variable_declaration)
|
14461
|
+
prev_linkage = @global_objects[name]
|
14462
|
+
case
|
14463
|
+
when linkage && prev_linkage && linkage != prev_linkage
|
14464
|
+
W(:W1031, variable_declaration.location, name)
|
14465
|
+
when linkage
|
14466
|
+
@global_objects[name] = linkage
|
14567
14467
|
end
|
14568
14468
|
end
|
14569
14469
|
|
14570
14470
|
def define_variable(variable_definition)
|
14571
|
-
|
14572
|
-
|
14573
|
-
|
14574
|
-
|
14575
|
-
|
14576
|
-
|
14577
|
-
|
14578
|
-
|
14579
|
-
@global_objects[name] = linkage
|
14580
|
-
end
|
14471
|
+
name = variable_definition.identifier.value
|
14472
|
+
linkage = linkage_of(variable_definition)
|
14473
|
+
prev_linkage = @global_objects[name]
|
14474
|
+
case
|
14475
|
+
when linkage && prev_linkage && linkage != prev_linkage
|
14476
|
+
W(:W1031, variable_definition.location, name)
|
14477
|
+
when linkage
|
14478
|
+
@global_objects[name] = linkage
|
14581
14479
|
end
|
14582
14480
|
end
|
14583
14481
|
|
14584
14482
|
def declare_function(function_declaration)
|
14585
|
-
|
14586
|
-
|
14587
|
-
|
14588
|
-
|
14589
|
-
|
14590
|
-
|
14591
|
-
|
14592
|
-
|
14593
|
-
@global_objects[name] = linkage
|
14594
|
-
end
|
14483
|
+
name = function_declaration.identifier.value
|
14484
|
+
linkage = linkage_of(function_declaration)
|
14485
|
+
prev_linkage = @global_objects[name]
|
14486
|
+
case
|
14487
|
+
when linkage && prev_linkage && linkage != prev_linkage
|
14488
|
+
W(:W1031, function_declaration.location, name)
|
14489
|
+
when linkage
|
14490
|
+
@global_objects[name] = linkage
|
14595
14491
|
end
|
14596
14492
|
end
|
14597
14493
|
|
14598
14494
|
def define_function(function_definition)
|
14599
|
-
|
14600
|
-
|
14601
|
-
|
14602
|
-
|
14603
|
-
|
14604
|
-
|
14605
|
-
|
14606
|
-
|
14607
|
-
@global_objects[name] = linkage
|
14608
|
-
end
|
14495
|
+
name = function_definition.identifier.value
|
14496
|
+
linkage = linkage_of(function_definition)
|
14497
|
+
prev_linkage = @global_objects[name]
|
14498
|
+
case
|
14499
|
+
when linkage && prev_linkage && linkage != prev_linkage
|
14500
|
+
W(:W1031, function_definition.location, name)
|
14501
|
+
when linkage
|
14502
|
+
@global_objects[name] = linkage
|
14609
14503
|
end
|
14610
14504
|
end
|
14611
14505
|
|
14612
|
-
def enter_block(
|
14613
|
-
@
|
14506
|
+
def enter_block(*)
|
14507
|
+
@block_level += 1
|
14614
14508
|
end
|
14615
14509
|
|
14616
|
-
def leave_block(
|
14617
|
-
@
|
14510
|
+
def leave_block(*)
|
14511
|
+
@block_level -= 1
|
14618
14512
|
end
|
14619
14513
|
|
14620
|
-
def linkage_of(
|
14621
|
-
if storage_class_specifier =
|
14514
|
+
def linkage_of(decl_or_def)
|
14515
|
+
if storage_class_specifier = decl_or_def.storage_class_specifier
|
14622
14516
|
case storage_class_specifier.type
|
14623
14517
|
when :STATIC
|
14624
|
-
|
14518
|
+
:internal
|
14625
14519
|
when :EXTERN
|
14626
|
-
|
14520
|
+
:external
|
14521
|
+
else
|
14522
|
+
nil
|
14627
14523
|
end
|
14524
|
+
else
|
14525
|
+
@block_level == 0 ? :external : nil
|
14628
14526
|
end
|
14629
|
-
nil
|
14630
14527
|
end
|
14631
14528
|
end
|
14632
14529
|
|
14633
14530
|
class W1032 < PassiveMessageDetection
|
14634
14531
|
def initialize(context)
|
14635
14532
|
super
|
14636
|
-
|
14637
|
-
|
14533
|
+
interp = context[:c_interpreter]
|
14534
|
+
interp.on_variable_defined += method(:check)
|
14638
14535
|
end
|
14639
14536
|
|
14640
14537
|
private
|
14641
|
-
def check(variable_definition)
|
14642
|
-
if
|
14643
|
-
|
14644
|
-
W(:W1032, variable_definition.location,
|
14645
|
-
variable_definition.identifier.value)
|
14646
|
-
end
|
14647
|
-
end
|
14648
|
-
end
|
14649
|
-
|
14650
|
-
def linkage_of(node)
|
14651
|
-
if storage_class_specifier = node.storage_class_specifier
|
14652
|
-
storage_class_specifier.type == :STATIC ? :internal : :external
|
14653
|
-
else
|
14654
|
-
:external
|
14538
|
+
def check(variable_definition, variable)
|
14539
|
+
if variable.declared_as_static? && variable.type.incomplete?
|
14540
|
+
W(:W1032, variable_definition.location, variable.name)
|
14655
14541
|
end
|
14656
14542
|
end
|
14657
14543
|
end
|
@@ -14663,33 +14549,24 @@ module C #:nodoc:
|
|
14663
14549
|
visitor.enter_function_declaration += method(:check)
|
14664
14550
|
visitor.enter_compound_statement += method(:enter_block)
|
14665
14551
|
visitor.leave_compound_statement += method(:leave_block)
|
14666
|
-
@
|
14552
|
+
@block_level = 0
|
14667
14553
|
end
|
14668
14554
|
|
14669
14555
|
private
|
14670
|
-
def check(
|
14671
|
-
|
14672
|
-
|
14673
|
-
|
14674
|
-
|
14675
|
-
function_declaration.identifier.value)
|
14556
|
+
def check(declaration)
|
14557
|
+
if @block_level > 0
|
14558
|
+
if scs = declaration.storage_class_specifier and scs.type == :STATIC
|
14559
|
+
W(:W1034, declaration.location, declaration.identifier.value)
|
14560
|
+
end
|
14676
14561
|
end
|
14677
14562
|
end
|
14678
14563
|
|
14679
|
-
def enter_block(
|
14680
|
-
@
|
14681
|
-
end
|
14682
|
-
|
14683
|
-
def leave_block(node)
|
14684
|
-
@block_depth -= 1
|
14564
|
+
def enter_block(*)
|
14565
|
+
@block_level += 1
|
14685
14566
|
end
|
14686
14567
|
|
14687
|
-
def
|
14688
|
-
|
14689
|
-
storage_class_specifier.type == :STATIC ? :internal : :external
|
14690
|
-
else
|
14691
|
-
:external
|
14692
|
-
end
|
14568
|
+
def leave_block(*)
|
14569
|
+
@block_level -= 1
|
14693
14570
|
end
|
14694
14571
|
end
|
14695
14572
|
|