Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[enhancement] --cppcheckargs flag was missing #3978

Merged
merged 1 commit into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion analyzer/codechecker_analyzer/analyzers/cppcheck/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,14 @@
import os
import pickle
import re
import shlex
import shutil
import subprocess
import xml.etree.ElementTree as ET

from codechecker_common.logger import get_logger

from codechecker_analyzer import analyzer_context
from codechecker_analyzer import analyzer_context, env
from codechecker_analyzer.env import get_binary_in_path

from .. import analyzer_base
Expand Down Expand Up @@ -225,6 +226,8 @@ def construct_analyzer_cmd(self, result_handler):

analyzer_cmd.append('--plist-output=' + str(output_dir))

analyzer_cmd.extend(config.analyzer_extra_arguments)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like this line was already present a few lines up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, thanks for the comment!


analyzer_cmd.append(self.source_file)

return analyzer_cmd
Expand Down Expand Up @@ -389,6 +392,21 @@ def construct_config_handler(cls, args):

handler.analyzer_config = analyzer_config

try:
with open(args.cppcheck_args_cfg_file, 'r', encoding='utf8',
errors='ignore') as sa_cfg:
handler.analyzer_extra_arguments = \
re.sub(r'\$\((.*?)\)',
env.replace_env_var(args.cppcheck_args_cfg_file),
sa_cfg.read().strip())
handler.analyzer_extra_arguments = \
shlex.split(handler.analyzer_extra_arguments)
except IOError as ioerr:
LOG.debug_analyzer(ioerr)
except AttributeError as aerr:
# No cppcheck arguments file was given in the command line.
LOG.debug_analyzer(aerr)

check_env = context.analyzer_env

# Overwrite PATH to contain only the parent of the cppcheck binary.
Expand Down
7 changes: 7 additions & 0 deletions analyzer/codechecker_analyzer/cmd/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,13 @@ def add_arguments_to_parser(parser):

cmd_config.add_option(analyzer_opts)

analyzer_opts.add_argument('--cppcheckargs',
dest="cppcheck_args_cfg_file",
required=False,
default=argparse.SUPPRESS,
help="File containing argument which will be "
"forwarded verbatim for Cppcheck.")

analyzer_opts.add_argument('--saargs',
dest="clangsa_args_cfg_file",
required=False,
Expand Down
67 changes: 67 additions & 0 deletions analyzer/tests/unit/test_checker_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
from distutils import util
import os
import re
import tempfile
import unittest
from argparse import Namespace

from codechecker_analyzer.analyzers.clangsa.analyzer import ClangSA
from codechecker_analyzer.analyzers.clangtidy.analyzer import ClangTidy
from codechecker_analyzer.analyzers.cppcheck.analyzer import Cppcheck
from codechecker_analyzer.analyzers.config_handler import CheckerState
from codechecker_analyzer.analyzers.clangtidy.config_handler \
import is_compiler_warning
Expand Down Expand Up @@ -49,6 +51,9 @@ def occurring_values(self, label):
elif label == 'sei-cert':
return ['rule1', 'rule2']

def checkers(self, analyzer=None):
return []


def create_analyzer_sa():
args = []
Expand Down Expand Up @@ -434,3 +439,65 @@ def test_clang_diags_as_compiler_warnings(self):
# -Wno-unused-value.
self.assertEqual(cmd.count('-Wvla'), 1)
self.assertEqual(cmd.count('-Wvla-extension'), 1)


def create_analyzer_cppcheck(args, workspace):
cfg_handler = Cppcheck.construct_config_handler(args)

action = {
'file': 'main.cpp',
'command': "g++ -o main main.cpp",
'directory': workspace}
build_action = log_parser.parse_options(action)

return Cppcheck(cfg_handler, build_action)


class MockCppcheckCheckerLabels:
def checkers_by_labels(self, labels):
if labels[0] == 'profile:default':
return [
'cppcheck-argumentSize',
'cppcheck-arrayIndexOutOfBounds',
'cppcheck-assertWithSideEffect']

def get_description(self, label):
if label == 'profile':
return ['default', 'sensitive', 'security', 'portability',
'extreme']

def occurring_values(self, label):
if label == 'guideline':
return ['sei-cert']
elif label == 'sei-cert':
return ['rule1', 'rule2']

def checkers(self, analyzer):
return []


class CheckerHandlingCppcheckTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
context = analyzer_context.get_context()
context._checker_labels = MockCppcheckCheckerLabels()

def test_cppcheckargs(self):
"""
Check if the content of --cppcheckargs config file is properly passed
to the analyzer command.
"""
with tempfile.TemporaryDirectory() as tmp_ws:
cppcheckargs = os.path.join(tmp_ws, 'cppcheckargs')
with open(cppcheckargs, 'w',
encoding='utf-8', errors='ignore') as f:
f.write('--max-ctu-depth=42')

args = Namespace()
args.cppcheck_args_cfg_file = cppcheckargs

analyzer = create_analyzer_cppcheck(args, tmp_ws)
result_handler = create_result_handler(analyzer)
cmd = analyzer.construct_analyzer_cmd(result_handler)

self.assertIn('--max-ctu-depth=42', cmd)
8 changes: 4 additions & 4 deletions docs/analyzer/user_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -917,7 +917,7 @@ usage: CodeChecker analyze [-h] [-j JOBS]
[-n NAME] [--analyzers ANALYZER [ANALYZER ...]]
[--capture-analysis-output] [--generate-reproducer]
[--config CONFIG_FILE]
[--cppcheck-args CPPCHECK_ARGS_CFG_FILE]
[--cppcheckargs CPPCHECK_ARGS_CFG_FILE]
[--saargs CLANGSA_ARGS_CFG_FILE]
[--tidyargs TIDY_ARGS_CFG_FILE]
[--timeout TIMEOUT]
Expand Down Expand Up @@ -1122,9 +1122,9 @@ analyzer arguments:
For more information see the docs: https://github.com/
Ericsson/codechecker/tree/master/docs/config_file.md
(default: None)
--cppcheck-args CPPCHECK_ARGS_CFG_FILE
Configuration file to pass cppcheck command line
arguments.
--cppcheckargs CPPCHECK_ARGS_CFG_FILE
File containing argument which will be forwarded
verbatim for Cppcheck.
--saargs CLANGSA_ARGS_CFG_FILE
File containing argument which will be forwarded
verbatim for the Clang Static Analyzer.
Expand Down
Loading