adlint 1.8.2 → 1.8.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|