adlint 1.8.10 → 1.10.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 +261 -3
- data/MANIFEST +25 -1
- data/NEWS +25 -5
- data/Rakefile +11 -0
- data/TODO +0 -1
- data/etc/mesg.d/en_US/messages.yml +1 -1
- data/etc/mesg.d/ja_JP/messages.yml +1 -1
- data/features/message_detection/W0001.feature +41 -0
- data/features/message_detection/W0002.feature +68 -0
- data/features/message_detection/W0003.feature +134 -0
- data/features/message_detection/W0007.feature +264 -0
- data/features/message_detection/W0010.feature +75 -0
- data/features/message_detection/W0013.feature +189 -0
- data/features/message_detection/W0109.feature +50 -0
- data/features/message_detection/W0583.feature +30 -0
- data/features/message_detection/W0606.feature +20 -0
- data/features/message_detection/W0698.feature +20 -0
- data/features/message_detection/W0699.feature +21 -0
- data/features/message_detection/W0703.feature +73 -0
- data/features/message_detection/W0716.feature +67 -0
- data/features/message_detection/W0717.feature +64 -0
- data/features/message_detection/W0718.feature +64 -0
- data/features/message_detection/W0723.feature +18 -0
- data/features/message_detection/W1031.feature +328 -0
- data/features/step_definitions/message_detection_steps.rb +45 -0
- data/features/support/env.rb +58 -0
- data/lib/adlint/c/branch.rb +16 -23
- data/lib/adlint/c/code.rb +1 -12
- data/lib/adlint/c/conv.rb +4 -4
- data/lib/adlint/c/ctrlexpr.rb +10 -6
- data/lib/adlint/c/domain.rb +2 -2
- data/lib/adlint/c/expr.rb +11 -33
- data/lib/adlint/c/format.rb +6 -6
- data/lib/adlint/c/interp.rb +137 -80
- data/lib/adlint/c/mediator.rb +5 -2
- data/lib/adlint/c/message.rb +123 -140
- data/lib/adlint/c/message_shima.rb +44 -0
- data/lib/adlint/c/object.rb +93 -26
- data/lib/adlint/c/option.rb +53 -0
- data/lib/adlint/c/phase.rb +4 -1
- data/lib/adlint/c/type.rb +112 -46
- data/lib/adlint/c.rb +1 -0
- data/lib/adlint/version.rb +3 -3
- 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 +35 -28
- data/share/doc/users_guide_en.texi +30 -22
- data/share/doc/users_guide_ja.html +35 -31
- data/share/doc/users_guide_ja.texi +30 -24
- data/spec/adlint/c/type_spec.rb +110 -0
- data/spec/conf.d/default_traits.yml +216 -0
- data/spec/conf.d/empty_cinit.h +11 -0
- data/spec/conf.d/empty_pinit.h +11 -0
- data/spec/spec_helper.rb +49 -0
- metadata +27 -3
- data/spec/MUST_WRITE_SPECS_WITH_RSPEC +0 -0
data/lib/adlint/c/interp.rb
CHANGED
@@ -36,14 +36,45 @@ require "adlint/c/mediator"
|
|
36
36
|
require "adlint/c/syntax"
|
37
37
|
require "adlint/c/expr"
|
38
38
|
require "adlint/c/conv"
|
39
|
+
require "adlint/c/option"
|
39
40
|
require "adlint/c/util"
|
40
41
|
|
41
42
|
module AdLint #:nodoc:
|
42
43
|
module C #:nodoc:
|
43
44
|
|
45
|
+
class Program
|
46
|
+
def initialize(interpreter, translation_unit)
|
47
|
+
@interpreter = interpreter
|
48
|
+
@translation_unit = translation_unit
|
49
|
+
end
|
50
|
+
|
51
|
+
def execute
|
52
|
+
@interpreter.notify_translation_unit_started(@translation_unit)
|
53
|
+
@translation_unit.accept(ExecutionDriver.new(@interpreter))
|
54
|
+
@interpreter.notify_translation_unit_ended(@translation_unit)
|
55
|
+
end
|
56
|
+
|
57
|
+
class ExecutionDriver < SyntaxTreeVisitor
|
58
|
+
include InterpreterMediator
|
59
|
+
|
60
|
+
def initialize(interpreter)
|
61
|
+
@interpreter = interpreter
|
62
|
+
end
|
63
|
+
|
64
|
+
def visit_declaration(node) interpret(node) end
|
65
|
+
def visit_ansi_function_definition(node) interpret(node) end
|
66
|
+
def visit_kandr_function_definition(node) interpret(node) end
|
67
|
+
|
68
|
+
private
|
69
|
+
def interpreter; @interpreter end
|
70
|
+
end
|
71
|
+
private_constant :ExecutionDriver
|
72
|
+
end
|
73
|
+
|
44
74
|
class Interpreter
|
45
75
|
include InterpreterMediator
|
46
76
|
include Conversion
|
77
|
+
include InterpreterOptions
|
47
78
|
|
48
79
|
def initialize(type_table)
|
49
80
|
type_table = type_table
|
@@ -51,7 +82,6 @@ module C #:nodoc:
|
|
51
82
|
@type_resolver = DynamicTypeResolver.new(type_table, self)
|
52
83
|
|
53
84
|
@sub_interpreters = [
|
54
|
-
TranslationUnitInterpreter.new(self),
|
55
85
|
DeclarationInterpreter.new(self),
|
56
86
|
ParameterDefinitionInterpreter.new(self),
|
57
87
|
FunctionInterpreter.new(self),
|
@@ -60,7 +90,7 @@ module C #:nodoc:
|
|
60
90
|
ExpressionInterpreter.new(self)
|
61
91
|
]
|
62
92
|
|
63
|
-
@
|
93
|
+
@options_stack = []
|
64
94
|
|
65
95
|
# NOTE: Active (executing) function may be nested if the nested
|
66
96
|
# function-definition of the GCC extension is used.
|
@@ -76,7 +106,7 @@ module C #:nodoc:
|
|
76
106
|
class_eval <<-EOS
|
77
107
|
def_plugin :on_#{event_name}
|
78
108
|
def notify_#{event_name}(#{arg_names.join(",")})
|
79
|
-
unless
|
109
|
+
unless quiet?
|
80
110
|
on_#{event_name}.invoke(#{arg_names.join(",")})
|
81
111
|
end
|
82
112
|
end
|
@@ -84,21 +114,24 @@ module C #:nodoc:
|
|
84
114
|
end
|
85
115
|
private_class_method :def_plugin_and_notifier
|
86
116
|
|
117
|
+
# NOTE: Notified when the interpreter evaluates a variable-declaration.
|
118
|
+
def_plugin_and_notifier :variable_declared,
|
119
|
+
:variable_declaration, :variable
|
120
|
+
|
121
|
+
# NOTE: Notified when the interpreter evaluates a variable-definition.
|
122
|
+
def_plugin_and_notifier :variable_defined, :variable_definition, :variable
|
123
|
+
|
87
124
|
# NOTE: Notified when the interpreter evaluates an initializer of
|
88
125
|
# variable-definition.
|
89
126
|
def_plugin_and_notifier :variable_initialized,
|
90
127
|
:variable_definition, :variable, :init_variable
|
91
128
|
|
92
|
-
# NOTE: Notified when the interpreter evaluates a variable-definition.
|
93
|
-
def_plugin_and_notifier :variable_defined, :variable_definition, :variable
|
94
|
-
|
95
129
|
# NOTE: Notified when the interpreter evaluates a function-declaration.
|
96
130
|
def_plugin_and_notifier :function_declared,
|
97
131
|
:function_declaration, :function
|
98
132
|
|
99
|
-
# NOTE: Notified when the interpreter evaluates a
|
100
|
-
def_plugin_and_notifier :
|
101
|
-
:variable_declaration, :variable
|
133
|
+
# NOTE: Notified when the interpreter evaluates a function-definition.
|
134
|
+
def_plugin_and_notifier :function_defined, :function_definition, :function
|
102
135
|
|
103
136
|
# NOTE: Notified when the interpreter evaluates a struct-type-declaration.
|
104
137
|
def_plugin_and_notifier :struct_declared, :struct_type_declaration
|
@@ -235,7 +268,7 @@ module C #:nodoc:
|
|
235
268
|
|
236
269
|
# NOTE: Notified when the interpreter evaluates a conditional-expression.
|
237
270
|
def_plugin_and_notifier :conditional_expr_evaled,
|
238
|
-
:conditional_expression, :
|
271
|
+
:conditional_expression, :controlling_variable,
|
239
272
|
:result_variable
|
240
273
|
|
241
274
|
# NOTE: Notified when the interpreter evaluates an address-expression.
|
@@ -393,16 +426,10 @@ module C #:nodoc:
|
|
393
426
|
def_plugin_and_notifier :sequence_point_reached, :sequence_point
|
394
427
|
|
395
428
|
def execute(node, *options)
|
396
|
-
|
397
|
-
@suppress_notification = true
|
398
|
-
end
|
399
|
-
|
429
|
+
@options_stack.push(current_options + options)
|
400
430
|
node.accept(interpreter_for(node))
|
401
|
-
|
402
431
|
ensure
|
403
|
-
|
404
|
-
@suppress_notification = false
|
405
|
-
end
|
432
|
+
@options_stack.pop
|
406
433
|
end
|
407
434
|
|
408
435
|
def object_to_variable(object)
|
@@ -429,9 +456,17 @@ module C #:nodoc:
|
|
429
456
|
ScalarValue.of(object.binding.memory.address)
|
430
457
|
end
|
431
458
|
|
432
|
-
def
|
459
|
+
def quiet?
|
460
|
+
current_options.include?(QUIET)
|
461
|
+
end
|
462
|
+
|
463
|
+
def _quiet=(quiet)
|
433
464
|
# NOTE: This method is called only from ControllingExpression.
|
434
|
-
|
465
|
+
if quiet
|
466
|
+
current_options.add(QUIET)
|
467
|
+
else
|
468
|
+
current_options.delete(QUIET)
|
469
|
+
end
|
435
470
|
end
|
436
471
|
|
437
472
|
def _active_function
|
@@ -459,6 +494,10 @@ module C #:nodoc:
|
|
459
494
|
end
|
460
495
|
end
|
461
496
|
|
497
|
+
def current_options
|
498
|
+
@options_stack.last || Set.new
|
499
|
+
end
|
500
|
+
|
462
501
|
def interpreter
|
463
502
|
# NOTE: This method is of the requirement for including
|
464
503
|
# InterpreterMediator.
|
@@ -471,6 +510,7 @@ module C #:nodoc:
|
|
471
510
|
include NotifierMediator
|
472
511
|
include Conversion
|
473
512
|
include MonitorUtil
|
513
|
+
include InterpreterOptions
|
474
514
|
|
475
515
|
def initialize(owner, target_node_class)
|
476
516
|
@owner = owner
|
@@ -485,38 +525,6 @@ module C #:nodoc:
|
|
485
525
|
end
|
486
526
|
end
|
487
527
|
|
488
|
-
class TranslationUnitInterpreter < SubInterpreter
|
489
|
-
def initialize(owner)
|
490
|
-
super(owner, TranslationUnit)
|
491
|
-
end
|
492
|
-
|
493
|
-
def visit_declaration(node)
|
494
|
-
checkpoint(node.location)
|
495
|
-
|
496
|
-
interpret(node)
|
497
|
-
end
|
498
|
-
|
499
|
-
def visit_translation_unit(node)
|
500
|
-
checkpoint(node.location)
|
501
|
-
|
502
|
-
notify_translation_unit_started(node)
|
503
|
-
super
|
504
|
-
notify_translation_unit_ended(node)
|
505
|
-
end
|
506
|
-
|
507
|
-
def visit_ansi_function_definition(node)
|
508
|
-
checkpoint(node.location)
|
509
|
-
|
510
|
-
interpret(node)
|
511
|
-
end
|
512
|
-
|
513
|
-
def visit_kandr_function_definition(node)
|
514
|
-
checkpoint(node.location)
|
515
|
-
|
516
|
-
interpret(node)
|
517
|
-
end
|
518
|
-
end
|
519
|
-
|
520
528
|
class DeclarationInterpreter < SubInterpreter
|
521
529
|
def initialize(owner)
|
522
530
|
super(owner, Declaration)
|
@@ -531,7 +539,8 @@ module C #:nodoc:
|
|
531
539
|
decl.mark_as_referred_by(node.identifier)
|
532
540
|
end
|
533
541
|
|
534
|
-
function =
|
542
|
+
function = declare_function(node)
|
543
|
+
|
535
544
|
notify_function_declared(node, function)
|
536
545
|
|
537
546
|
evaluate_sequence_point(node.init_declarator.declarator)
|
@@ -562,12 +571,12 @@ module C #:nodoc:
|
|
562
571
|
end
|
563
572
|
|
564
573
|
if initializer = node.initializer
|
565
|
-
|
574
|
+
init_var, converted = evaluate_initializer(initializer, node.type)
|
566
575
|
variable = define_variable(node, converted.value.to_defined_value)
|
567
576
|
|
568
|
-
notify_variable_value_referred(node,
|
577
|
+
notify_variable_value_referred(node, init_var)
|
569
578
|
notify_variable_defined(node, variable)
|
570
|
-
notify_variable_initialized(node, variable,
|
579
|
+
notify_variable_initialized(node, variable, init_var)
|
571
580
|
else
|
572
581
|
notify_variable_defined(node, define_variable(node))
|
573
582
|
end
|
@@ -809,8 +818,6 @@ module C #:nodoc:
|
|
809
818
|
def interpret_function(node)
|
810
819
|
checkpoint(node.location)
|
811
820
|
|
812
|
-
interpreter._enter_function(node)
|
813
|
-
|
814
821
|
reset_environment
|
815
822
|
resolve_unresolved_type(node)
|
816
823
|
|
@@ -823,27 +830,32 @@ module C #:nodoc:
|
|
823
830
|
function = define_explicit_function(node)
|
824
831
|
end
|
825
832
|
|
826
|
-
|
827
|
-
notify_function_started(node, function)
|
828
|
-
notify_block_started(node.function_body)
|
833
|
+
notify_function_defined(node, function)
|
829
834
|
|
830
|
-
|
835
|
+
begin
|
836
|
+
interpreter._enter_function(node)
|
837
|
+
scoped_eval do
|
838
|
+
notify_function_started(node, function)
|
839
|
+
notify_block_started(node.function_body)
|
831
840
|
|
832
|
-
|
833
|
-
|
834
|
-
|
841
|
+
node.parameter_definitions.each { |pdef| interpret(pdef) }
|
842
|
+
|
843
|
+
BreakEvent.catch do
|
844
|
+
node.function_body.block_items.each { |item| interpret(item) }
|
845
|
+
end
|
835
846
|
|
836
|
-
|
837
|
-
|
847
|
+
notify_block_ended(node.function_body)
|
848
|
+
notify_function_ended(node, function)
|
849
|
+
end
|
850
|
+
ensure
|
851
|
+
interpreter._leave_function(node)
|
838
852
|
end
|
839
|
-
ensure
|
840
|
-
interpreter._leave_function(node)
|
841
853
|
end
|
842
854
|
end
|
843
855
|
|
844
856
|
class StatementInterpreter < SubInterpreter
|
845
|
-
include
|
846
|
-
include
|
857
|
+
include BranchOptions
|
858
|
+
include BranchGroupOptions
|
847
859
|
include SyntaxNodeCollector
|
848
860
|
|
849
861
|
def initialize(owner)
|
@@ -865,8 +877,7 @@ module C #:nodoc:
|
|
865
877
|
|
866
878
|
node.executed = true
|
867
879
|
ctrlexpr = node.expression
|
868
|
-
ctrlexpr_result = object_to_variable(interpret(ctrlexpr,
|
869
|
-
:suppress_notification))
|
880
|
+
ctrlexpr_result = object_to_variable(interpret(ctrlexpr, QUIET))
|
870
881
|
notify_case_ctrlexpr_evaled(node, ctrlexpr_result)
|
871
882
|
|
872
883
|
interpret(node.statement)
|
@@ -905,7 +916,7 @@ module C #:nodoc:
|
|
905
916
|
|
906
917
|
node.executed = true
|
907
918
|
ctrlexpr = node.expression
|
908
|
-
ctrlexpr_value = value_of(interpret(ctrlexpr,
|
919
|
+
ctrlexpr_value = value_of(interpret(ctrlexpr, QUIET))
|
909
920
|
notify_if_ctrlexpr_evaled(node, ctrlexpr_value)
|
910
921
|
|
911
922
|
case
|
@@ -931,7 +942,7 @@ module C #:nodoc:
|
|
931
942
|
|
932
943
|
node.executed = true
|
933
944
|
ctrlexpr = node.expression
|
934
|
-
ctrlexpr_value = value_of(interpret(ctrlexpr,
|
945
|
+
ctrlexpr_value = value_of(interpret(ctrlexpr, QUIET))
|
935
946
|
notify_if_else_ctrlexpr_evaled(node, ctrlexpr_value)
|
936
947
|
|
937
948
|
case
|
@@ -1303,8 +1314,8 @@ module C #:nodoc:
|
|
1303
1314
|
end
|
1304
1315
|
|
1305
1316
|
class SwitchStatementInterpreter < SubInterpreter
|
1306
|
-
include
|
1307
|
-
include
|
1317
|
+
include BranchOptions
|
1318
|
+
include BranchGroupOptions
|
1308
1319
|
|
1309
1320
|
def initialize(owner)
|
1310
1321
|
super(owner, SwitchStatement)
|
@@ -1367,7 +1378,7 @@ module C #:nodoc:
|
|
1367
1378
|
|
1368
1379
|
def execute_branch(labeled_statement, block_items, index, branch_options)
|
1369
1380
|
ctrlexpr = labeled_statement.normalized_expression
|
1370
|
-
ctrlexpr_value = value_of(interpret(ctrlexpr,
|
1381
|
+
ctrlexpr_value = value_of(interpret(ctrlexpr, QUIET))
|
1371
1382
|
|
1372
1383
|
case
|
1373
1384
|
when ctrlexpr_value.must_be_true?
|
@@ -1411,7 +1422,7 @@ module C #:nodoc:
|
|
1411
1422
|
|
1412
1423
|
branch.restart_versioning do
|
1413
1424
|
ctrlexpr = labeled_statement.normalized_expression
|
1414
|
-
ctrlexpr_value = value_of(interpret(ctrlexpr,
|
1425
|
+
ctrlexpr_value = value_of(interpret(ctrlexpr, QUIET))
|
1415
1426
|
|
1416
1427
|
case
|
1417
1428
|
when ctrlexpr_value.must_be_true?
|
@@ -1481,6 +1492,8 @@ module C #:nodoc:
|
|
1481
1492
|
|
1482
1493
|
class ExpressionInterpreter < SubInterpreter
|
1483
1494
|
include ExpressionEvaluator
|
1495
|
+
include BranchOptions
|
1496
|
+
include BranchGroupOptions
|
1484
1497
|
|
1485
1498
|
def initialize(owner)
|
1486
1499
|
super(owner, Expression)
|
@@ -1534,10 +1547,54 @@ module C #:nodoc:
|
|
1534
1547
|
def_eval_with_sequence_point :visit_inclusive_or_expression
|
1535
1548
|
def_eval_with_sequence_point :visit_logical_and_expression
|
1536
1549
|
def_eval_with_sequence_point :visit_logical_or_expression
|
1537
|
-
def_eval_with_sequence_point :visit_conditional_expression
|
1538
1550
|
def_eval_with_sequence_point :visit_simple_assignment_expression
|
1539
1551
|
def_eval_with_sequence_point :visit_compound_assignment_expression
|
1540
1552
|
def_eval_with_sequence_point :visit_comma_separated_expression
|
1553
|
+
|
1554
|
+
def visit_conditional_expression(node)
|
1555
|
+
checkpoint(node.location)
|
1556
|
+
|
1557
|
+
ctrlexpr = node.condition
|
1558
|
+
ctrlexpr_variable = interpret(ctrlexpr, QUIET)
|
1559
|
+
ctrlexpr_value = value_of(ctrlexpr_variable)
|
1560
|
+
|
1561
|
+
then_var = nil
|
1562
|
+
if ctrlexpr_value.may_be_true?
|
1563
|
+
branched_eval(ctrlexpr, NARROWING) do
|
1564
|
+
then_var = object_to_variable(interpret(node.then_expression))
|
1565
|
+
end
|
1566
|
+
end
|
1567
|
+
|
1568
|
+
else_var = nil
|
1569
|
+
if ctrlexpr_value.may_be_false?
|
1570
|
+
branched_eval(nil, NARROWING, FINAL, COMPLETE) do
|
1571
|
+
else_var = object_to_variable(interpret(node.else_expression))
|
1572
|
+
end
|
1573
|
+
else
|
1574
|
+
branched_eval(nil, NARROWING, FINAL, COMPLETE) {}
|
1575
|
+
end
|
1576
|
+
|
1577
|
+
case
|
1578
|
+
when then_var && else_var
|
1579
|
+
result_val = then_var.value.single_value_unified_with(else_var.value)
|
1580
|
+
result = temporary_variable(then_var.type, result_val)
|
1581
|
+
when then_var
|
1582
|
+
result = then_var
|
1583
|
+
when else_var
|
1584
|
+
result = else_var
|
1585
|
+
else
|
1586
|
+
# FIXME: Nevertheless, the then-expression is not reachable, the branch
|
1587
|
+
# execution check may fail in evaluation of the else branch.
|
1588
|
+
result = temporary_variable
|
1589
|
+
end
|
1590
|
+
|
1591
|
+
notify_conditional_expr_evaled(node, ctrlexpr_variable, result)
|
1592
|
+
result
|
1593
|
+
ensure
|
1594
|
+
if sequence_point = node.subsequent_sequence_point
|
1595
|
+
notify_sequence_point_reached(sequence_point)
|
1596
|
+
end
|
1597
|
+
end
|
1541
1598
|
end
|
1542
1599
|
|
1543
1600
|
end
|
data/lib/adlint/c/mediator.rb
CHANGED
@@ -106,6 +106,7 @@ module C #:nodoc:
|
|
106
106
|
def_delegator :variable_table, :lookup, :variable_named
|
107
107
|
def_delegator :variable_table, :declare, :declare_variable
|
108
108
|
def_delegator :variable_table, :define, :define_variable
|
109
|
+
def_delegator :variable_table, :storage_duration_of
|
109
110
|
|
110
111
|
def local_variables
|
111
112
|
variable_table.all_named_variables.select { |variable|
|
@@ -132,6 +133,7 @@ module C #:nodoc:
|
|
132
133
|
extend Forwardable
|
133
134
|
|
134
135
|
def_delegator :function_table, :lookup, :function_named
|
136
|
+
def_delegator :function_table, :declare, :declare_function
|
135
137
|
def_delegator :function_table, :define, :define_function
|
136
138
|
|
137
139
|
def define_explicit_function(function_declaration_or_definition)
|
@@ -177,10 +179,11 @@ module C #:nodoc:
|
|
177
179
|
|
178
180
|
extend Forwardable
|
179
181
|
|
180
|
-
def_delegator :interpreter, :
|
182
|
+
def_delegator :interpreter, :notify_variable_declared
|
181
183
|
def_delegator :interpreter, :notify_variable_defined
|
184
|
+
def_delegator :interpreter, :notify_variable_initialized
|
182
185
|
def_delegator :interpreter, :notify_function_declared
|
183
|
-
def_delegator :interpreter, :
|
186
|
+
def_delegator :interpreter, :notify_function_defined
|
184
187
|
def_delegator :interpreter, :notify_struct_declared
|
185
188
|
def_delegator :interpreter, :notify_union_declared
|
186
189
|
def_delegator :interpreter, :notify_enum_declared
|