Skip to content

Commit c56e1ce

Browse files
committed
TypographicallyDifferent: Update after changes to Scope
Scope no longer provides a suitable predicate for determining variables in nested scopes. Instead, first determine the set of conflicting names, then identify a set of variables which are conflicting, and are hidden within a nested scope.
1 parent cf315ba commit c56e1ce

File tree

1 file changed

+40
-7
lines changed

1 file changed

+40
-7
lines changed

cpp/common/src/codingstandards/cpp/rules/differentidentifiersnottypographicallyunambiguous/DifferentIdentifiersNotTypographicallyUnambiguous.qll

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,32 @@ string step1(string s) {
4646

4747
string step2(string s) { s = "m_" and result = "rn" }
4848

49-
predicate violation(UserVariable v1, UserVariable v2) {
50-
v2 = getPotentialScopeOfVariable(v1) and
49+
class VariableName extends string {
50+
VariableName() { exists(UserVariable uv | uv.getName() = this) }
51+
52+
string getCanon() {
53+
result =
54+
this.toLowerCase()
55+
.replaceAll("_", "")
56+
.regexpReplaceAll("[il]", "1")
57+
.replaceAll("s", "5")
58+
.replaceAll("z", "2")
59+
.replaceAll("b", "8")
60+
.replaceAll("h", "n")
61+
.replaceAll("m", "rn")
62+
.replaceAll("o", "0")
63+
}
64+
}
65+
66+
predicate isConflictingName(VariableName name1, VariableName name2) {
5167
exists(string s1, string s2 |
5268
// over-approximate a match, because it is cheaper to compute
53-
getCanon(v1) = getCanon(v2) and
54-
v1 != v2 and
55-
not v1.getName() = v2.getName() and
69+
name1.getCanon() = name2.getCanon() and
70+
// Exclude identical names
71+
not name1 = name2 and
5672
// expand 'm' to 'm_' to match either 'm_' or 'rn'
57-
s1 = v1.getName().replaceAll("_", "").replaceAll("m", "m_") and
58-
s2 = v2.getName().replaceAll("_", "").replaceAll("m", "m_") and
73+
s1 = name1.replaceAll("_", "").replaceAll("m", "m_") and
74+
s2 = name2.replaceAll("_", "").replaceAll("m", "m_") and
5975
// at this point the strings must have equal length, the substitutions do not expand nor contract the string
6076
s1.length() = s2.length() and
6177
forall(int i | i in [0 .. s1.length() - 1] |
@@ -87,6 +103,23 @@ predicate violation(UserVariable v1, UserVariable v2) {
87103
)
88104
}
89105

106+
predicate violation(UserVariable v1, UserVariable v2) {
107+
exists(string name1, string name2 |
108+
isConflictingName(name1, name2) and
109+
exists(Scope parentScope, Scope childScope |
110+
parentScope.getVariable(name1) = v1 and
111+
childScope.getVariable(name2) = v2
112+
|
113+
childScope.getStrictParent+() = parentScope
114+
or
115+
// Disambiguate names in the same scope by name order
116+
childScope = parentScope and
117+
name1 < name2
118+
) and
119+
inSameTranslationUnitLate(v1.getFile(), v2.getFile())
120+
)
121+
}
122+
90123
query predicate problems(
91124
UserVariable v, string message, UserVariable v1, string v1Description, UserVariable v2,
92125
string v2Description

0 commit comments

Comments
 (0)