Skip to content

Improve performance of C queries related to identifiers #242

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

Merged
merged 4 commits into from
Mar 29, 2023
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,39 @@ import cpp
import codingstandards.c.misra
import codingstandards.cpp.Identifiers

from Declaration de, ExternalIdentifiers e
/**
* Holds if the `identifierName` has conflicting declarations.
*/
predicate isExternalIdentifierNotUnique(string identifierName) {
// More than one declaration with this name
count(Declaration d | d.getName() = identifierName) > 1 and
// At least one declaration is an external identifier
exists(ExternalIdentifiers e | e.getName() = identifierName)
}

/**
* Holds if the `Declaration` `d` is conflicting with an external identifier.
*/
predicate isConflictingDeclaration(Declaration d, string name) {
isExternalIdentifierNotUnique(name) and
d.getName() = name
}

/**
* An external identifier which is not uniquely defined in the source code.
*/
class NotUniqueExternalIdentifier extends ExternalIdentifiers {
NotUniqueExternalIdentifier() { isExternalIdentifierNotUnique(getName()) }

Declaration getAConflictingDeclaration() {
not result = this and
isConflictingDeclaration(result, getName())
}
}

from NotUniqueExternalIdentifier e, Declaration de
where
not isExcluded(de, Declarations6Package::identifiersWithExternalLinkageNotUniqueQuery()) and
not isExcluded(e, Declarations6Package::identifiersWithExternalLinkageNotUniqueQuery()) and
not de = e and
de.getName() = e.getName()
de = e.getAConflictingDeclaration()
select de, "Identifier conflicts with external identifier $@", e, e.getName()
39 changes: 24 additions & 15 deletions c/misra/src/rules/RULE-8-7/ShouldNotBeDefinedWithExternalLinkage.ql
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,36 @@ import codingstandards.c.misra
import codingstandards.cpp.Identifiers
import codingstandards.cpp.Scope

ExternalIdentifiers getExternalIdentifierTarget(NameQualifiableElement nqe) {
result = nqe.(Access).getTarget()
or
result = nqe.(FunctionCall).getTarget()
}

/**
* Re-introduce function calls into access description as
* "any reference"
* A reference to an external identifier, either as an `Access` or a `FunctionCall`.
*/
class Reference extends NameQualifiableElement {
Reference() {
this instanceof Access or
this instanceof FunctionCall
}
class ExternalIdentifierReference extends NameQualifiableElement {
ExternalIdentifierReference() { exists(getExternalIdentifierTarget(this)) }

ExternalIdentifiers getExternalIdentifierTarget() { result = getExternalIdentifierTarget(this) }
}

predicate isReferencedInTranslationUnit(
ExternalIdentifiers e, ExternalIdentifierReference r, TranslationUnit t
) {
r.getExternalIdentifierTarget() = e and
r.getFile() = t
}

from ExternalIdentifiers e, Reference a1, TranslationUnit t1
from ExternalIdentifiers e, ExternalIdentifierReference a1, TranslationUnit t1
where
not isExcluded(e, Declarations6Package::shouldNotBeDefinedWithExternalLinkageQuery()) and
(a1.(Access).getTarget() = e or a1.(FunctionCall).getTarget() = e) and
a1.getFile() = t1 and
//not accessed in any other translation unit
not exists(TranslationUnit t2, Reference a2 |
not t1 = t2 and
(a2.(Access).getTarget() = e or a2.(FunctionCall).getTarget() = e) and
a2.getFile() = t2
isReferencedInTranslationUnit(e, a1, t1) and
// Not referenced in any other translation unit
not exists(TranslationUnit t2 |
isReferencedInTranslationUnit(e, _, t2) and
not t1 = t2
)
select e, "Declaration with external linkage is accessed in only one translation unit $@.", a1,
a1.toString()
3 changes: 3 additions & 0 deletions change_notes/2023-03-08-identifier-performance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* The performance of the following identifier related rules has been improved:
* MISRA C 2012 `Rule 5.8`
* MISRA C 2012 `Rule 8.7`