From af01eba5f7270a776dd45ccbe3a899019c4d93cc Mon Sep 17 00:00:00 2001 From: michael-jabbour-sonarsource Date: Mon, 27 Oct 2025 16:01:13 +0000 Subject: [PATCH 1/2] Create rule S8231 --- rules/S8231/cfamily/metadata.json | 25 ++++++++++++++++++ rules/S8231/cfamily/rule.adoc | 44 +++++++++++++++++++++++++++++++ rules/S8231/metadata.json | 2 ++ 3 files changed, 71 insertions(+) create mode 100644 rules/S8231/cfamily/metadata.json create mode 100644 rules/S8231/cfamily/rule.adoc create mode 100644 rules/S8231/metadata.json diff --git a/rules/S8231/cfamily/metadata.json b/rules/S8231/cfamily/metadata.json new file mode 100644 index 00000000000..87c2b0c822a --- /dev/null +++ b/rules/S8231/cfamily/metadata.json @@ -0,0 +1,25 @@ +{ + "title": "FIXME", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-8231", + "sqKey": "S8231", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "unknown", + "code": { + "impacts": { + "MAINTAINABILITY": "HIGH", + "RELIABILITY": "MEDIUM", + "SECURITY": "LOW" + }, + "attribute": "CONVENTIONAL" + } +} diff --git a/rules/S8231/cfamily/rule.adoc b/rules/S8231/cfamily/rule.adoc new file mode 100644 index 00000000000..69c2a03a830 --- /dev/null +++ b/rules/S8231/cfamily/rule.adoc @@ -0,0 +1,44 @@ +FIXME: add a description + +// If you want to factorize the description uncomment the following line and create the file. +//include::../description.adoc[] + +== Why is this an issue? + +FIXME: remove the unused optional headers (that are commented out) + +//=== What is the potential impact? + +== How to fix it +//== How to fix it in FRAMEWORK NAME + +=== Code examples + +==== Noncompliant code example + +[source,cpp,diff-id=1,diff-type=noncompliant] +---- +FIXME +---- + +==== Compliant solution + +[source,cpp,diff-id=1,diff-type=compliant] +---- +FIXME +---- + +//=== How does this work? + +//=== Pitfalls + +//=== Going the extra mile + + +//== Resources +//=== Documentation +//=== Articles & blog posts +//=== Conference presentations +//=== Standards +//=== External coding guidelines +//=== Benchmarks diff --git a/rules/S8231/metadata.json b/rules/S8231/metadata.json new file mode 100644 index 00000000000..2c63c085104 --- /dev/null +++ b/rules/S8231/metadata.json @@ -0,0 +1,2 @@ +{ +} From e0f95d209c06bf63af2b1ffa9619b761f15557d3 Mon Sep 17 00:00:00 2001 From: Michael Jabbour Date: Tue, 4 Nov 2025 09:17:25 +0100 Subject: [PATCH 2/2] WIP --- rules/S8231/cfamily/metadata.json | 13 +++--- rules/S8231/cfamily/rule.adoc | 68 +++++++++++++++++++++---------- 2 files changed, 52 insertions(+), 29 deletions(-) diff --git a/rules/S8231/cfamily/metadata.json b/rules/S8231/cfamily/metadata.json index 87c2b0c822a..01801ad587f 100644 --- a/rules/S8231/cfamily/metadata.json +++ b/rules/S8231/cfamily/metadata.json @@ -1,5 +1,5 @@ { - "title": "FIXME", + "title": "Non-standard attributes should not be used", "type": "CODE_SMELL", "status": "ready", "remediation": { @@ -7,18 +7,17 @@ "constantCost": "5min" }, "tags": [ + "lock-in" ], - "defaultSeverity": "Major", + "defaultSeverity": "Minor", "ruleSpecification": "RSPEC-8231", "sqKey": "S8231", "scope": "All", - "defaultQualityProfiles": ["Sonar way"], - "quickfix": "unknown", + "defaultQualityProfiles": [], + "quickfix": "infeasible", "code": { "impacts": { - "MAINTAINABILITY": "HIGH", - "RELIABILITY": "MEDIUM", - "SECURITY": "LOW" + "MAINTAINABILITY": "LOW" }, "attribute": "CONVENTIONAL" } diff --git a/rules/S8231/cfamily/rule.adoc b/rules/S8231/cfamily/rule.adoc index 69c2a03a830..29dd4f044d2 100644 --- a/rules/S8231/cfamily/rule.adoc +++ b/rules/S8231/cfamily/rule.adoc @@ -1,44 +1,68 @@ -FIXME: add a description - -// If you want to factorize the description uncomment the following line and create the file. -//include::../description.adoc[] +Non-standard attributes should not be used == Why is this an issue? -FIXME: remove the unused optional headers (that are commented out) +Attributes provide a standardized syntax for conveying implementation-defined language extensions and hints to the compiler. While the {{cpp}} standard defines several attributes (such as ``++[[deprecated]]++``, ``++[[maybe_unused]]++``, and ``++[[nodiscard]]++``), compilers also support vendor-specific attributes for compiler-specific features and optimizations. + +Using non-standard attributes introduces portability risks. When code with compiler-specific attributes is compiled with a different toolchain, unrecognized attributes are silently ignored, which can lead to: + +* Loss of intended behavior (e.g., optimization hints, alignment requirements, or safety checks) +* Runtime failures when the ignored attribute was critical for correctness +* Maintenance burden when vendor-specific attributes are scattered across the codebase + +This rule allows only standard attributes that are specified using the standard ``++[[...]]++`` syntax. It reports: +* All attributes that are not defined in the {{cpp}} standard itself, whether expressed using standard attribute syntax with vendor namespaces (e.g., ``++[[msvc::no_unique_address]]++``), GNU-style ``++__attribute__++`` syntax (e.g., ``++__attribute__((packed))++``), or MSVC's ``++__declspec++`` syntax (e.g., ``++__declspec(align(16))++``) +* Standard attributes that are specified using non-standard syntax (e.g., ``++__attribute__((noreturn))++`` instead of ``++[[noreturn]]++``) -//=== What is the potential impact? +The goal is to ensure that such attributes are reviewed to be well-behaved under all used toolchains, or replaced with standard-conforming alternatives when possible. == How to fix it -//== How to fix it in FRAMEWORK NAME -=== Code examples +Replace non-standard attributes with standard attributes when equivalent functionality exists, or ensure that vendor-specific attributes are only used in code paths that are known to be compiled with the appropriate toolchain. Consider using preprocessor directives or build-system configuration to conditionally apply compiler-specific attributes. -==== Noncompliant code example +=== Non-standard attribute using standard syntax +==== Noncompliant code example [source,cpp,diff-id=1,diff-type=noncompliant] ---- -FIXME +struct Empty {}; + +struct Container { + [[msvc::no_unique_address]] Empty e; // Noncompliant: non-standard attribute + int value; +}; ---- ==== Compliant solution - [source,cpp,diff-id=1,diff-type=compliant] ---- -FIXME +struct Empty {}; + +struct Container { + [[no_unique_address]] Empty e; // Use standard attribute if C++20 is available + int value; +}; ---- -//=== How does this work? +=== Standard attribute using non-standard syntax + +==== Noncompliant code example +[source,cpp,diff-id=2,diff-type=noncompliant] +---- +__attribute__((noreturn)) +void terminate(); // Noncompliant: standard attribute using GNU-style syntax +---- -//=== Pitfalls +==== Compliant solution +[source,cpp,diff-id=2,diff-type=compliant] +---- +[[noreturn]] +void terminate(); // Use standard syntax +---- -//=== Going the extra mile +== Resources +=== Related rules -//== Resources -//=== Documentation -//=== Articles & blog posts -//=== Conference presentations -//=== Standards -//=== External coding guidelines -//=== Benchmarks +* S8216 - Code should not rely on features beyond the configured {{cpp}} standard +* S8230 - MSVC-specific extensions should not be used