Skip to content
Open
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
2 changes: 2 additions & 0 deletions change_notes/2026-01-15-a3-1-4-extern-to-full.md
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()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,11 @@

import cpp
import codingstandards.cpp.autosar
import codingstandards.cpp.Linkage
import codingstandards.cpp.EncapsulatingFunctions
import codingstandards.cpp.rules.externallinkagenotdeclaredinheaderfile.ExternalLinkageNotDeclaredInHeaderFile

from DeclarationEntry de, string kind
where
not isExcluded(de, IncludesPackage::externalLinkageNotDeclaredInHeaderFileQuery()) 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 kind = "function" else kind = "object"
select de, "Externally linked " + kind + " '" + de.getName() + "' not declared in header file."
class ExternalLinkageNotDeclaredInHeaderFileQuery extends ExternalLinkageNotDeclaredInHeaderFileSharedQuery
{
ExternalLinkageNotDeclaredInHeaderFileQuery() {
this = IncludesPackage::externalLinkageNotDeclaredInHeaderFileQuery()
}
}

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
8 changes: 0 additions & 8 deletions cpp/autosar/test/rules/A3-1-4/test.cpp

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
44 changes: 44 additions & 0 deletions cpp/common/src/codingstandards/cpp/exclusions/cpp/Linkage1.qll
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
Expand Up @@ -34,6 +34,7 @@ import IntegerConversion
import Invariants
import Iterators
import Lambdas
import Linkage1
import Literals
import Loops
import Macros
Expand Down Expand Up @@ -96,6 +97,7 @@ newtype TCPPQuery =
TInvariantsPackageQuery(InvariantsQuery q) or
TIteratorsPackageQuery(IteratorsQuery q) or
TLambdasPackageQuery(LambdasQuery q) or
TLinkage1PackageQuery(Linkage1Query q) or
TLiteralsPackageQuery(LiteralsQuery q) or
TLoopsPackageQuery(LoopsQuery q) or
TMacrosPackageQuery(MacrosQuery q) or
Expand Down Expand Up @@ -158,6 +160,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isInvariantsQueryMetadata(query, queryId, ruleId, category) or
isIteratorsQueryMetadata(query, queryId, ruleId, category) or
isLambdasQueryMetadata(query, queryId, ruleId, category) or
isLinkage1QueryMetadata(query, queryId, ruleId, category) or
isLiteralsQueryMetadata(query, queryId, ruleId, category) or
isLoopsQueryMetadata(query, queryId, ruleId, category) or
isMacrosQueryMetadata(query, queryId, ruleId, category) or
Expand Down
16 changes: 8 additions & 8 deletions cpp/common/src/codingstandards/cpp/exclusions/cpp/Scope.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import codingstandards.cpp.exclusions.RuleMetadata

newtype ScopeQuery =
TNonStandardEntitiesInStandardNamespacesQuery() or
TExternalLinkageArrayWithoutExplicitSizeQuery() or
TExternalLinkageArrayWithoutExplicitSizeAutosarQuery() or
THiddenInheritedNonOverridableMemberFunctionQuery() or
THiddenInheritedOverridableMemberFunctionQuery() or
TDefinitionNotConsideredForUnqualifiedLookupQuery() or
Expand Down Expand Up @@ -33,11 +33,11 @@ predicate isScopeQueryMetadata(Query query, string queryId, string ruleId, strin
category = "required"
or
query =
// `Query` instance for the `externalLinkageArrayWithoutExplicitSize` query
ScopePackage::externalLinkageArrayWithoutExplicitSizeQuery() and
// `Query` instance for the `externalLinkageArrayWithoutExplicitSizeAutosar` query
ScopePackage::externalLinkageArrayWithoutExplicitSizeAutosarQuery() and
queryId =
// `@id` for the `externalLinkageArrayWithoutExplicitSize` query
"cpp/autosar/external-linkage-array-without-explicit-size" and
// `@id` for the `externalLinkageArrayWithoutExplicitSizeAutosar` query
"cpp/autosar/external-linkage-array-without-explicit-size-autosar" and
ruleId = "A3-1-4" and
category = "required"
or
Expand Down Expand Up @@ -185,11 +185,11 @@ module ScopePackage {
TQueryCPP(TScopePackageQuery(TNonStandardEntitiesInStandardNamespacesQuery()))
}

Query externalLinkageArrayWithoutExplicitSizeQuery() {
Query externalLinkageArrayWithoutExplicitSizeAutosarQuery() {
//autogenerate `Query` type
result =
// `Query` type for `externalLinkageArrayWithoutExplicitSize` query
TQueryCPP(TScopePackageQuery(TExternalLinkageArrayWithoutExplicitSizeQuery()))
// `Query` type for `externalLinkageArrayWithoutExplicitSizeAutosar` query
TQueryCPP(TScopePackageQuery(TExternalLinkageArrayWithoutExplicitSizeAutosarQuery()))
}

Query hiddenInheritedNonOverridableMemberFunctionQuery() {
Expand Down
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
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

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

The documentation comment describes the wrong issue. This file is about arrays with external linkage declared without explicit size, but the comment describes "Introducing a function or object with external linkage outside of a header file" which is actually the description for the other rule (ExternalLinkageNotDeclaredInHeaderFile). The comment should describe the array size issue instead.

Suggested change
* 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.

Copilot uses AI. Check for mistakes.
*/

import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Linkage

abstract class ExternalLinkageArrayWithoutExplicitSizeSharedQuery extends Query { }

Query getQuery() { result instanceof ExternalLinkageArrayWithoutExplicitSizeSharedQuery }

query predicate problems(DeclarationEntry declEntry, string message) {
exists(Variable v, ArrayType arrayType |
not isExcluded(declEntry, getQuery()) and
message =
"The declared array '" + declEntry.getName() +
"' with external linkage doesn't specify the size explicitly." and
hasExternalLinkage(v) and
not arrayType.hasArraySize() and
// Holds is if declEntry is an array variable declaration (not a definition)
Copy link

Copilot AI Jan 15, 2026

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".

Suggested change
// Holds is if declEntry is an array variable declaration (not a definition)
// Holds if declEntry is an array variable declaration (not a definition)

Copilot uses AI. Check for mistakes.
v.getADeclarationEntry() = declEntry and
not declEntry.isDefinition() and
arrayType = v.getType().stripTopLevelSpecifiers()
)
}
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
// 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()
}
}
Loading
Loading