Skip to content

Commit 4fea942

Browse files
Merge pull request #950 from github/michaelrfairhurst/implement-naming-package
Implement naming package, new IdentifierIntroduction.qll, unicode funcs.
2 parents d5b8a46 + 4a98c70 commit 4fea942

File tree

18 files changed

+288981
-2
lines changed

18 files changed

+288981
-2
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- "Function-like macros"
2+
- The parameter list of variadic macros previously included the ellipsis in name of the final parameter, potentially leading to incorrect analysis. This has been corrected.
3+
- The parameter list of function-like macros with no parameters (i.e. `MACRO()`) was interpreted in a shared library as having a single parameter with an empty name. This does not seem to have had an impact on any existing queries, but has been fixed to correctly show no parameters.

cpp/common/src/codingstandards/cpp/Identifiers.qll

Lines changed: 446 additions & 0 deletions
Large diffs are not rendered by default.

cpp/common/src/codingstandards/cpp/Macro.qll

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
import cpp
22

33
/**
4-
* Macros with a parameter
4+
* Macros with parentheses, e.g. `#define MACRO(x) (x * 2)`.
5+
*
6+
* Note that this includes macros with empty parameter lists, e.g. `#define MACRO() 42`.
57
*/
68
class FunctionLikeMacro extends Macro {
79
FunctionLikeMacro() { this.getHead().regexpMatch("[_a-zA-Z0-9]+\\s*\\([^\\)]*?\\)") }
810

911
string getParameter(int i) {
1012
result =
11-
this.getHead().regexpCapture("[_a-zA-Z0-9]+\\s*\\(([^\\)]*)\\)", 1).splitAt(",", i).trim()
13+
this.getHead()
14+
.regexpCapture("[_a-zA-Z0-9]+\\s*\\(([^\\)]*)\\)", 1)
15+
.splitAt(",", i)
16+
.trim()
17+
.replaceAll("...", "") and
18+
not result = ""
1219
}
1320

1421
string getAParameter() { result = getParameter(_) }
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import codeql.util.Numbers
2+
3+
/**
4+
* Provides properties of a Unicode code point, where the property is of 'enumeration', 'catalog',
5+
* or 'string-valued' type, however, the only supported property is `NFC_QC`.
6+
*
7+
* For example, `Block` is an enumeration property, `Line_Break` is a catalog property, and
8+
* `Uppercase_Mapping` is a string-valued property.
9+
*
10+
* For boolean properties, see `unicodeHasBooleanProperty`, and for numeric properties, see
11+
* `unicodeHasNumericProperty`.
12+
*/
13+
extensible predicate unicodeHasProperty(int codePoint, string propertyName, string propertyValue);
14+
15+
/**
16+
* Holds when the Unicode code point's boolean property of the given name is true.
17+
*
18+
* For example, `Alphabetic` is a boolean property that can be true or false for a code point.
19+
*
20+
* For other types of properties, see `unicodeHasProperty`.
21+
*/
22+
extensible predicate unicodeHasBooleanProperty(int codePoint, string propertyName);
23+
24+
bindingset[input]
25+
int unescapedCodePointAt(string input, int index) {
26+
exists(string match |
27+
match = input.regexpFind("(\\\\u[0-9a-fA-F]{4}|.)", index, _) and
28+
if match.matches("\\u%")
29+
then result = parseHexInt(match.substring(2, match.length()))
30+
else result = match.codePointAt(0)
31+
)
32+
}
33+
34+
bindingset[input]
35+
string unescapeUnicode(string input) {
36+
result =
37+
concat(int code, int idx |
38+
code = unescapedCodePointAt(input, idx)
39+
|
40+
code.toUnicode() order by idx
41+
)
42+
}
43+
44+
bindingset[id]
45+
predicate nonUax44IdentifierCodepoint(string id, int index) {
46+
exists(int codePoint |
47+
codePoint = id.codePointAt(index) and
48+
(
49+
not unicodeHasBooleanProperty(codePoint, "XID_Start") and
50+
not unicodeHasBooleanProperty(codePoint, "XID_Continue")
51+
or
52+
index = 0 and
53+
not unicodeHasBooleanProperty(codePoint, "XID_Start")
54+
)
55+
)
56+
}
57+
58+
bindingset[id]
59+
predicate nonNfcNormalizedCodepoint(string id, int index, string noOrMaybe) {
60+
exists(int codePoint |
61+
codePoint = id.codePointAt(index) and
62+
unicodeHasProperty(codePoint, "NFC_QC", noOrMaybe) and
63+
noOrMaybe = ["N", "M"]
64+
)
65+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtype Naming2Query = TPoorlyFormedIdentifierQuery()
7+
8+
predicate isNaming2QueryMetadata(Query query, string queryId, string ruleId, string category) {
9+
query =
10+
// `Query` instance for the `poorlyFormedIdentifier` query
11+
Naming2Package::poorlyFormedIdentifierQuery() and
12+
queryId =
13+
// `@id` for the `poorlyFormedIdentifier` query
14+
"cpp/misra/poorly-formed-identifier" and
15+
ruleId = "RULE-5-10-1" and
16+
category = "required"
17+
}
18+
19+
module Naming2Package {
20+
Query poorlyFormedIdentifierQuery() {
21+
//autogenerate `Query` type
22+
result =
23+
// `Query` type for `poorlyFormedIdentifier` query
24+
TQueryCPP(TNaming2PackageQuery(TPoorlyFormedIdentifierQuery()))
25+
}
26+
}

cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import Memory2
4444
import Memory3
4545
import MoveForward
4646
import Naming
47+
import Naming2
4748
import Null
4849
import OperatorInvariants
4950
import Operators
@@ -112,6 +113,7 @@ newtype TCPPQuery =
112113
TMemory3PackageQuery(Memory3Query q) or
113114
TMoveForwardPackageQuery(MoveForwardQuery q) or
114115
TNamingPackageQuery(NamingQuery q) or
116+
TNaming2PackageQuery(Naming2Query q) or
115117
TNullPackageQuery(NullQuery q) or
116118
TOperatorInvariantsPackageQuery(OperatorInvariantsQuery q) or
117119
TOperatorsPackageQuery(OperatorsQuery q) or
@@ -180,6 +182,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
180182
isMemory3QueryMetadata(query, queryId, ruleId, category) or
181183
isMoveForwardQueryMetadata(query, queryId, ruleId, category) or
182184
isNamingQueryMetadata(query, queryId, ruleId, category) or
185+
isNaming2QueryMetadata(query, queryId, ruleId, category) or
183186
isNullQueryMetadata(query, queryId, ruleId, category) or
184187
isOperatorInvariantsQueryMetadata(query, queryId, ruleId, category) or
185188
isOperatorsQueryMetadata(query, queryId, ruleId, category) or

0 commit comments

Comments
 (0)