adlint 3.0.4 → 3.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +374 -13
- data/INSTALL +1 -3
- data/MANIFEST +12 -0
- data/NEWS +30 -4
- data/README +0 -4
- data/TODO +2 -1
- data/etc/mesg.d/c_builtin/en_US/messages.yml +2 -2
- data/etc/mesg.d/c_builtin/ja_JP/messages.yml +2 -2
- data/etc/mesg.d/core/en_US/messages.yml +5 -1
- data/etc/mesg.d/core/ja_JP/messages.yml +5 -1
- data/features/code_check/W0422.feature +128 -0
- data/features/code_check/W0491.feature +57 -0
- data/features/code_check/W0492.feature +80 -0
- data/features/code_check/W0542.feature +20 -0
- data/features/code_check/W0580.feature +25 -0
- data/features/code_check/W0610.feature +36 -0
- data/features/code_check/W0642.feature +67 -0
- data/features/code_check/W0786.feature +39 -0
- data/features/code_check/W0830.feature +27 -0
- data/features/code_check/W1047.feature +72 -0
- data/features/code_check/W9003.feature +22 -0
- data/features/code_extraction/TODO +1 -0
- data/features/metric_measurement/TODO +1 -0
- data/lib/adlint/analyzer.rb +2 -2
- data/lib/adlint/cc1/ctrlexpr.rb +27 -6
- data/lib/adlint/cc1/domain.rb +72 -12
- data/lib/adlint/cc1/enum.rb +4 -0
- data/lib/adlint/cc1/expr.rb +31 -29
- data/lib/adlint/cc1/interp.rb +45 -56
- data/lib/adlint/cc1/lexer.rb +26 -5
- data/lib/adlint/cc1/mediator.rb +35 -6
- data/lib/adlint/cc1/object.rb +62 -19
- data/lib/adlint/cc1/parser.rb +948 -904
- data/lib/adlint/cc1/parser.y +59 -29
- data/lib/adlint/cc1/phase.rb +6 -8
- data/lib/adlint/cc1/syntax.rb +70 -17
- data/lib/adlint/cc1/util.rb +4 -4
- data/lib/adlint/code.rb +16 -6
- data/lib/adlint/cpp/eval.rb +31 -25
- data/lib/adlint/cpp/lexer.rb +11 -5
- data/lib/adlint/cpp/macro.rb +34 -7
- data/lib/adlint/cpp/phase.rb +8 -8
- data/lib/adlint/error.rb +6 -0
- data/lib/adlint/exam/c_builtin/cc1_check.rb +557 -594
- data/lib/adlint/exam/c_builtin/cc1_check_shima.rb +72 -72
- data/lib/adlint/exam/c_builtin/cc1_code.rb +72 -52
- data/lib/adlint/exam/c_builtin/cc1_metric.rb +131 -131
- data/lib/adlint/exam/c_builtin/cpp_check.rb +48 -48
- data/lib/adlint/exam/c_builtin/cpp_check_shima.rb +2 -2
- data/lib/adlint/exam/c_builtin/cpp_code.rb +21 -21
- data/lib/adlint/exam/c_builtin/ld_check.rb +88 -87
- data/lib/adlint/exam/c_builtin/ld_metric.rb +4 -5
- data/lib/adlint/exam/c_builtin.rb +6 -6
- data/lib/adlint/ld/object.rb +269 -186
- data/lib/adlint/ld/phase.rb +19 -19
- data/lib/adlint/ld/typedef.rb +7 -7
- data/lib/adlint/ld/util.rb +25 -17
- data/lib/adlint/location.rb +6 -1
- data/lib/adlint/memo.rb +66 -13
- data/lib/adlint/prelude.rb +2 -2
- data/lib/adlint/report.rb +13 -14
- data/lib/adlint/util.rb +1 -1
- data/lib/adlint/version.rb +2 -2
- data/share/doc/Makefile +6 -2
- data/share/doc/c99gram.dot +502 -0
- data/share/doc/c99gram.pdf +0 -0
- data/share/doc/developers_guide_ja.html +4 -3
- data/share/doc/developers_guide_ja.texi +2 -1
- data/share/doc/users_guide_en.html +9 -9
- data/share/doc/users_guide_en.texi +7 -7
- data/share/doc/users_guide_ja.html +9 -9
- data/share/doc/users_guide_ja.texi +7 -7
- metadata +14 -2
data/lib/adlint/ld/typedef.rb
CHANGED
@@ -57,7 +57,7 @@ module Ld #:nodoc:
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
class
|
60
|
+
class TypedefMap
|
61
61
|
def initialize
|
62
62
|
@name_index = Hash.new { |hash, key| hash[key] = Set.new }
|
63
63
|
@composing_fpaths = Set.new
|
@@ -83,10 +83,10 @@ module Ld #:nodoc:
|
|
83
83
|
|
84
84
|
class TypedefMapper
|
85
85
|
def initialize
|
86
|
-
@
|
86
|
+
@map = TypedefMap.new
|
87
87
|
end
|
88
88
|
|
89
|
-
attr_reader :
|
89
|
+
attr_reader :map
|
90
90
|
|
91
91
|
def execute(met_fpath)
|
92
92
|
sma_wd = Pathname.pwd
|
@@ -96,15 +96,15 @@ module Ld #:nodoc:
|
|
96
96
|
when rec.version?
|
97
97
|
sma_wd = Pathname.new(rec.exec_working_directory)
|
98
98
|
when rec.typedef_declaration?
|
99
|
-
@
|
99
|
+
@map.add(Typedef.new(rec.type_name, rec.location))
|
100
100
|
end
|
101
101
|
end
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
105
|
class TypedefTraversal
|
106
|
-
def initialize(
|
107
|
-
@
|
106
|
+
def initialize(typedef_map)
|
107
|
+
@map = typedef_map
|
108
108
|
end
|
109
109
|
|
110
110
|
extend Pluggable
|
@@ -112,7 +112,7 @@ module Ld #:nodoc:
|
|
112
112
|
def_plugin :on_declaration
|
113
113
|
|
114
114
|
def execute
|
115
|
-
@
|
115
|
+
@map.all_typedefs.each { |tdef| on_declaration.invoke(tdef) }
|
116
116
|
end
|
117
117
|
end
|
118
118
|
|
data/lib/adlint/ld/util.rb
CHANGED
@@ -39,21 +39,25 @@ module Ld #:nodoc:
|
|
39
39
|
map_fname = Pathname.new("#{proj_name}.map")
|
40
40
|
map_fpath = map_fname.expand_path(phase_ctxt.msg_fpath.dirname)
|
41
41
|
|
42
|
-
|
43
|
-
call_graph = phase_ctxt[:
|
44
|
-
return unless
|
42
|
+
map = phase_ctxt[:ld_function_map]
|
43
|
+
call_graph = phase_ctxt[:ld_call_graph]
|
44
|
+
return unless map && call_graph
|
45
45
|
|
46
46
|
File.open(map_fpath, "w") do |io|
|
47
47
|
io.puts("-- Function Call Graph --")
|
48
|
-
|
48
|
+
map.all_functions.each do |callee|
|
49
49
|
io.puts("DC of #{callee.signature}")
|
50
|
-
call_graph.direct_callers_of(callee).each do |
|
51
|
-
|
50
|
+
call_graph.direct_callers_of(callee).each do |ref|
|
51
|
+
if fun = ref.function
|
52
|
+
io.puts(" #{fun.signature}")
|
53
|
+
end
|
52
54
|
end
|
53
55
|
io.puts
|
54
56
|
io.puts("IC of #{callee.signature}")
|
55
|
-
call_graph.indirect_callers_of(callee).each do |
|
56
|
-
|
57
|
+
call_graph.indirect_callers_of(callee).each do |ref|
|
58
|
+
if fun = ref.function
|
59
|
+
io.puts(" #{fun.signature}")
|
60
|
+
end
|
57
61
|
end
|
58
62
|
io.puts
|
59
63
|
end
|
@@ -68,21 +72,25 @@ module Ld #:nodoc:
|
|
68
72
|
map_fname = Pathname.new("#{proj_name}.map")
|
69
73
|
map_fpath = map_fname.expand_path(phase_ctxt.msg_fpath.dirname)
|
70
74
|
|
71
|
-
|
72
|
-
ref_graph = phase_ctxt[:
|
73
|
-
return unless
|
75
|
+
map = phase_ctxt[:ld_variable_map]
|
76
|
+
ref_graph = phase_ctxt[:ld_xref_graph]
|
77
|
+
return unless map && ref_graph
|
74
78
|
|
75
79
|
File.open(map_fpath, "a") do |io|
|
76
80
|
io.puts("-- Variable Reference Graph --")
|
77
|
-
|
81
|
+
map.all_variables.each do |accessee|
|
78
82
|
io.puts("DR of #{accessee.name}")
|
79
|
-
ref_graph.direct_referrers_of(accessee).each do |
|
80
|
-
|
83
|
+
ref_graph.direct_referrers_of(accessee).each do |ref|
|
84
|
+
if fun = ref.function
|
85
|
+
io.puts(" #{fun.signature}")
|
86
|
+
end
|
81
87
|
end
|
82
88
|
io.puts
|
83
|
-
io.puts("IR or #{accessee.
|
84
|
-
ref_graph.indirect_referrers_of(accessee).each do |
|
85
|
-
|
89
|
+
io.puts("IR or #{accessee.name}")
|
90
|
+
ref_graph.indirect_referrers_of(accessee).each do |ref|
|
91
|
+
if fun = ref.function
|
92
|
+
io.puts(" #{fun.signature}")
|
93
|
+
end
|
86
94
|
end
|
87
95
|
io.puts
|
88
96
|
end
|
data/lib/adlint/location.rb
CHANGED
@@ -69,7 +69,12 @@ module AdLint #:nodoc:
|
|
69
69
|
false
|
70
70
|
end
|
71
71
|
end
|
72
|
-
|
72
|
+
# NOTE: Value of #in_analysis_target? depends on the `traits' parameter.
|
73
|
+
# But the `traits' parameter always points the same object in an
|
74
|
+
# AdLint instance.
|
75
|
+
# So, it is safe to treat this method as nullary method for improving
|
76
|
+
# the performance.
|
77
|
+
memoize :in_analysis_target?, force_nullary: true
|
73
78
|
|
74
79
|
def ==(rhs)
|
75
80
|
self.to_a == rhs.to_a
|
data/lib/adlint/memo.rb
CHANGED
@@ -32,20 +32,29 @@
|
|
32
32
|
module AdLint #:nodoc:
|
33
33
|
|
34
34
|
module Memoizable
|
35
|
-
def memoize(name, *
|
36
|
-
|
37
|
-
|
35
|
+
def memoize(name, *opts)
|
36
|
+
force_nullary, key_indices = extract_memoize_options(opts)
|
37
|
+
case
|
38
|
+
when instance_method(name).arity == 0 || force_nullary
|
39
|
+
memoize_nullary_method(name)
|
40
|
+
when instance_method(name).arity == 1 || key_indices.size == 1
|
41
|
+
memoize_unary_method(name, key_indices.first || 0)
|
38
42
|
else
|
39
|
-
|
43
|
+
memoize_polynomial_method(name, key_indices)
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
43
47
|
private
|
44
|
-
def
|
48
|
+
def extract_memoize_options(opts)
|
49
|
+
hash = opts.first || {}
|
50
|
+
[hash[:force_nullary], hash[:key_indices] || []]
|
51
|
+
end
|
52
|
+
|
53
|
+
def memoize_nullary_method(name)
|
45
54
|
save_memoizing_method(name)
|
46
|
-
|
55
|
+
prepare_nullary_method_cache(name)
|
47
56
|
class_eval <<-EOS
|
48
|
-
define_method(:#{name}) do
|
57
|
+
define_method(:#{name}) do |*args|
|
49
58
|
if #{cache_name_of(name)}_initialized ||= false
|
50
59
|
#{cache_name_of(name)}_forbidden = false
|
51
60
|
#{cache_name_of(name)}
|
@@ -55,16 +64,43 @@ module AdLint #:nodoc:
|
|
55
64
|
#{org_name_of(name)}
|
56
65
|
else
|
57
66
|
#{cache_name_of(name)}_initialized = true
|
58
|
-
#{cache_name_of(name)} = #{org_name_of(name)}
|
67
|
+
#{cache_name_of(name)} = #{org_name_of(name)}(*args)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
EOS
|
72
|
+
end
|
73
|
+
|
74
|
+
def memoize_unary_method(name, key_index)
|
75
|
+
save_memoizing_method(name)
|
76
|
+
prepare_unary_method_cache(name, key_index)
|
77
|
+
class_eval <<-EOS
|
78
|
+
define_method(:#{name}) do |*args|
|
79
|
+
key = args[#{key_index}]
|
80
|
+
if #{cache_name_of(name)}_initialized ||= false
|
81
|
+
#{cache_name_of(name)}_forbidden = false
|
82
|
+
if #{cache_name_of(name)}.include?(key)
|
83
|
+
#{cache_name_of(name)}[key]
|
84
|
+
else
|
85
|
+
#{cache_name_of(name)}[key] = #{org_name_of(name)}(*args)
|
86
|
+
end
|
87
|
+
else
|
88
|
+
if #{cache_name_of(name)}_forbidden ||= false
|
89
|
+
#{cache_name_of(name)}_forbidden = false
|
90
|
+
#{org_name_of(name)}(*args)
|
91
|
+
else
|
92
|
+
#{cache_name_of(name)}_initialized = true
|
93
|
+
#{cache_name_of(name)} = {}
|
94
|
+
#{cache_name_of(name)}[key] = #{org_name_of(name)}(*args)
|
59
95
|
end
|
60
96
|
end
|
61
97
|
end
|
62
98
|
EOS
|
63
99
|
end
|
64
100
|
|
65
|
-
def
|
101
|
+
def memoize_polynomial_method(name, key_indices)
|
66
102
|
save_memoizing_method(name)
|
67
|
-
|
103
|
+
prepare_polynomial_method_cache(name, key_indices)
|
68
104
|
class_eval <<-EOS
|
69
105
|
define_method(:#{name}) do |*args|
|
70
106
|
key = __key_for_#{name}(*args)
|
@@ -89,7 +125,7 @@ module AdLint #:nodoc:
|
|
89
125
|
EOS
|
90
126
|
end
|
91
127
|
|
92
|
-
def
|
128
|
+
def prepare_nullary_method_cache(name)
|
93
129
|
class_eval <<-EOS
|
94
130
|
define_method(:forbid_once_memo_of__#{name}) do
|
95
131
|
#{cache_name_of(name)}_forbidden = true
|
@@ -104,7 +140,24 @@ module AdLint #:nodoc:
|
|
104
140
|
EOS
|
105
141
|
end
|
106
142
|
|
107
|
-
def
|
143
|
+
def prepare_unary_method_cache(name, key_index)
|
144
|
+
class_eval <<-EOS
|
145
|
+
define_method(:forbid_once_memo_of__#{name}) do
|
146
|
+
#{cache_name_of(name)}_forbidden = true
|
147
|
+
end
|
148
|
+
define_method(:clear_memo_of__#{name}) do
|
149
|
+
#{cache_name_of(name)} = nil
|
150
|
+
#{cache_name_of(name)}_initialized = false
|
151
|
+
end
|
152
|
+
define_method(:forget_memo_of__#{name}) do |*args|
|
153
|
+
if #{cache_name_of(name)}_initialized
|
154
|
+
#{cache_name_of(name)}.delete(args[#{key_index}])
|
155
|
+
end
|
156
|
+
end
|
157
|
+
EOS
|
158
|
+
end
|
159
|
+
|
160
|
+
def prepare_polynomial_method_cache(name, key_indices)
|
108
161
|
define_key_generator(name, key_indices)
|
109
162
|
class_eval <<-EOS
|
110
163
|
define_method(:forbid_once_memo_of__#{name}) do
|
@@ -147,7 +200,7 @@ module AdLint #:nodoc:
|
|
147
200
|
end
|
148
201
|
|
149
202
|
def cache_name_of(name)
|
150
|
-
"@__cache_of__#{name.to_s.sub("?", "
|
203
|
+
"@__cache_of__#{name.to_s.sub("?", "P")}"
|
151
204
|
end
|
152
205
|
|
153
206
|
def org_name_of(name)
|
data/lib/adlint/prelude.rb
CHANGED
@@ -327,9 +327,9 @@ end
|
|
327
327
|
# string_item: "foo${VAR}baz"
|
328
328
|
#
|
329
329
|
class Psych::TreeBuilder < Psych::Handler
|
330
|
-
alias :
|
330
|
+
alias :_org_scalar :scalar
|
331
331
|
def scalar(value, anchor, tag, plain, quoted, style)
|
332
|
-
|
332
|
+
_org_scalar(substitute_environment_variables(value),
|
333
333
|
anchor, tag, plain, quoted, style)
|
334
334
|
end
|
335
335
|
|
data/lib/adlint/report.rb
CHANGED
@@ -248,7 +248,7 @@ module AdLint #:nodoc:
|
|
248
248
|
# Writes a function declaration information on the report.
|
249
249
|
#
|
250
250
|
# Abbreviation below is available.
|
251
|
-
#
|
251
|
+
# write_fundcl(...) => FUNDCL(...)
|
252
252
|
#
|
253
253
|
# === PARAMETER
|
254
254
|
# _loc_:: Location -- Location where the declaration appears.
|
@@ -259,11 +259,10 @@ module AdLint #:nodoc:
|
|
259
259
|
#
|
260
260
|
# === RETURN VALUE
|
261
261
|
# None.
|
262
|
-
def
|
263
|
-
write_code_struct(
|
264
|
-
fun_id))
|
262
|
+
def write_fundcl(loc, linkage, scope_type, dcl_type, fun_id)
|
263
|
+
write_code_struct(FunDcl.new(loc, linkage, scope_type, dcl_type, fun_id))
|
265
264
|
end
|
266
|
-
alias :
|
265
|
+
alias :FUNDCL :write_fundcl
|
267
266
|
|
268
267
|
# === DESCRIPTION
|
269
268
|
# Writes a variable definition information on the report.
|
@@ -291,7 +290,7 @@ module AdLint #:nodoc:
|
|
291
290
|
# Writes a function definition information on the report.
|
292
291
|
#
|
293
292
|
# Abbreviation below is available.
|
294
|
-
#
|
293
|
+
# write_fundef(...) => FUNDEF(...)
|
295
294
|
#
|
296
295
|
# === PARAMETER
|
297
296
|
# _loc_:: Location -- Location where the definition appears.
|
@@ -302,10 +301,10 @@ module AdLint #:nodoc:
|
|
302
301
|
#
|
303
302
|
# === RETURN VALUE
|
304
303
|
# None.
|
305
|
-
def
|
306
|
-
write_code_struct(
|
304
|
+
def write_fundef(loc, linkage, scope_type, fun_id, lines)
|
305
|
+
write_code_struct(FunDef.new(loc, linkage, scope_type, fun_id, lines))
|
307
306
|
end
|
308
|
-
alias :
|
307
|
+
alias :FUNDEF :write_fundef
|
309
308
|
|
310
309
|
# === DESCRIPTION
|
311
310
|
# Writes a macro definition information on the report.
|
@@ -399,16 +398,16 @@ module AdLint #:nodoc:
|
|
399
398
|
# Writes a function call information on the report.
|
400
399
|
#
|
401
400
|
# Abbreviation below is available.
|
402
|
-
#
|
401
|
+
# write_funcall(...) => FUNCALL(...)
|
403
402
|
#
|
404
403
|
# === PARAMETER
|
405
404
|
# _loc_:: Location -- Location where the function call appears.
|
406
405
|
# _caller_fun_:: FunctionId -- Calling function identifier.
|
407
406
|
# _callee_fun_:: FunctionId -- Called function identifier.
|
408
|
-
def
|
409
|
-
write_code_struct(
|
407
|
+
def write_funcall(loc, caller_fun, callee_fun)
|
408
|
+
write_code_struct(Funcall.new(loc, caller_fun, callee_fun))
|
410
409
|
end
|
411
|
-
alias :
|
410
|
+
alias :FUNCALL :write_funcall
|
412
411
|
|
413
412
|
# === DESCRIPTION
|
414
413
|
# Writes a variable cross reference information on the report.
|
@@ -444,7 +443,7 @@ module AdLint #:nodoc:
|
|
444
443
|
# === RETURN VALUE
|
445
444
|
# None.
|
446
445
|
def write_xref_function(loc, referrer, ref_type, fun)
|
447
|
-
write_code_struct(
|
446
|
+
write_code_struct(XRefFun.new(loc, referrer, ref_type, fun))
|
448
447
|
end
|
449
448
|
alias :XREF_FUNC :write_xref_function
|
450
449
|
|
data/lib/adlint/util.rb
CHANGED
data/lib/adlint/version.rb
CHANGED
data/share/doc/Makefile
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
MAKEINFO = makeinfo
|
2
|
+
DOT = dot
|
2
3
|
|
3
|
-
.SUFFIXES : .texi .html .txt
|
4
|
+
.SUFFIXES : .texi .html .txt .dot .pdf
|
4
5
|
|
5
6
|
.texi.html :
|
6
7
|
$(MAKEINFO) --html --no-split --css-include=texinfo.css -o $@ $<
|
@@ -8,7 +9,10 @@ MAKEINFO = makeinfo
|
|
8
9
|
.texi.txt :
|
9
10
|
$(MAKEINFO) --plaintext -o $@ $<
|
10
11
|
|
11
|
-
|
12
|
+
.dot.pdf :
|
13
|
+
$(DOT) -Tpdf -o $@ $<
|
14
|
+
|
15
|
+
TARGET = users_guide_ja.html users_guide_en.html developers_guide_ja.html c99gram.pdf
|
12
16
|
|
13
17
|
all : $(TARGET)
|
14
18
|
|