From ce6709d26cd590513bf90256bd4cddc0f9e32903 Mon Sep 17 00:00:00 2001 From: Michael R Fairhurst Date: Wed, 18 Sep 2024 19:58:23 +0000 Subject: [PATCH] Fix #689, false negatives for A1-1-2 thinking -Wno-foo is compliant. The presence of -Wno-foo should not mark the compilation compliant with A1-1-2, nor should the presence of -Wfoo=0. Easily check for all -Wfoo=bar flags, that foo is not no-baz, and bar is not 0. Also check there is no -Wno-foo flag overruling it. Otherwise the query functionality remains the same. Add test cases for non-compliant scenarios -Wfoo=0 and -Wno-foo, and for the compliant scenario -Wall -Wno-foo. This will have some compatibility issues with PR #688, after one is merged the other will need some small updates before this can be merged. --- ...2024-09-18-handle-warning-suppresion-flags | 2 + .../CompilerWarningLevelNotInCompliance.ql | 51 ++++++++++++++++++- ...mpilerWarningLevelNotInCompliance.expected | 1 + .../CompilerWarningLevelNotInCompliance.qlref | 1 + .../Wformat=0-Wno-format-security.cpp | 2 + cpp/autosar/test/rules/A1-1-2.4/options.clang | 1 + cpp/autosar/test/rules/A1-1-2.4/options.gcc | 1 + cpp/autosar/test/rules/A1-1-2.4/options.qcc | 1 + ...mpilerWarningLevelNotInCompliance.expected | 1 + ...WarningLevelNotInCompliance.expected.clang | 0 ...erWarningLevelNotInCompliance.expected.gcc | 0 ...erWarningLevelNotInCompliance.expected.qcc | 1 + .../CompilerWarningLevelNotInCompliance.qlref | 1 + .../test/rules/A1-1-2.5/Wall-Wno-format.cpp | 14 +++++ cpp/autosar/test/rules/A1-1-2.5/options.clang | 1 + cpp/autosar/test/rules/A1-1-2.5/options.gcc | 1 + cpp/autosar/test/rules/A1-1-2.5/options.qcc | 1 + ...mpilerWarningLevelNotInCompliance.expected | 2 +- 18 files changed, 79 insertions(+), 3 deletions(-) create mode 100644 change_notes/2024-09-18-handle-warning-suppresion-flags create mode 100644 cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.expected create mode 100644 cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.qlref create mode 100644 cpp/autosar/test/rules/A1-1-2.4/Wformat=0-Wno-format-security.cpp create mode 100644 cpp/autosar/test/rules/A1-1-2.4/options.clang create mode 100644 cpp/autosar/test/rules/A1-1-2.4/options.gcc create mode 100644 cpp/autosar/test/rules/A1-1-2.4/options.qcc create mode 100644 cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected create mode 100644 cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.clang create mode 100644 cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.gcc create mode 100644 cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.qcc create mode 100644 cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.qlref create mode 100644 cpp/autosar/test/rules/A1-1-2.5/Wall-Wno-format.cpp create mode 100644 cpp/autosar/test/rules/A1-1-2.5/options.clang create mode 100644 cpp/autosar/test/rules/A1-1-2.5/options.gcc create mode 100644 cpp/autosar/test/rules/A1-1-2.5/options.qcc diff --git a/change_notes/2024-09-18-handle-warning-suppresion-flags b/change_notes/2024-09-18-handle-warning-suppresion-flags new file mode 100644 index 0000000000..12bf30e937 --- /dev/null +++ b/change_notes/2024-09-18-handle-warning-suppresion-flags @@ -0,0 +1,2 @@ +- `A1-1-2` - `CompilerWarningLevelNotInCompliance.ql`: + - Fixes #689 false negatives where '-Wno-foo' was treated as enabling, rather than disabling warnings. \ No newline at end of file diff --git a/cpp/autosar/src/rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql b/cpp/autosar/src/rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql index 60efab251a..55f67a9301 100644 --- a/cpp/autosar/src/rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql +++ b/cpp/autosar/src/rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql @@ -18,14 +18,61 @@ import cpp import codingstandards.cpp.autosar +predicate hasResponseFileArgument(Compilation c) { c.getAnArgument().matches("@%") } + class CompilationWithNoWarnings extends Compilation { CompilationWithNoWarnings() { getAnArgument() = "-w" or - not getAnArgument().regexpMatch("-W[\\w=-]+") + not exists(EnableWarningFlag enableFlag | + this.getAnArgument() = enableFlag and + not exists(DisableWarningFlag disableFlag | + this.getAnArgument() = disableFlag and + enableFlag.getWarningType() = disableFlag.getWarningType() + ) + ) } } -predicate hasResponseFileArgument(Compilation c) { c.getAnArgument().matches("@%") } +class CompilationArgument extends string { + Compilation compilation; + + CompilationArgument() { + this = compilation.getAnArgument() + } +} + +/** + * Compiler flags of type -Wfoo or -Wfoo=bar, which enables the `foo` warning. + */ +class EnableWarningFlag extends CompilationArgument { + string warningType; + + EnableWarningFlag() { + warningType = regexpCapture("^-W([\\w-]+)(=.*)?$", 1) + and not this instanceof DisableWarningFlag + } + + string getWarningType() { + result = warningType + } +} + +/** + * Compiler flags of type -Wno-foo or -Wfoo=0, which disables the `foo` warning + * and overrules -Wfoo. + */ +class DisableWarningFlag extends CompilationArgument { + string warningType; + + DisableWarningFlag() { + warningType = regexpCapture("^-Wno-([\\w-]+)", 1) or + warningType = regexpCapture("^-W([\\w-]+)=0", 1) + } + + string getWarningType() { + result = warningType + } +} from File f where diff --git a/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.expected b/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.expected new file mode 100644 index 0000000000..dd7f320be2 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.expected @@ -0,0 +1 @@ +| Wformat=0-Wno-format-security.cpp:0:0:0:0 | Wformat=0-Wno-format-security.cpp | No warning-level options were used in the compilation of 'Wformat=0-Wno-format-security.cpp'. | diff --git a/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.qlref b/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.qlref new file mode 100644 index 0000000000..30fb98b639 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.4/CompilerWarningLevelNotInCompliance.qlref @@ -0,0 +1 @@ +rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.4/Wformat=0-Wno-format-security.cpp b/cpp/autosar/test/rules/A1-1-2.4/Wformat=0-Wno-format-security.cpp new file mode 100644 index 0000000000..29523ad24e --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.4/Wformat=0-Wno-format-security.cpp @@ -0,0 +1,2 @@ +// semmle-extractor-options: --clang -std=c++14 -Wformat=0 -Wno-format-security +// NON_COMPLIANT \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.4/options.clang b/cpp/autosar/test/rules/A1-1-2.4/options.clang new file mode 100644 index 0000000000..4544f91ecb --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.4/options.clang @@ -0,0 +1 @@ +-Wformat=0 -Wno-format-security \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.4/options.gcc b/cpp/autosar/test/rules/A1-1-2.4/options.gcc new file mode 100644 index 0000000000..4544f91ecb --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.4/options.gcc @@ -0,0 +1 @@ +-Wformat=0 -Wno-format-security \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.4/options.qcc b/cpp/autosar/test/rules/A1-1-2.4/options.qcc new file mode 100644 index 0000000000..e28a2c3ac5 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.4/options.qcc @@ -0,0 +1 @@ +-Wno-format -Wno-format-security \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected new file mode 100644 index 0000000000..df69d21d5a --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected @@ -0,0 +1 @@ +| Wall-Wno-format.cpp:0:0:0:0 | Wall-Wno-format.cpp | No warning-level options were used in the compilation of 'Wall-Wno-format.cpp'. | \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.clang b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.clang new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.gcc b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.gcc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.qcc b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.qcc new file mode 100644 index 0000000000..c6354c2475 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.expected.qcc @@ -0,0 +1 @@ +| Wall-Wno-format.cpp:0:0:0:0 | Wall-Wno-format.cpp | No warning-level options were used in the compilation of 'Wall-Wno-format.cpp'. | diff --git a/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.qlref b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.qlref new file mode 100644 index 0000000000..30fb98b639 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.5/CompilerWarningLevelNotInCompliance.qlref @@ -0,0 +1 @@ +rules/A1-1-2/CompilerWarningLevelNotInCompliance.ql \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.5/Wall-Wno-format.cpp b/cpp/autosar/test/rules/A1-1-2.5/Wall-Wno-format.cpp new file mode 100644 index 0000000000..93c4b98248 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.5/Wall-Wno-format.cpp @@ -0,0 +1,14 @@ +// semmle-extractor-options: --clang -std=c++14 -Wall -Wno-format +// COMPLIANT + +// NOTE: When tested with `codeql test run`, the test extractor provides `-w` +// which overrides `-Wcast-function-type` and causes this test case to be +// non-compliant. +// +// However, when tested with our compiler matrix tests, this test db is built +// via `codeql database create --command="..."`, and the `-w` flag will NOT be +// used. This means the `-Wcast-function-type` flag is active and the test case +// is compliant. +// +// Therefore, the .expected file for this test expects non-compliance, and the +// .expected.gcc and .expected.clang files expect this test to be compliant. diff --git a/cpp/autosar/test/rules/A1-1-2.5/options.clang b/cpp/autosar/test/rules/A1-1-2.5/options.clang new file mode 100644 index 0000000000..735817b680 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.5/options.clang @@ -0,0 +1 @@ +-Wall -Wno-format \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.5/options.gcc b/cpp/autosar/test/rules/A1-1-2.5/options.gcc new file mode 100644 index 0000000000..735817b680 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.5/options.gcc @@ -0,0 +1 @@ +-Wall -Wno-format \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2.5/options.qcc b/cpp/autosar/test/rules/A1-1-2.5/options.qcc new file mode 100644 index 0000000000..735817b680 --- /dev/null +++ b/cpp/autosar/test/rules/A1-1-2.5/options.qcc @@ -0,0 +1 @@ +-Wall -Wno-format \ No newline at end of file diff --git a/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected b/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected index 82ff1c0c36..ddc4e03f62 100644 --- a/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected +++ b/cpp/autosar/test/rules/A1-1-2/CompilerWarningLevelNotInCompliance.expected @@ -1 +1 @@ -| Wall.cpp:0:0:0:0 | Wall.cpp | No warning-level options were used in the compilation of 'Wall.cpp'. | \ No newline at end of file +| Wall.cpp:0:0:0:0 | Wall.cpp | No warning-level options were used in the compilation of 'Wall.cpp'. |