[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH 2/4] xen/scripts: add cppcheck tool to the xen-analysis.py script
Hi Stefano, > I think the revert of the cppcheck integration in xen/Makefile and > xen/tools/merge_cppcheck_reports.py could be a separate patch. There is > no need to make sure cppcheck support in the xen Makefile is > "bisectable". That patch could have my acked-by already. Ok I will split these changes in a following patch > > Also the document changes introduced in this patch have my reviewed-by: > - docs/misra/cppcheck.txt > - docs/misra/documenting-violations.rst > - docs/misra/false-positive-cppcheck.json > - docs/misra/xen-static-analysis.rst Thank you, should I put those files in a separate patch with your rev-by before this patch or this is just a comment for you to remember which file you already reviewed? >> >> + >> +def generate_cppcheck_deps(): >> + global cppcheck_extra_make_args >> + >> + # Compile flags to pass to cppcheck: >> + # - include config.h as this is passed directly to the compiler. >> + # - define CPPCHECK as we use it to disable or enable some specific >> part of >> + # the code to solve some cppcheck issues. >> + # - explicitely enable some cppcheck checks as we do not want to use >> "all" >> + # which includes unusedFunction which gives wrong positives as we >> check >> + # file per file. >> + # - Explicitly suppress warnings on compiler-def.h because cppcheck >> throws >> + # an unmatchedSuppression due to the rule we put in >> suppression-list.txt >> + # to skip every finding in the file. >> + # >> + # Compiler defines are in compiler-def.h which is included in config.h >> + # >> + cppcheck_flags=""" >> +--cppcheck-build-dir={}/{} >> + --max-ctu-depth=10 >> + --enable=style,information,missingInclude >> + >> --template=\'{{file}}({{line}},{{column}}):{{id}}:{{severity}}:{{message}}\' >> + --relative-paths={} >> + --inline-suppr >> + --suppressions-list={}/suppression-list.txt >> + --suppress='unmatchedSuppression:*generated/compiler-def.h' >> + --include={}/include/xen/config.h > > I noticed that some of the includes we used to have like > xsm/flask/include are missing here. Is that intended? Yes it is, now that cppcheck is using the JSON compilation database, it can understand by the compilation argument “-I” what include path it needs to add, before we were adding it to every file, resulting in some false positive from the tool. Just --include={}/include/xen/config.h is needed because in the Xen makefile we are doing the same, passing the option to the compiler, resulting in every compiled file to have that header included. >> >> + case ${OPTION} in >> + -h|--help) >> + help >> + exit 0 >> + ;; >> + --compiler=*) >> + COMPILER="$(eval echo "${OPTION#*=}")" > > This can be: > > COMPILER="${OPTION#*=}" > > and same for all the other below Ok I’ll fix that > > >> + sm_tool_args="n" >> + ;; >> + --cppcheck-cmd=*) >> + CPPCHECK_TOOL="$(eval echo "${OPTION#*=}")" >> + sm_tool_args="y" >> + ;; >> + --cppcheck-html) >> + CPPCHECK_HTML="y" >> + sm_tool_args="n" >> + ;; >> + --cppcheck-plat=*) >> + CPPCHECK_PLAT_PATH="$(eval echo "${OPTION#*=}")" >> + sm_tool_args="n" >> + ;; >> + --ignore-path=*) >> + IGNORE_PATH_LIST="${IGNORE_PATH_LIST} $(eval echo >> "${OPTION#*=}")" >> + sm_tool_args="n" >> + ;; >> + --) >> + forward_to_cc="y" >> + sm_tool_args="n" >> + ;; >> + *) >> + if [ "${sm_tool_args}" = "y" ]; then >> + CPPCHECK_TOOL_ARGS="${CPPCHECK_TOOL_ARGS} ${OPTION}" >> + else >> + echo "Invalid option ${OPTION}" >> + exit 1 > > It doesn't look like sm_tool_args is really needed? It is only set to > 'y' in the case of --cppcheck-cmd, and in that case we also set > CPPCHECK_TOOL. CPPCHECK_TOOL is the variable used below. Am I missing > something? We use sm_tool_args to fill CPPCHECK_TOOL_ARGS, basically it’s a state machine where when we find --cppcheck-cmd=<xxx> we expect that every other space separated arguments passed afterwards are the args for cppcheck, so we append to CPPCHECK_TOOL_ARGS until we find an argument that is supposed to be only for this script. > > >> + fi >> + ;; >> + esac >> +done >> + >> +if [ "${COMPILER}" = "" ] >> +then >> + echo "--compiler arg is mandatory." >> + exit 1 >> +fi >> + >> +function print_file() { >> + local text="${1}" >> + local init_file="${2}" >> + >> + if [ "${init_file}" = "y" ] >> + then >> + echo -e -n "${text}" > "${JDB_FILE}" >> + else >> + echo -e -n "${text}" >> "${JDB_FILE}" >> + fi > > The >> can be used to create a file if the file is not already present. > So why the need for this if? In fact, we don't need print_file at all > and we can just > > echo -e -n "something" >> "${JDB_FILE}" > > directly from create_jcd. If you are concerned about a preexisting file, > then at the beginning of create_jcd you can: > > rm "${JDB_FILE}" Ok I’ll remove the file in the top of create_jcd and use echo -e -n "something" >> "${JDB_FILE}” >> >> + >> + # Check wchar size >> + wchar_plat_suffix="t4" >> + # sed prints the last occurence of -f(no-)short-wchar which is the >> one >> + # applied to the file by the compiler >> + wchar_option=$(echo "${FORWARD_FLAGS}" | \ >> + sed -nre 's,.*(-f(no-)?short-wchar).*,\1,p') >> + if [ "${wchar_option}" = "-fshort-wchar" ] >> + then >> + wchar_plat_suffix="t2" >> + fi > > This seems a bit unnecessary: we should be able to find the right > platform file from XEN_TARGET_ARCH alone. No need to reverse engineer > the compiler command line? The efi code is compiled with -fshort-wchar, but the rest of the file uses default length wchar, now maybe it was a bit of overthinking because I guess we have only these cases: arm64: arm64-wchar_t2 (efi code uses -fshort-wchar) arm32: arm32-wchar_t4 (efi code is not in, but common-stub compiled with -f-no-short-wchar) x86_64: x86_64-wchar_t2 (efi code uses -fshort-wchar) Am I right? > > >> + >> + # Select the right target platform, ARCH is generated from Xen >> Makefile >> + >> platform="${CPPCHECK_PLAT_PATH}/${ARCH}-wchar_${wchar_plat_suffix}.xml" >> + if [ ! -f "${platform}" ] >> + then >> + echo "${platform} not found!" >> + exit 1 >> + fi >> + >> + # Shellcheck complains about missing quotes on CPPCHECK_TOOL_ARGS, >> but >> + # they can't be used here >> + # shellcheck disable=SC2086 >> + ${CPPCHECK_TOOL} ${CPPCHECK_TOOL_ARGS} \ >> + --project="${JDB_FILE}" \ >> + --output-file="${out_file}" \ >> + --platform=${platform} >> + >> + if [ "${CPPCHECK_HTML}" = "y" ] >> + then >> + # Shellcheck complains about missing quotes on >> CPPCHECK_TOOL_ARGS, >> + # but they can't be used here >> + # shellcheck disable=SC2086 >> + ${CPPCHECK_TOOL} ${CPPCHECK_TOOL_ARGS} \ >> + --project="${JDB_FILE}" \ >> + --output-file="${out_file%.txt}.xml" \ >> + --platform=${platform} \ >> + -q \ >> + --xml > > This is showing my ignorance in cppcheck, but does it actually need to > be called twice in the html generation case? Actually three times if we > count the extra cppcheck-htmlreport call? Cppcheck is not able to output a text report and an XML report at the same time, hence we need to call it twice, but the second call will use the cppcheck build directory As a “cache” to generate the results so it will be much more faster than the first one. > > >> + fi >> + fi >> +fi >> diff --git a/xen/tools/cppcheck-plat/arm32-wchar_t4.xml >> b/xen/tools/cppcheck-plat/arm32-wchar_t4.xml >> new file mode 100644 >> index 000000000000..3aefa7ba5c98 >> --- /dev/null >> +++ b/xen/tools/cppcheck-plat/arm32-wchar_t4.xml >> @@ -0,0 +1,17 @@ >> +<?xml version="1.0"?> >> +<platform> >> + <char_bit>8</char_bit> >> + <default-sign>unsigned</default-sign> > > usually in C the default is actually "signed" not "unsigned". If you > write: > > int i; > > i is signed It took me a bit to understand this field, as the documentation is not clear at all, the default-sign is referring to the default char sign, which should be unsigned for arm, right? Here the code to cppcheck that clarifies the field: https://github.com/danmar/cppcheck/blob/2.7.5/lib/platform.cpp At line 204, defaultSign is taking the value of <default-sign>, at line 64, when the platform is Native, defaultSign = (std::numeric_limits<char>::is_signed) ? 's' : 'u'; I’ve done some tests with this code in arm/arm64/x86_64: #define is_type_signed(my_type) (((my_type)-1) < 0) if (is_type_signed(char)) printf("signed\n"); else printf("unsigned\n"); And I have unsigned for arm/arm64 and signed for x86_64 (which I will change as it is wrong in this patch) Can you confirm my results are right? >> >> +++ b/xen/tools/cppcheck-plat/arm64-wchar_t2.xml >> @@ -0,0 +1,17 @@ >> +<?xml version="1.0"?> >> +<platform> >> + <char_bit>8</char_bit> >> + <default-sign>unsigned</default-sign> >> + <sizeof> >> + <short>2</short> >> + <int>4</int> >> + <long>8</long> >> + <long-long>8</long-long> >> + <float>4</float> >> + <double>8</double> >> + <long-double>16</long-double> >> + <pointer>8</pointer> >> + <size_t>4</size_t> > > Isn't size_t 8 bytes on arm64? Yes you are right, I will fix it > > >> + <wchar_t>2</wchar_t> >> + </sizeof> >> +</platform>
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |