Skip to content

Commit ee9defa

Browse files
committed
valueflow-fast: Added a --check-level=fast option.
1 parent fc6e9d3 commit ee9defa

File tree

5 files changed

+77
-100
lines changed

5 files changed

+77
-100
lines changed

cli/cmdlineparser.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,9 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
471471
else if (std::strncmp(argv[i], "--check-level=", 14) == 0) {
472472
Settings::CheckLevel level = Settings::CheckLevel::normal;
473473
const std::string level_s(argv[i] + 14);
474-
if (level_s == "normal")
474+
if (level_s == "reduced")
475+
level = Settings::CheckLevel::reduced;
476+
else if (level_s == "normal")
475477
level = Settings::CheckLevel::normal;
476478
else if (level_s == "exhaustive")
477479
level = Settings::CheckLevel::exhaustive;
@@ -947,6 +949,11 @@ CmdLineParser::Result CmdLineParser::parseFromArgs(int argc, const char* const a
947949
return Result::Fail;
948950
}
949951

952+
else if (std::strncmp(argv[i], "--performance-valueflow-max-iterations=", 39) == 0) {
953+
if (!parseNumberArg(argv[i], 39, mSettings.vfOptions.maxIterations, true))
954+
return Result::Fail;
955+
}
956+
950957
// Specify platform
951958
else if (std::strncmp(argv[i], "--platform=", 11) == 0) {
952959
const std::string platform(11+argv[i]);
@@ -1518,8 +1525,9 @@ void CmdLineParser::printHelp() const
15181525
" --check-config Check cppcheck configuration. The normal code\n"
15191526
" analysis is disabled by this flag.\n"
15201527
" --check-level=<level>\n"
1521-
" Configure how much checking you want:\n"
1522-
" * normal: Cppcheck uses some compromises in the checking so\n"
1528+
" Configure how much valueflow analysis you want:\n"
1529+
" * reduced: Reduce valueflow to finish checking quickly.\n"
1530+
" * normal: Cppcheck uses some compromises in the analysis so\n"
15231531
" the checking will finish in reasonable time.\n"
15241532
" * exhaustive: deeper analysis that you choose when you can\n"
15251533
" wait.\n"

lib/settings.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,16 @@ void Settings::loadSummaries()
299299

300300
void Settings::setCheckLevel(CheckLevel level)
301301
{
302-
if (level == CheckLevel::normal) {
302+
if (level == CheckLevel::reduced) {
303+
// Checking should finish quickly.
304+
checkLevel = level;
305+
vfOptions.maxSubFunctionArgs = 8;
306+
vfOptions.maxIfCount = 100;
307+
vfOptions.doConditionExpressionAnalysis = false;
308+
vfOptions.maxForwardBranches = 4;
309+
vfOptions.maxIterations = 1;
310+
}
311+
else if (level == CheckLevel::normal) {
303312
// Checking should finish in reasonable time.
304313
checkLevel = level;
305314
vfOptions.maxSubFunctionArgs = 8;

lib/settings.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,8 @@ class CPPCHECKLIB WARN_UNUSED Settings {
511511
return jobs == 1;
512512
}
513513

514-
enum class CheckLevel : std::uint8_t {
514+
enum class CheckLevel: std::uint8_t {
515+
reduced,
515516
normal,
516517
exhaustive
517518
};

tools/compare-normal-exhaustive.py renamed to tools/compare-valueflow-options.py

Lines changed: 51 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,20 @@ def format_float(a, b=1):
4646
os.makedirs(work_path)
4747

4848
lib.set_jobs('-j' + str(args.j))
49-
result_file = os.path.join(work_path, args.o)
50-
(f, ext) = os.path.splitext(result_file)
51-
timing_file = f + '_timing' + ext
52-
normal_results = f + '_normal' + ext
53-
exhaustive_results = f + '_exhaustive' + ext
54-
55-
if os.path.exists(result_file):
56-
os.remove(result_file)
57-
if os.path.exists(timing_file):
58-
os.remove(timing_file)
59-
if os.path.exists(normal_results):
60-
os.remove(normal_results)
61-
if os.path.exists(exhaustive_results):
62-
os.remove(exhaustive_results)
49+
50+
def results_file(name):
51+
f, ext = os.path.splitext(args.o)
52+
return os.path.join(work_path, f + '_' + name + ext)
53+
54+
opts = {'0': '--check-level=exhaustive --suppress=valueFlow*',
55+
'it2': '--check-level=exhaustive --performance-valueflow-max-iterations=2 --suppress=valueFlow*',
56+
'it1': '--check-level=exhaustive --performance-valueflow-max-iterations=1 --suppress=valueFlow*',
57+
'if8': '--check-level=exhaustive --performance-valueflow-max-if-count=8 --suppress=valueFlow*'}
58+
59+
for o in opts.keys():
60+
f = results_file(o)
61+
if os.path.exists(f):
62+
os.remove(f)
6363

6464
cppcheck_path = args.cppcheck_path
6565

@@ -117,95 +117,52 @@ def format_float(a, b=1):
117117
print("No files to process")
118118
continue
119119

120-
results_to_diff = []
120+
results_to_diff = list()
121+
timings = list()
121122

122-
normal_crashed = False
123-
exhaustive_crashed = False
124-
125-
normal_timeout = False
126-
exhaustive_timeout = False
123+
crashed = []
124+
timeout = []
127125

128126
enable = 'style'
129127
debug_warnings = False
130128

131129
libraries = lib.library_includes.get_libraries(source_path)
132-
c, errout, info, time_normal, cppcheck_options, timing_info = lib.scan_package(cppcheck_path, source_path, libraries, enable=enable, debug_warnings=debug_warnings, check_level='normal')
133-
if c < 0:
134-
if c == -101 and 'error: could not find or open any of the paths given.' in errout:
135-
# No sourcefile found (for example only headers present)
136-
print('Error: 101')
137-
elif c == lib.RETURN_CODE_TIMEOUT:
138-
print('Normal check level timed out!')
139-
normal_timeout = True
140-
continue # we don't want to compare timeouts
141-
else:
142-
print('Normal check level crashed!')
143-
normal_crashed = True
144-
results_to_diff.append(errout)
145-
146-
c, errout, info, time_exhaustive, cppcheck_options, timing_info = lib.scan_package(cppcheck_path, source_path, libraries, enable=enable, debug_warnings=debug_warnings, check_level='exhaustive')
147-
if c < 0:
148-
if c == -101 and 'error: could not find or open any of the paths given.' in errout:
149-
# No sourcefile found (for example only headers present)
150-
print('Error: 101')
151-
elif c == lib.RETURN_CODE_TIMEOUT:
152-
print('Exhaustive check level timed out!')
153-
exhaustive_timeout = True
154-
continue # we don't want to compare timeouts
155-
else:
156-
print('Exhaustive check level crashed!')
157-
exhaustive_crashed = True
158-
results_to_diff.append(errout)
159-
160-
if normal_crashed or exhaustive_crashed:
161-
who = None
162-
if normal_crashed and exhaustive_crashed:
163-
who = 'Both'
164-
elif normal_crashed:
165-
who = 'Normal'
166-
else:
167-
who = 'Exhaustive'
168-
crashes.append(package + ' ' + who)
169-
170-
if normal_timeout or exhaustive_timeout:
171-
who = None
172-
if normal_timeout and exhaustive_timeout:
173-
who = 'Both'
174-
elif normal_timeout:
175-
who = 'Normal'
176-
else:
177-
who = 'Exhaustive'
178-
timeouts.append(package + ' ' + who)
179-
180-
with open(result_file, 'a') as myfile:
181-
myfile.write(package + '\n')
182-
diff = lib.diff_results('normal', results_to_diff[0], 'exhaustive', results_to_diff[1])
183-
if not normal_crashed and not exhaustive_crashed and diff != '':
130+
131+
for id, extra_args in opts.items():
132+
print('scan:'+id)
133+
c, errout, info, time, cppcheck_options, timing_info = lib.scan_package(cppcheck_path, source_path, libraries, enable=enable, extra_args=extra_args)
134+
if c < 0:
135+
if c == -101 and 'error: could not find or open any of the paths given.' in errout:
136+
# No sourcefile found (for example only headers present)
137+
print('Error: 101')
138+
elif c == lib.RETURN_CODE_TIMEOUT:
139+
print(id + ' timed out!')
140+
timeout.append(id)
141+
continue # we don't want to compare timeouts
142+
else:
143+
print(f'{id} crashed! code={c}')
144+
crashed.append(id)
145+
results_to_diff.append(errout)
146+
timings.append(time)
147+
148+
if len(results_to_diff) <= 1:
149+
continue
150+
151+
r0 = results_to_diff[0]
152+
with open(results_file(id), 'a') as myfile:
153+
myfile.write(package + '\n')
154+
if id in crashed:
155+
myfile.write('Crash\n')
156+
elif id in timeout:
157+
myfile.write('Timeout\n')
158+
else:
159+
diff = lib.diff_results('0', r0, id, errout)
160+
if diff != '':
161+
myfile.write('diff:\n' + diff + '\n')
162+
myfile.write('time: %.1f %.1f\n' % (timings[0], time))
184163
myfile.write('libraries:' + ','.join(libraries) +'\n')
185-
myfile.write('diff:\n' + diff + '\n')
186-
187-
if not normal_crashed and not exhaustive_crashed:
188-
with open(timing_file, 'a') as myfile:
189-
package_width = '140'
190-
timing_width = '>7'
191-
myfile.write('{:{package_width}} {:{timing_width}} {:{timing_width}} {:{timing_width}}\n'.format(
192-
package, format_float(time_normal),
193-
format_float(time_exhaustive), format_float(time_normal, time_exhaustive),
194-
package_width=package_width, timing_width=timing_width))
195-
with open(normal_results, 'a') as myfile:
196-
myfile.write(results_to_diff[0])
197-
with open(exhaustive_results, 'a') as myfile:
198-
myfile.write(results_to_diff[1])
199164

200165
packages_processed += 1
201166
print(str(packages_processed) + ' of ' + str(args.p) + ' packages processed\n')
202167

203-
with open(result_file, 'a') as myfile:
204-
myfile.write('\n\ncrashes\n')
205-
myfile.write('\n'.join(crashes))
206-
207-
with open(result_file, 'a') as myfile:
208-
myfile.write('\n\ntimeouts\n')
209-
myfile.write('\n'.join(timeouts) + '\n')
210-
211168
print('Result saved to: ' + result_file)

tools/donate_cpu_lib.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ def __run_command(cmd, print_cmd=True):
436436
return return_code, stdout, stderr, elapsed_time
437437

438438

439-
def scan_package(cppcheck_path, source_path, libraries, capture_callstack=True, enable='style,information', debug_warnings=True, check_level=None):
439+
def scan_package(cppcheck_path, source_path, libraries, capture_callstack=True, enable='style,information', debug_warnings=True, check_level=None, extra_args=None):
440440
print('Analyze..')
441441
libs = ''
442442
for library in libraries:
@@ -453,6 +453,8 @@ def scan_package(cppcheck_path, source_path, libraries, capture_callstack=True,
453453
options += ' --disable=missingInclude --suppress=unmatchedSuppression'
454454
if check_level:
455455
options += ' --check-level=' + check_level
456+
if extra_args:
457+
options += ' ' + extra_args
456458
if debug_warnings:
457459
options += ' --check-library --debug-warnings --suppress=autoNoType --suppress=valueFlowBailout' \
458460
' --suppress=bailoutUninitVar --suppress=symbolDatabaseWarning --suppress=normalCheckLevelConditionExpressions'

0 commit comments

Comments
 (0)