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