From 74b9e25bb8ef70a332607e7f15e43cc9b1250ed6 Mon Sep 17 00:00:00 2001 From: michael-jabbour-sonarsource Date: Wed, 22 Oct 2025 12:19:10 +0000 Subject: [PATCH 1/4] Create rule S8216 --- rules/S8216/cfamily/metadata.json | 25 ++++++++++++++++++ rules/S8216/cfamily/rule.adoc | 44 +++++++++++++++++++++++++++++++ rules/S8216/metadata.json | 2 ++ 3 files changed, 71 insertions(+) create mode 100644 rules/S8216/cfamily/metadata.json create mode 100644 rules/S8216/cfamily/rule.adoc create mode 100644 rules/S8216/metadata.json diff --git a/rules/S8216/cfamily/metadata.json b/rules/S8216/cfamily/metadata.json new file mode 100644 index 00000000000..164c3897246 --- /dev/null +++ b/rules/S8216/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-8216", + "sqKey": "S8216", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "unknown", + "code": { + "impacts": { + "MAINTAINABILITY": "HIGH", + "RELIABILITY": "MEDIUM", + "SECURITY": "LOW" + }, + "attribute": "CONVENTIONAL" + } +} diff --git a/rules/S8216/cfamily/rule.adoc b/rules/S8216/cfamily/rule.adoc new file mode 100644 index 00000000000..69c2a03a830 --- /dev/null +++ b/rules/S8216/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/S8216/metadata.json b/rules/S8216/metadata.json new file mode 100644 index 00000000000..2c63c085104 --- /dev/null +++ b/rules/S8216/metadata.json @@ -0,0 +1,2 @@ +{ +} From 6db088bd9a55ef5646f323a0c3fbd9186d3013e7 Mon Sep 17 00:00:00 2001 From: Michael Jabbour Date: Mon, 27 Oct 2025 17:27:56 +0100 Subject: [PATCH 2/4] Add rspec --- rules/S8216/cfamily/metadata.json | 14 ++-- rules/S8216/cfamily/rule.adoc | 121 ++++++++++++++++++++++++------ 2 files changed, 106 insertions(+), 29 deletions(-) diff --git a/rules/S8216/cfamily/metadata.json b/rules/S8216/cfamily/metadata.json index 164c3897246..64b0b0d612e 100644 --- a/rules/S8216/cfamily/metadata.json +++ b/rules/S8216/cfamily/metadata.json @@ -1,5 +1,5 @@ { - "title": "FIXME", + "title": "Code should not rely on features beyond the configured C++ standard", "type": "CODE_SMELL", "status": "ready", "remediation": { @@ -7,18 +7,18 @@ "constantCost": "5min" }, "tags": [ + "lock-in" ], - "defaultSeverity": "Major", + "defaultSeverity": "Minor", "ruleSpecification": "RSPEC-8216", "sqKey": "S8216", "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/S8216/cfamily/rule.adoc b/rules/S8216/cfamily/rule.adoc index 69c2a03a830..9d69e43f289 100644 --- a/rules/S8216/cfamily/rule.adoc +++ b/rules/S8216/cfamily/rule.adoc @@ -1,44 +1,121 @@ -FIXME: add a description - -// If you want to factorize the description uncomment the following line and create the file. -//include::../description.adoc[] +Code should not rely on features beyond the configured {cpp} standard == Why is this an issue? -FIXME: remove the unused optional headers (that are commented out) +Relying on features that are not part of the configured {cpp} standard leads to non-portable builds and fragile code. Some toolchains accept such code as extensions or for backward compatibility, while others strictly reject it under the same standard setting. This rule flags: + +* Uses of features from future {cpp} standards (compared to the configured standard). +* Uses of features removed in the configured {cpp} standard. +* Uses of C-only constructs that some {cpp} implementations accept as extensions. -//=== What is the potential impact? +Keeping code within the configured standard ensures consistency across compilers and prevents accidental lock-in to permissive extensions. == How to fix it -//== How to fix it in FRAMEWORK NAME -=== Code examples +Replace uses of out-of-scope features with standard-conforming alternatives that exist in the configured {cpp} standard. If the newer feature (or a removed feature) is truly required, upgrade (or align) the project’s configured standard and all toolchains consistently. -==== Noncompliant code example +=== Defaulted comparison operators +Defaulted comparison operators are introduced in {cpp}20. When the configured standard is earlier than {cpp}20, using defaulted comparison operators is noncompliant. Under {cpp}20 or later, the same code is compliant. + +==== Noncompliant code example [source,cpp,diff-id=1,diff-type=noncompliant] ---- -FIXME +struct Account { + int id; + bool operator==(const Account&) const = default; // Noncompliant before C++20 +}; ---- ==== Compliant solution - [source,cpp,diff-id=1,diff-type=compliant] ---- -FIXME +struct Account { + int id; + bool operator==(const Account& other) const { return id == other.id; } +}; +---- + +=== Using enum declaration + +The "using enum" declaration is a {cpp}20 feature. When the configured standard is earlier than {cpp}20, it is noncompliant to rely on it. Under {cpp}20 or later, the same code is compliant. + +==== Noncompliant code example +[source,cpp,diff-id=2,diff-type=noncompliant] +---- +enum class Status { Ok, Error }; +using enum Status; // Noncompliant before C++20 +auto s = Ok; +---- + +==== Compliant solution +[source,cpp,diff-id=2,diff-type=compliant] +---- +enum class Status { Ok, Error }; +auto s = Status::Ok; +---- + +=== Lambda template parameter list + +Lambda template parameter lists are available starting in {cpp}20. When the configured standard is earlier than {cpp}20, this usage is noncompliant. Under {cpp}20 or later, the same code is compliant. + +==== Noncompliant code example +[source,cpp,diff-id=3,diff-type=noncompliant] +---- +auto mapValue = [](T t) { return t; }; // Noncompliant before C++20 +---- + +==== Compliant solution +[source,cpp,diff-id=3,diff-type=compliant] +---- +auto mapValue = [](auto t) { return t; }; +---- + +=== C array designators in {cpp} + +Some C-only constructs, such as array designators, may be accepted by {cpp} compilers as extensions, but they are not part of the {cpp} standard and should be avoided in {cpp} code. + +==== Noncompliant code example +[source,cpp,diff-id=4,diff-type=noncompliant] +---- +int values[3] = { [1] = 5 }; // Noncompliant in C++ +---- + +==== Compliant solution +[source,cpp,diff-id=4,diff-type=compliant] +---- +int values[3] = {}; +values[1] = 5; +---- + +=== Removed library feature + +Some features are removed in newer standards. For example, ``++std::auto_ptr++`` was removed in {cpp}17; using it when the configured standard has removed it is noncompliant. + +==== Noncompliant code example +[source,cpp,diff-id=5,diff-type=noncompliant] +---- +#include + +std::auto_ptr p(new int(42)); // Noncompliant in C++17 and later +---- + +==== Compliant solution +[source,cpp,diff-id=5,diff-type=compliant] +---- +#include + +std::unique_ptr p = std::make_unique(42); ---- -//=== How does this work? +=== Limitations -//=== Pitfalls +This version primarily reports extensions starting from {cpp}20 and later. For example, it does not yet report use of a {cpp}17-only feature when the configured standard is {cpp}14. This limitation is temporary and will be addressed in a future update. -//=== Going the extra mile +== Resources +=== Related rules -//== Resources -//=== Documentation -//=== Articles & blog posts -//=== Conference presentations -//=== Standards -//=== External coding guidelines -//=== Benchmarks +* S3715 - GNU extensions should not be used +* S8230 - MSVC-specific extensions should not be used +* S8231 - Non-standard attributes should not be used From 04558adc0413ee3ac77d9a62592b5d20d20a16d1 Mon Sep 17 00:00:00 2001 From: Michael Jabbour Date: Thu, 30 Oct 2025 09:59:19 +0100 Subject: [PATCH 3/4] Add related rules --- rules/S8216/cfamily/rule.adoc | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/rules/S8216/cfamily/rule.adoc b/rules/S8216/cfamily/rule.adoc index 9d69e43f289..905d58f7467 100644 --- a/rules/S8216/cfamily/rule.adoc +++ b/rules/S8216/cfamily/rule.adoc @@ -8,7 +8,7 @@ Relying on features that are not part of the configured {cpp} standard leads to * Uses of features removed in the configured {cpp} standard. * Uses of C-only constructs that some {cpp} implementations accept as extensions. -Keeping code within the configured standard ensures consistency across compilers and prevents accidental lock-in to permissive extensions. +Keeping code within the configured standard ensures consistency across compilers and prevents accidental lock-in to permissive extensions. Check the list of related rules for focused rules that report specific compiler extension cases; S8216 covers remaining standard violations not addressed by these specialized rules. == How to fix it @@ -88,24 +88,34 @@ int values[3] = {}; values[1] = 5; ---- -=== Removed library feature +=== std::bind1st and std::bind2nd -Some features are removed in newer standards. For example, ``++std::auto_ptr++`` was removed in {cpp}17; using it when the configured standard has removed it is noncompliant. +The ``++std::bind1st++`` and ``++std::bind2nd++`` function templates were deprecated in {cpp}11 and removed in {cpp}17. When the configured standard is {cpp}17 or later, using these functions is noncompliant. Under earlier standards, the same code may be compliant but is still deprecated. ==== Noncompliant code example [source,cpp,diff-id=5,diff-type=noncompliant] ---- -#include +#include -std::auto_ptr p(new int(42)); // Noncompliant in C++17 and later +auto bound = std::bind1st(std::greater(), 5); // Noncompliant in C++17 or later +auto result = bound(3); // Returns true (5 > 3) ---- ==== Compliant solution [source,cpp,diff-id=5,diff-type=compliant] ---- -#include +#include -std::unique_ptr p = std::make_unique(42); +auto bound = std::bind(std::greater(), 5, std::placeholders::_1); +auto result = bound(3); // Returns true (5 > 3) +---- + +Or use a lambda expression: + +[source,cpp,diff-id=5,diff-type=compliant] +---- +auto bound = [](int x) { return std::greater()(5, x); }; +auto result = bound(3); // Returns true (5 > 3) ---- === Limitations @@ -119,3 +129,14 @@ This version primarily reports extensions starting from {cpp}20 and later. For e * S3715 - GNU extensions should not be used * S8230 - MSVC-specific extensions should not be used * S8231 - Non-standard attributes should not be used +* S3731 reports usages of ``++auto++`` as a storage class specifier, which was removed in {cpp}11 +* S7129 reports assignments of string literals to mutable char pointers, which is allowed only before {cpp}11 +* S6172 - Designated initializers should be used in their {cpp} compliant form +* S2754 - Declarations should not be empty +* S796 - Only escape sequences defined in the ISO C standard should be used +* S3689 - Declaration specifiers should not be redundant +* S2324 - Flexible array members should not be declared +* S4997 reports usages of ``++std::auto_ptr++``, which was removed in {cpp}17 +* S2668 reports usages of the increment operator on a ``++bool++`` variable, which was removed in {cpp}17 +* S3522 reports usages of the ``++register++`` storage class specifier, which was removed in {cpp}17 +* S5020 - Facilities in should be used instead of "srand", "rand" and "random_shuffle" From 9e233eaa98bb4f68f03c983e9ae06f6c761a2831 Mon Sep 17 00:00:00 2001 From: Michael Jabbour Date: Thu, 30 Oct 2025 14:24:45 +0100 Subject: [PATCH 4/4] Add link to S2260 --- rules/S8216/cfamily/rule.adoc | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/rules/S8216/cfamily/rule.adoc b/rules/S8216/cfamily/rule.adoc index 905d58f7467..1f3e1549a7f 100644 --- a/rules/S8216/cfamily/rule.adoc +++ b/rules/S8216/cfamily/rule.adoc @@ -10,6 +10,8 @@ Relying on features that are not part of the configured {cpp} standard leads to Keeping code within the configured standard ensures consistency across compilers and prevents accidental lock-in to permissive extensions. Check the list of related rules for focused rules that report specific compiler extension cases; S8216 covers remaining standard violations not addressed by these specialized rules. +This version primarily reports extensions starting from {cpp}20 and later. For example, it does not yet report use of a {cpp}17-only feature when the configured standard is {cpp}14. This limitation is temporary and will be addressed in a future update. + == How to fix it Replace uses of out-of-scope features with standard-conforming alternatives that exist in the configured {cpp} standard. If the newer feature (or a removed feature) is truly required, upgrade (or align) the project’s configured standard and all toolchains consistently. @@ -118,10 +120,6 @@ auto bound = [](int x) { return std::greater()(5, x); }; auto result = bound(3); // Returns true (5 > 3) ---- -=== Limitations - -This version primarily reports extensions starting from {cpp}20 and later. For example, it does not yet report use of a {cpp}17-only feature when the configured standard is {cpp}14. This limitation is temporary and will be addressed in a future update. - == Resources === Related rules @@ -140,3 +138,4 @@ This version primarily reports extensions starting from {cpp}20 and later. For e * S2668 reports usages of the increment operator on a ``++bool++`` variable, which was removed in {cpp}17 * S3522 reports usages of the ``++register++`` storage class specifier, which was removed in {cpp}17 * S5020 - Facilities in should be used instead of "srand", "rand" and "random_shuffle" +* S2260 tracks parsing failures and can help identify compiler-specific extensions that the analyzer fails to recognize