-
Notifications
You must be signed in to change notification settings - Fork 69
Implement most of Classes2, split out two harder rules #948
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
Open
MichaelRFairhurst
wants to merge
3
commits into
main
Choose a base branch
from
michaelrfairhurst/package-classes2-split
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
129 changes: 129 additions & 0 deletions
129
cpp/common/src/codingstandards/cpp/exclusions/cpp/Classes2.qll
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| //** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/ | ||
| import cpp | ||
| import RuleMetadata | ||
| import codingstandards.cpp.exclusions.RuleMetadata | ||
|
|
||
| newtype Classes2Query = | ||
| TVirtualInheritanceNotAllowedQuery() or | ||
| TMemberSpecifiersNotUsedAppropriatelyQuery() or | ||
| TPrivateAndPublicDataMembersMixedQuery() or | ||
| TInvalidSignatureForSpecialMemberFunctionQuery() or | ||
| TNonExplicitConversionMemberQuery() or | ||
| TLogicalAndAndLogicalOrOperatorsOverloadedQuery() or | ||
| TInvalidOperatorOverloadedAsMemberFunctionQuery() | ||
|
|
||
| predicate isClasses2QueryMetadata(Query query, string queryId, string ruleId, string category) { | ||
| query = | ||
| // `Query` instance for the `virtualInheritanceNotAllowed` query | ||
| Classes2Package::virtualInheritanceNotAllowedQuery() and | ||
| queryId = | ||
| // `@id` for the `virtualInheritanceNotAllowed` query | ||
| "cpp/misra/virtual-inheritance-not-allowed" and | ||
| ruleId = "RULE-13-1-1" and | ||
| category = "advisory" | ||
| or | ||
| query = | ||
| // `Query` instance for the `memberSpecifiersNotUsedAppropriately` query | ||
| Classes2Package::memberSpecifiersNotUsedAppropriatelyQuery() and | ||
| queryId = | ||
| // `@id` for the `memberSpecifiersNotUsedAppropriately` query | ||
| "cpp/misra/member-specifiers-not-used-appropriately" and | ||
| ruleId = "RULE-13-3-1" and | ||
| category = "required" | ||
| or | ||
| query = | ||
| // `Query` instance for the `privateAndPublicDataMembersMixed` query | ||
| Classes2Package::privateAndPublicDataMembersMixedQuery() and | ||
| queryId = | ||
| // `@id` for the `privateAndPublicDataMembersMixed` query | ||
| "cpp/misra/private-and-public-data-members-mixed" and | ||
| ruleId = "RULE-14-1-1" and | ||
| category = "advisory" | ||
| or | ||
| query = | ||
| // `Query` instance for the `invalidSignatureForSpecialMemberFunction` query | ||
| Classes2Package::invalidSignatureForSpecialMemberFunctionQuery() and | ||
| queryId = | ||
| // `@id` for the `invalidSignatureForSpecialMemberFunction` query | ||
| "cpp/misra/invalid-signature-for-special-member-function" and | ||
| ruleId = "RULE-15-0-2" and | ||
| category = "advisory" | ||
| or | ||
| query = | ||
| // `Query` instance for the `nonExplicitConversionMember` query | ||
| Classes2Package::nonExplicitConversionMemberQuery() and | ||
| queryId = | ||
| // `@id` for the `nonExplicitConversionMember` query | ||
| "cpp/misra/non-explicit-conversion-member" and | ||
| ruleId = "RULE-15-1-3" and | ||
| category = "required" | ||
| or | ||
| query = | ||
| // `Query` instance for the `logicalAndAndLogicalOrOperatorsOverloaded` query | ||
| Classes2Package::logicalAndAndLogicalOrOperatorsOverloadedQuery() and | ||
| queryId = | ||
| // `@id` for the `logicalAndAndLogicalOrOperatorsOverloaded` query | ||
| "cpp/misra/logical-and-and-logical-or-operators-overloaded" and | ||
| ruleId = "RULE-16-5-1" and | ||
| category = "required" | ||
| or | ||
| query = | ||
| // `Query` instance for the `invalidOperatorOverloadedAsMemberFunction` query | ||
| Classes2Package::invalidOperatorOverloadedAsMemberFunctionQuery() and | ||
| queryId = | ||
| // `@id` for the `invalidOperatorOverloadedAsMemberFunction` query | ||
| "cpp/misra/invalid-operator-overloaded-as-member-function" and | ||
| ruleId = "RULE-16-6-1" and | ||
| category = "advisory" | ||
| } | ||
|
|
||
| module Classes2Package { | ||
| Query virtualInheritanceNotAllowedQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `virtualInheritanceNotAllowed` query | ||
| TQueryCPP(TClasses2PackageQuery(TVirtualInheritanceNotAllowedQuery())) | ||
| } | ||
|
|
||
| Query memberSpecifiersNotUsedAppropriatelyQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `memberSpecifiersNotUsedAppropriately` query | ||
| TQueryCPP(TClasses2PackageQuery(TMemberSpecifiersNotUsedAppropriatelyQuery())) | ||
| } | ||
|
|
||
| Query privateAndPublicDataMembersMixedQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `privateAndPublicDataMembersMixed` query | ||
| TQueryCPP(TClasses2PackageQuery(TPrivateAndPublicDataMembersMixedQuery())) | ||
| } | ||
|
|
||
| Query invalidSignatureForSpecialMemberFunctionQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `invalidSignatureForSpecialMemberFunction` query | ||
| TQueryCPP(TClasses2PackageQuery(TInvalidSignatureForSpecialMemberFunctionQuery())) | ||
| } | ||
|
|
||
| Query nonExplicitConversionMemberQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `nonExplicitConversionMember` query | ||
| TQueryCPP(TClasses2PackageQuery(TNonExplicitConversionMemberQuery())) | ||
| } | ||
|
|
||
| Query logicalAndAndLogicalOrOperatorsOverloadedQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `logicalAndAndLogicalOrOperatorsOverloaded` query | ||
| TQueryCPP(TClasses2PackageQuery(TLogicalAndAndLogicalOrOperatorsOverloadedQuery())) | ||
| } | ||
|
|
||
| Query invalidOperatorOverloadedAsMemberFunctionQuery() { | ||
| //autogenerate `Query` type | ||
| result = | ||
| // `Query` type for `invalidOperatorOverloadedAsMemberFunction` query | ||
| TQueryCPP(TClasses2PackageQuery(TInvalidOperatorOverloadedAsMemberFunctionQuery())) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
cpp/misra/src/rules/RULE-13-1-1/VirtualInheritanceNotAllowed.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| /** | ||
| * @id cpp/misra/virtual-inheritance-not-allowed | ||
| * @name RULE-13-1-1: Classes should not be inherited virtually | ||
| * @description Virtual inheritance should not be used as it may lead to unexpected behavior. | ||
| * @kind problem | ||
| * @precision very-high | ||
| * @problem.severity warning | ||
| * @tags external/misra/id/rule-13-1-1 | ||
| * scope/single-translation-unit | ||
| * correctness | ||
| * readability | ||
| * external/misra/enforcement/decidable | ||
| * external/misra/obligation/advisory | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.cpp.misra | ||
|
|
||
| from VirtualClassDerivation vcd | ||
| where not isExcluded(vcd, Classes2Package::virtualInheritanceNotAllowedQuery()) | ||
| select vcd, | ||
| "Class '" + vcd.getDerivedClass().getName() + "' inherits virtually from '" + | ||
| vcd.getBaseClass().getName() + "'." |
59 changes: 59 additions & 0 deletions
59
cpp/misra/src/rules/RULE-13-3-1/MemberSpecifiersNotUsedAppropriately.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,59 @@ | ||
| /** | ||
| * @id cpp/misra/member-specifiers-not-used-appropriately | ||
| * @name RULE-13-3-1: User-declared member functions shall use the virtual, override and final specifiers appropriately | ||
| * @description Appropriate use of specifiers on member functions more clearly indicate the | ||
| * intention of the function. | ||
| * @kind problem | ||
| * @precision very-high | ||
| * @problem.severity warning | ||
| * @tags external/misra/id/rule-13-3-1 | ||
| * scope/single-translation-unit | ||
| * readability | ||
| * maintainability | ||
| * external/misra/enforcement/decidable | ||
| * external/misra/obligation/required | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.cpp.misra | ||
|
|
||
| from MemberFunction f, string message | ||
| where | ||
| not isExcluded(f, Classes2Package::memberSpecifiersNotUsedAppropriatelyQuery()) and | ||
| ( | ||
| // Case 1: Specifiers incompatible with explicitly virtual | ||
| f.isDeclaredVirtual() and | ||
| exists(Specifier s | | ||
| s = f.getASpecifier() and | ||
| s.getName() = ["final", "override"] | ||
| ) and | ||
| message = | ||
| "Member function '" + f.getName() + | ||
| "' uses redundant 'virtual' and 'final' specifiers together." | ||
| or | ||
| // Case 2: Redundant 'virtual' specifier | ||
| f.overrides(_) and | ||
| f.isDeclaredVirtual() and | ||
| message = | ||
| "Member function '" + f.getName() + | ||
| "' overrides a base function but uses 'virtual' specifier." | ||
| or | ||
| // Case 3: both 'override' and 'final' specifiers on an overridden virtual function | ||
| f.isVirtual() and | ||
| not f.isDeclaredVirtual() and | ||
| f.isOverride() and | ||
| f.isFinal() and | ||
| message = | ||
| "Member function '" + f.getName() + | ||
| "' uses redundant 'override' and 'final' specifiers together." | ||
| or | ||
| // Case 5: overrides a virtual function but has no override or final specifier | ||
| f.overrides(_) and | ||
| not f.isDeclaredVirtual() and | ||
| not f.isOverride() and | ||
| not f.isFinal() and | ||
| message = | ||
| "Member function '" + f.getName() + | ||
| "' overrides a base function but lacks 'override' or 'final' specifier." | ||
| ) | ||
| select f, message | ||
48 changes: 48 additions & 0 deletions
48
cpp/misra/src/rules/RULE-14-1-1/PrivateAndPublicDataMembersMixed.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| /** | ||
| * @id cpp/misra/private-and-public-data-members-mixed | ||
| * @name RULE-14-1-1: Non-static data members should be either all private or all public | ||
| * @description Mixing public and private data members in a class obfuscates the range of valid | ||
| * states allowable for that class. | ||
| * @kind problem | ||
| * @precision very-high | ||
| * @problem.severity warning | ||
| * @tags external/misra/id/rule-14-1-1 | ||
| * scope/single-translation-unit | ||
| * maintanability | ||
| * external/misra/enforcement/decidable | ||
| * external/misra/obligation/advisory | ||
| */ | ||
|
|
||
| import cpp | ||
| import codingstandards.cpp.misra | ||
|
|
||
| from Class c, Field f | ||
| where | ||
| not isExcluded(f, Classes2Package::privateAndPublicDataMembersMixedQuery()) and | ||
|
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. Should we also allow the exclusion to be placed only on the |
||
| f = c.getAMember() and | ||
| not f.isStatic() and | ||
| ( | ||
| // Protected data members is not allowed. | ||
| f.isProtected() | ||
| or | ||
| // Public and private data members cannot be mixed. | ||
| exists(Field other | | ||
| other = c.getAMember() and | ||
| not other.isStatic() and | ||
| other != f and | ||
| ( | ||
| f.isPublic() and other.isPrivate() | ||
| or | ||
| f.isPrivate() and other.isPublic() | ||
| or | ||
| f.isProtected() and | ||
| (other.isPublic() or other.isPrivate()) | ||
| or | ||
| (f.isPublic() or f.isPrivate()) and | ||
| other.isProtected() | ||
| ) | ||
| ) | ||
| ) | ||
| select f, | ||
| "Non-static data member '" + f.getName() + | ||
| "' has mixed access level with other data members in class '" + c.getName() + "'." | ||
103 changes: 103 additions & 0 deletions
103
cpp/misra/src/rules/RULE-15-0-2/InvalidSignatureForSpecialMemberFunction.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,103 @@ | ||||||
| /** | ||||||
| * @id cpp/misra/invalid-signature-for-special-member-function | ||||||
| * @name RULE-15-0-2: User-provided copy and move member functions of a class should have appropriate signatures | ||||||
| * @description Proper implementations of copy and move constructors and assignment operators ensure | ||||||
| * that resources are managed correctly. | ||||||
| * @kind problem | ||||||
| * @precision very-high | ||||||
| * @problem.severity warning | ||||||
| * @tags external/misra/id/rule-15-0-2 | ||||||
| * scope/single-translation-unit | ||||||
| * correctness | ||||||
| * maintainability | ||||||
| * external/misra/enforcement/decidable | ||||||
| * external/misra/obligation/advisory | ||||||
| */ | ||||||
|
|
||||||
| import cpp | ||||||
| import codingstandards.cpp.misra | ||||||
| import codeql.util.Boolean | ||||||
|
|
||||||
| pragma[inline] | ||||||
| predicate checkSignature( | ||||||
| MemberFunction f, Boolean noexcept, Boolean lvalueQualified, Boolean rvalueRef, string err | ||||||
| ) { | ||||||
| f.getNumberOfParameters() > 1 and | ||||||
| err = "too many parameters" | ||||||
|
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. typo
Suggested change
|
||||||
| or | ||||||
| noexcept = true and | ||||||
| not f.isNoExcept() and | ||||||
| err = "should be noexcept" | ||||||
| or | ||||||
| lvalueQualified = true and | ||||||
| not f.isLValueRefQualified() and | ||||||
| err = "should be lvalue-qualified" | ||||||
| or | ||||||
| lvalueQualified = false and | ||||||
| f.isLValueRefQualified() and | ||||||
| err = "should not be lvalue-qualified" | ||||||
| or | ||||||
| rvalueRef = true and | ||||||
| not isRvalueRefX(f.getParameter(0).getType(), f.getDeclaringType()) and | ||||||
| err = "should take rvalue reference to class or struct type" | ||||||
| or | ||||||
| rvalueRef = false and | ||||||
| not isConstRefX(f.getParameter(0).getType(), f.getDeclaringType()) and | ||||||
| err = "should take const reference to class or struct type" | ||||||
| or | ||||||
| f.isVirtual() and | ||||||
| err = "should not be virtual" | ||||||
| or | ||||||
| not f instanceof Constructor and | ||||||
| not f.getType().(LValueReferenceType).getBaseType() = f.getDeclaringType() and | ||||||
| not f.getType() instanceof VoidType and | ||||||
| err = "should return void or lvalue reference to class or struct type" | ||||||
| or | ||||||
| not f instanceof Constructor and | ||||||
| f.isExplicit() and | ||||||
| err = "should not be explicit" | ||||||
| } | ||||||
|
|
||||||
| predicate isRvalueRefX(Type t, Class x) { | ||||||
| // X && | ||||||
| t.(RValueReferenceType).getBaseType() = x | ||||||
| } | ||||||
|
|
||||||
| predicate isConstRefX(Type t, Class x) { | ||||||
| exists(SpecifiedType st | | ||||||
| // X const & | ||||||
| st = t.(LValueReferenceType).getBaseType() and | ||||||
| st.getSpecifierString() = "const" and | ||||||
| st.getBaseType() = x | ||||||
| or | ||||||
| // const X & | ||||||
| st = t and | ||||||
| st.getSpecifierString() = "const" and | ||||||
| st.getBaseType().(LValueReferenceType).getBaseType() = x | ||||||
| ) | ||||||
| } | ||||||
|
|
||||||
| from MemberFunction f, string err, string prefix | ||||||
| where | ||||||
| not isExcluded(f, Classes2Package::invalidSignatureForSpecialMemberFunctionQuery()) and | ||||||
| not f.isDeleted() and | ||||||
| not f.isDefaulted() and | ||||||
| not f.isCompilerGenerated() and | ||||||
| ( | ||||||
| f instanceof CopyConstructor and | ||||||
| prefix = "Copy constructor" and | ||||||
| checkSignature(f, false, false, false, err) | ||||||
| or | ||||||
| f instanceof MoveConstructor and | ||||||
| prefix = "Move constructor" and | ||||||
| checkSignature(f, true, false, true, err) | ||||||
| or | ||||||
| f instanceof CopyAssignmentOperator and | ||||||
| prefix = "Copy assignment operator" and | ||||||
| checkSignature(f, false, true, false, err) | ||||||
| or | ||||||
| f instanceof MoveAssignmentOperator and | ||||||
| prefix = "Move assignment operator" and | ||||||
| checkSignature(f, true, true, true, err) | ||||||
| ) | ||||||
| select f, prefix + " on type $@ " + err + ".", f.getDeclaringType(), f.getDeclaringType().getName() | ||||||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
More specific message: