From 2e2cf8e92a7381c381526fb04a743ac28cecb72b Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Wed, 4 Oct 2023 15:25:45 +0100 Subject: [PATCH 1/2] A16-0-1: Fix handling of else directives The #else family of directives were not treated as legitimate children of conditional preprocessor directives. This commit: * Updates #else to be universally acceptable. * Updates #elif to be acceptable within a conditional directive, while retaining the ability to report invalid conditions. --- change_notes/2023-10-04-a16-0-1-handle-else.md | 1 + ...essorShallOnlyBeUsedForCertainDirectivesPatterns.ql | 10 +++++++--- cpp/autosar/test/rules/A16-0-1/test.cpp | 6 ++++++ 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 change_notes/2023-10-04-a16-0-1-handle-else.md diff --git a/change_notes/2023-10-04-a16-0-1-handle-else.md b/change_notes/2023-10-04-a16-0-1-handle-else.md new file mode 100644 index 0000000000..28aa27edb2 --- /dev/null +++ b/change_notes/2023-10-04-a16-0-1-handle-else.md @@ -0,0 +1 @@ + * `A16-0-1` - address false positives by permitting #else and #elif within an otherwise valid #if preprocessor conditional. \ No newline at end of file diff --git a/cpp/autosar/src/rules/A16-0-1/PreProcessorShallOnlyBeUsedForCertainDirectivesPatterns.ql b/cpp/autosar/src/rules/A16-0-1/PreProcessorShallOnlyBeUsedForCertainDirectivesPatterns.ql index a8e1e59839..bd731db3e9 100644 --- a/cpp/autosar/src/rules/A16-0-1/PreProcessorShallOnlyBeUsedForCertainDirectivesPatterns.ql +++ b/cpp/autosar/src/rules/A16-0-1/PreProcessorShallOnlyBeUsedForCertainDirectivesPatterns.ql @@ -26,13 +26,14 @@ class PermittedDirectiveType extends PreprocessorDirective { //permissive listing in case directive types modelled in ql ever expands (example non valid directives) this instanceof MacroWrapper or this instanceof PreprocessorEndif or + this instanceof PreprocessorElse or this instanceof Include or this instanceof PermittedMacro } } pragma[noinline] -predicate isPreprocFileAndLine(Element pd, string filepath, int startLine) { +predicate isPreprocFileAndLine(Locatable pd, string filepath, int startLine) { pd.getLocation().hasLocationInfo(filepath, startLine, _, _, _) } @@ -49,7 +50,7 @@ predicate isPreprocConditionalRange( /** * An optimised version of `PreprocessorBranchDirective.getAGuard()`. */ -private PreprocessorBranch getAGuard(Element guardedElement) { +private PreprocessorBranch getAGuard(Locatable guardedElement) { exists(string filepath, int ifStartLine, int guardedElementStartLine, int endifStartLine | isPreprocConditionalRange(result, filepath, ifStartLine, endifStartLine) and isPreprocFileAndLine(guardedElement, filepath, guardedElementStartLine) and @@ -72,8 +73,11 @@ class MacroWrapper extends PreprocessorIfndef { class AcceptableWrapper extends PreprocessorBranch { AcceptableWrapper() { - forall(Element inner | not inner instanceof Comment and this = getAGuard(inner) | + forall(Locatable inner | not inner instanceof Comment and this = getAGuard(inner) | inner instanceof PermittedDirectiveType + or + // Ignore elifs, as they will be considered separately + inner instanceof PreprocessorElif ) } } diff --git a/cpp/autosar/test/rules/A16-0-1/test.cpp b/cpp/autosar/test/rules/A16-0-1/test.cpp index b1ee540032..b17d0daf52 100644 --- a/cpp/autosar/test/rules/A16-0-1/test.cpp +++ b/cpp/autosar/test/rules/A16-0-1/test.cpp @@ -17,3 +17,9 @@ int g; #ifndef TESTHEADER // COMPLIANT #include //COMPLIANT #endif // COMPLIANT + +#ifdef MACRO_ENABLED // COMPLIANT +#include "test1.h" //COMPLIANT +#else +#include "test2.h" //COMPLIANT +#endif \ No newline at end of file From a47f245dcac1aaea89c58de1d40c62a86727bff5 Mon Sep 17 00:00:00 2001 From: Luke Cartey Date: Wed, 4 Oct 2023 16:27:38 +0100 Subject: [PATCH 2/2] Add missing files --- cpp/autosar/test/rules/A16-0-1/test.h | 4 ++++ cpp/autosar/test/rules/A16-0-1/test2.h | 0 2 files changed, 4 insertions(+) create mode 100644 cpp/autosar/test/rules/A16-0-1/test.h create mode 100644 cpp/autosar/test/rules/A16-0-1/test2.h diff --git a/cpp/autosar/test/rules/A16-0-1/test.h b/cpp/autosar/test/rules/A16-0-1/test.h new file mode 100644 index 0000000000..a37243f616 --- /dev/null +++ b/cpp/autosar/test/rules/A16-0-1/test.h @@ -0,0 +1,4 @@ +#ifndef _TEST_HEADER_INCLUDE // COMPLIANT - header guard +#define _TEST_HEADER_INCLUDE // COMPLIANT +int x; +#endif // COMPLIANT \ No newline at end of file diff --git a/cpp/autosar/test/rules/A16-0-1/test2.h b/cpp/autosar/test/rules/A16-0-1/test2.h new file mode 100644 index 0000000000..e69de29bb2