-
Notifications
You must be signed in to change notification settings - Fork 73
Add linkage1 package #1016
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
base: main
Are you sure you want to change the base?
Add linkage1 package #1016
Changes from all commits
e32ee19
70375b4
b321608
179e8b7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| - `A3-1-4` - `ExternalLinkageArrayWithoutExplicitSizeAutosar.ql`: | ||
| - `ExternalLinkageArrayWithoutExplicitSize.ql` has been renamed to `ExternalLinkageArrayWithoutExplicitSizeAutosar.ql` to reflect shared query implementation. Additionally the query previously only detected explicit uses of `extern` to determine external linkage, and now would catch other cases that are possible where it is external linkage and an array is declared without an explicit size. | ||
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /** | ||
| * @id cpp/autosar/external-linkage-array-without-explicit-size-autosar | ||
| * @name A3-1-4: When an array with external linkage is declared, its size shall be stated explicitly | ||
| * @description A developer can more safely access the elements of an array if the size of the array | ||
| * can be explicitly determined. | ||
| * @kind problem | ||
| * @precision very-high | ||
| * @problem.severity warning | ||
| * @tags external/autosar/id/a3-1-4 | ||
| * correctness | ||
| * external/autosar/allocated-target/design | ||
| * external/autosar/allocated-target/implementation | ||
| * external/autosar/enforcement/automated | ||
| * external/autosar/obligation/required | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.cpp.autosar | ||
| import codingstandards.cpp.rules.externallinkagearraywithoutexplicitsize.ExternalLinkageArrayWithoutExplicitSize | ||
|
|
||
| class ExternalLinkageArrayWithoutExplicitSizeAutosarQuery extends ExternalLinkageArrayWithoutExplicitSizeSharedQuery | ||
| { | ||
| ExternalLinkageArrayWithoutExplicitSizeAutosarQuery() { | ||
| this = ScopePackage::externalLinkageArrayWithoutExplicitSizeAutosarQuery() | ||
| } | ||
| } |
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| cpp/common/test/rules/externallinkagearraywithoutexplicitsize/ExternalLinkageArrayWithoutExplicitSize.ql |
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| cpp/common/test/rules/externallinkagenotdeclaredinheaderfile/ExternalLinkageNotDeclaredInHeaderFile.ql |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| //** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ | ||
| import cpp | ||
| import RuleMetadata | ||
| import codingstandards.cpp.exclusions.RuleMetadata | ||
|
|
||
| newtype Linkage1Query = | ||
| TExternalLinkageArrayWithoutExplicitSizeMisraQuery() or | ||
| TExternalLinkageNotDeclaredInHeaderFileMisraQuery() | ||
|
|
||
| predicate isLinkage1QueryMetadata(Query query, string queryId, string ruleId, string category) { | ||
| query = | ||
| // `Query` instance for the `externalLinkageArrayWithoutExplicitSizeMisra` query | ||
| Linkage1Package::externalLinkageArrayWithoutExplicitSizeMisraQuery() and | ||
| queryId = | ||
| // `@id` for the `externalLinkageArrayWithoutExplicitSizeMisra` query | ||
| "cpp/misra/external-linkage-array-without-explicit-size-misra" and | ||
| ruleId = "RULE-6-0-2" and | ||
| category = "advisory" | ||
| or | ||
| query = | ||
| // `Query` instance for the `externalLinkageNotDeclaredInHeaderFileMisra` query | ||
| Linkage1Package::externalLinkageNotDeclaredInHeaderFileMisraQuery() and | ||
| queryId = | ||
| // `@id` for the `externalLinkageNotDeclaredInHeaderFileMisra` query | ||
| "cpp/misra/external-linkage-not-declared-in-header-file-misra" and | ||
| ruleId = "RULE-6-5-1" and | ||
| category = "advisory" | ||
| } | ||
|
|
||
| module Linkage1Package { | ||
| Query externalLinkageArrayWithoutExplicitSizeMisraQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `externalLinkageArrayWithoutExplicitSizeMisra` query | ||
| TQueryCPP(TLinkage1PackageQuery(TExternalLinkageArrayWithoutExplicitSizeMisraQuery())) | ||
| } | ||
|
|
||
| Query externalLinkageNotDeclaredInHeaderFileMisraQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `externalLinkageNotDeclaredInHeaderFileMisra` query | ||
| TQueryCPP(TLinkage1PackageQuery(TExternalLinkageNotDeclaredInHeaderFileMisraQuery())) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,29 @@ | ||||||||||
| /** | ||||||||||
| * Provides a library with a `problems` predicate for the following issue: | ||||||||||
| * Introducing a function or object with external linkage outside of a header file can | ||||||||||
| * cause developer confusion about its translation unit access semantics. | ||||||||||
|
Comment on lines
+3
to
+4
|
||||||||||
| * Introducing a function or object with external linkage outside of a header file can | |
| * cause developer confusion about its translation unit access semantics. | |
| * Declaring an array with external linkage without explicitly specifying its size | |
| * can lead to unclear or inconsistent expectations about the array's bounds. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems copilot is right here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised that hasArraySize was working before..!
Below are a bunch of thoughts that kind of go down a rabbit hole. Consider it 100% up to you how you want to proceed -- you could file a bug and copy my comment, or you can explore it, add tests, etc.
We may not be able to do much about it, but it may be worth adding some .hpp test cases to see if the following are FNs:
// test.hpp
int header_only[]; // NON_COMPLIANT
int header_and_cpp[]; // NON_COMPLIANT
// test.cpp
#include "test.hpp"
// definition associated with a declaration from test.hpp
int header_and_cpp[10] = ...
Basically, I fear that header_and_cpp[] will be a false negative. It should be extracted as one Variable, with one Type -- that type probably being an int array of size 10.
If this is a FN we can write NON_COMPLIANT[False negative] along with an explanatory comment, and I'm not sure if we have any recourse to fix it if so. However, we likely don't have to fix it.....if it is a FN, we probably also want to add a test like:
// test.hpp
// an array declaration that's defined in test1.cpp but not test2.cpp
int defined_in_test1_cpp[]; // NON_COMPLIANT
// test1.cpp
int defined_in_test1_cpp[10] = ...;
// test2.cpp
// This file exists to _not_ do the following:
// int defined_in_test1_cpp[10] = ...;
// So that we can test that a violation of the One Definition Rule is caught in this case
My guess is that this will be correctly reported as non compliant because we would have two variables (a violation of ODR), and one would have no size. This would means the NON_COMPLIANT[False negative] is low impact.
Let me know if any of this is unclear, feel free to reach out via chat etc. Up to you what next steps you think may be best!
Copilot
AI
Jan 15, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Grammatical error: "Holds is if" should be "Holds if". Remove the word "is".
| // Holds is if declEntry is an array variable declaration (not a definition) | |
| // Holds if declEntry is an array variable declaration (not a definition) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /** | ||
| * Provides a library with a `problems` predicate for the following issue: | ||
| * Using objects or functions with external linkage in implementation files makes code | ||
| * harder to understand. | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.cpp.Customizations | ||
| import codingstandards.cpp.Exclusions | ||
| import codingstandards.cpp.Linkage | ||
| import codingstandards.cpp.EncapsulatingFunctions | ||
|
|
||
| abstract class ExternalLinkageNotDeclaredInHeaderFileSharedQuery extends Query { } | ||
|
|
||
| Query getQuery() { result instanceof ExternalLinkageNotDeclaredInHeaderFileSharedQuery } | ||
|
|
||
| query predicate problems(DeclarationEntry de, string message) { | ||
| not isExcluded(de, getQuery()) and | ||
| hasExternalLinkage(de.getDeclaration()) and | ||
| // Exclude subobjects such as struct members or member functions | ||
| de.getDeclaration().isTopLevel() and | ||
| // The declaration with external linkage does not have a declaration in a header file | ||
| exists(Compilation c | de.getFile() = c.getAFileCompiled()) and | ||
| not exists(DeclarationEntry otherDe | | ||
| de.getDeclaration() = otherDe.getDeclaration() and | ||
| not de = otherDe and | ||
| not otherDe.isDefinition() | ||
| | | ||
| otherDe.getFile() instanceof HeaderFile | ||
| ) and | ||
| // Main functions are an exception to the rule | ||
| not de.getDeclaration() instanceof MainFunction and | ||
| if de.getDeclaration() instanceof Function | ||
| then message = "Externally linked function '" + de.getName() + "' not declared in header file." | ||
| else message = "Externally linked object '" + de.getName() + "' not declared in header file." | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| | test.cpp:19:14:19:15 | declaration of e1 | The declared array 'e1' with external linkage doesn't specify the size explicitly. | |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| // GENERATED FILE - DO NOT MODIFY | ||
| import codingstandards.cpp.rules.externallinkagearraywithoutexplicitsize.ExternalLinkageArrayWithoutExplicitSize | ||
|
|
||
| class TestFileQuery extends ExternalLinkageArrayWithoutExplicitSizeSharedQuery, TestQuery { } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| #define TEST 1 | ||
|
|
||
| // globals - external linkage | ||
| int a[1]; // COMPLIANT | ||
| int x = 1; | ||
| // int a1[1 + x]; // NON_COMPLIANT - compiler checked | ||
| // int a2[x]; //NON_COMPLIANT - compiler checked | ||
| // int a3[1][x]; // NON_COMPLIANT - compiler checked | ||
| int a4[] = {1}; // COMPLIANT - size explicitly provided | ||
| // int a5[]; // NON_COMPLIANT - compiler checked | ||
| int a6[1 + 1]; // COMPLIANT - size explicitly provided | ||
| // int a7[x][1]; // NON_COMPLIANT - compiler checked | ||
| // int (*a8)[x]; // NON_COMPLIANT - compiler checked | ||
|
|
||
| void f(int n) { | ||
| int a1[] = {1}; // COMPLIANT - not external linkage | ||
| int a2[1]; // COMPLIANT - not external linkage | ||
|
|
||
| extern int e1[]; // NON_COMPLIANT | ||
| } | ||
|
|
||
| struct s { | ||
| // Structs must have at least one non-flexible array member. | ||
| int foo; | ||
|
|
||
| // static data members have external linkage - but not currently detected in | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you add a case for this? |
||
| // our external linkage lib - also FAMs are not in scope for this rule | ||
| static const int flexibleArrayMember[]; // COMPLIANT | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| // GENERATED FILE - DO NOT MODIFY | ||
| import codingstandards.cpp.rules.externallinkagenotdeclaredinheaderfile.ExternalLinkageNotDeclaredInHeaderFile | ||
|
|
||
| class TestFileQuery extends ExternalLinkageNotDeclaredInHeaderFileSharedQuery, TestQuery { } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /** | ||
| * @id cpp/misra/external-linkage-array-without-explicit-size-misra | ||
| * @name RULE-6-0-2: Arrays with external linkage declared without explicit size shall not be used | ||
| * @description Declaring an array with external linkage without its size being explicitly specified | ||
| * can disallow consistency and range checks on the array size and usage. | ||
| * @kind problem | ||
| * @precision very-high | ||
| * @problem.severity warning | ||
| * @tags external/misra/id/rule-6-0-2 | ||
| * maintainability | ||
| * readability | ||
| * scope/single-translation-unit | ||
| * external/misra/enforcement/decidable | ||
| * external/misra/obligation/advisory | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.cpp.misra | ||
| import codingstandards.cpp.rules.externallinkagearraywithoutexplicitsize.ExternalLinkageArrayWithoutExplicitSize | ||
|
|
||
| class ExternalLinkageArrayWithoutExplicitSizeMisraQuery extends ExternalLinkageArrayWithoutExplicitSizeSharedQuery | ||
| { | ||
| ExternalLinkageArrayWithoutExplicitSizeMisraQuery() { | ||
| this = Linkage1Package::externalLinkageArrayWithoutExplicitSizeMisraQuery() | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| /** | ||
| * @id cpp/misra/external-linkage-not-declared-in-header-file-misra | ||
| * @name RULE-6-5-1: Objects or functions with external linkage shall be declared in a header file | ||
| * @description Using objects or functions with external linkage in implementation files makes code | ||
| * harder to understand. | ||
| * @kind problem | ||
| * @precision very-high | ||
| * @problem.severity warning | ||
| * @tags external/misra/id/rule-6-5-1 | ||
| * correctness | ||
| * maintainability | ||
| * readability | ||
| * scope/single-translation-unit | ||
| * external/misra/enforcement/decidable | ||
| * external/misra/obligation/advisory | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.cpp.misra | ||
| import codingstandards.cpp.rules.externallinkagenotdeclaredinheaderfile.ExternalLinkageNotDeclaredInHeaderFile | ||
|
|
||
| class ExternalLinkageNotDeclaredInHeaderFileMisraQuery extends ExternalLinkageNotDeclaredInHeaderFileSharedQuery | ||
| { | ||
| ExternalLinkageNotDeclaredInHeaderFileMisraQuery() { | ||
| this = Linkage1Package::externalLinkageNotDeclaredInHeaderFileMisraQuery() | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very nice to catch and fix this!