-
Notifications
You must be signed in to change notification settings - Fork 76
Expand file tree
/
Copy pathExtensions.qll
More file actions
223 lines (193 loc) · 7.25 KB
/
Extensions.qll
File metadata and controls
223 lines (193 loc) · 7.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
import cpp
/**
* Common base class for modeling compiler extensions.
*/
abstract class CompilerExtension extends Locatable { }
/**
* Common base class for modeling compiler extensions in CPP.
*/
abstract class CPPCompilerExtension extends CompilerExtension {
abstract string getMessage();
}
/**
* An `Attribute` that may be a `GnuAttribute` or `Declspec`, or `MicrosoftAttribute`, etc.
*
* There are language extensions such as GNU `__attribute__`, Microsoft `__declspec` or
* `[attribute]` syntax.
*/
class CPPAttributeExtension extends CPPCompilerExtension, Attribute {
CPPAttributeExtension() { not this instanceof StdAttribute and not this instanceof AlignAs }
override string getMessage() {
result =
"Use of attribute '" + getName() +
"' is a compiler extension and is not portable to other compilers."
}
}
/**
* An `Attribute` within a compiler specific namespace such as `[[gnu::weak]]`.
*/
class CppNamespacedStdAttributeExtension extends CPPCompilerExtension, StdAttribute {
CppNamespacedStdAttributeExtension() { exists(this.getNamespace()) and not getNamespace() = "" }
override string getMessage() {
result =
"Use of attribute '" + getName() + "' in namespace '" + getNamespace() +
"' is a compiler extension and is not portable to other compilers."
}
}
class CppUnrecognizedAttributeExtension extends CPPCompilerExtension, StdAttribute {
CppUnrecognizedAttributeExtension() {
not this instanceof CppNamespacedStdAttributeExtension and
not getName() in [
"maybe_unused", "nodiscard", "noreturn", "deprecated", "carries_dependency", "fallthrough"
]
}
override string getMessage() {
result = "Use of unrecognized or non-C++17 attribute '" + getName() + "'."
}
}
/**
* Compiler-specific builtin functions.
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
*/
class CPPBuiltinFunctionExtension extends CPPCompilerExtension, FunctionCall {
CPPBuiltinFunctionExtension() {
getTarget().getName().indexOf("__builtin_") = 0 or
getTarget().getName().indexOf("__sync_") = 0 or
getTarget().getName().indexOf("__atomic_") = 0
}
override string getMessage() {
result =
"Call to builtin function '" + getTarget().getName() +
"' is a compiler extension and is not portable to other compilers."
}
}
/**
* Statement expressions: ({ ... }) syntax.
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html
*/
class CPPStmtExprExtension extends CPPCompilerExtension, StmtExpr {
override string getMessage() {
result =
"Statement expressions are a compiler extension and are not portable to other compilers."
}
}
/**
* Ternary expressions with omitted middle operand: x ?: y
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Conditionals.html
*/
class CPPTerseTernaryExtension extends CPPCompilerExtension, ConditionalExpr {
CPPTerseTernaryExtension() { getCondition() = getElse() or getCondition() = getThen() }
override string getMessage() {
result =
"Ternaries with omitted middle operands are a compiler extension and are not portable to other compilers."
}
}
/**
* Extended integer types: __int128, etc.
* Reference: https://gcc.gnu.org/onlinedocs/gcc/__int128.html
*/
class CPPExtendedIntegerTypeExtension extends CPPCompilerExtension, DeclarationEntry {
CPPExtendedIntegerTypeExtension() { getType() instanceof Int128Type }
override string getMessage() {
result = "128-bit integers are a compiler extension and are not portable to other compilers."
}
}
/**
* Extended floating-point types: __float128, _Decimal32, etc.
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html
*/
class CPPExtendedFloatTypeExtension extends CPPCompilerExtension, DeclarationEntry {
CPPExtendedFloatTypeExtension() {
getType() instanceof Decimal128Type or
getType() instanceof Decimal32Type or
getType() instanceof Decimal64Type or
getType() instanceof Float128Type
}
override string getMessage() {
result =
"Extended floating-point types are a compiler extension and are not portable to other compilers."
}
}
/**
* Zero-length arrays (flexible array members must be last).
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html
*/
class CPPZeroLengthArraysExtension extends CPPCompilerExtension, DeclarationEntry {
CPPZeroLengthArraysExtension() { getType().(ArrayType).getArraySize() = 0 }
override string getMessage() {
result = "Zero length arrays are a compiler extension and are not portable to other compilers."
}
}
/**
* Variable-length arrays in struct members (not C++17 compliant).
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html
*/
class CPPVariableLengthArraysExtension extends CPPCompilerExtension, Field {
CPPVariableLengthArraysExtension() {
getType() instanceof ArrayType and
not getType().(ArrayType).hasArraySize() and
// Not the final member of the struct, which is allowed in some contexts
not exists(int lastIndex, Class declaringStruct |
declaringStruct = getDeclaringType() and
lastIndex = count(declaringStruct.getACanonicalMember()) - 1 and
this = declaringStruct.getCanonicalMember(lastIndex)
)
}
override string getMessage() {
result =
"Variable length arrays are a compiler extension and are not portable to other compilers."
}
}
/**
* __alignof__ operator (use alignof from C++11 instead).
*/
class CPPAlignofExtension extends CPPCompilerExtension, AlignofExprOperator {
CPPAlignofExtension() { exists(getValueText().indexOf("__alignof__")) }
override string getMessage() {
result = "'__alignof__' is a compiler extension and is not portable to other compilers."
}
}
/**
* Preprocessor extensions for feature detection.
* Reference: https://clang.llvm.org/docs/LanguageExtensions.html
*/
class CPPConditionalDefineExtension extends CPPCompilerExtension, PreprocessorIfdef {
string feature;
CPPConditionalDefineExtension() {
feature =
[
"__has_builtin", "__has_constexpr_builtin", "__has_feature", "__has_extension",
"__has_attribute", "__has_declspec_attribute", "__is_identifier", "__has_include",
"__has_include_next", "__has_warning", "__has_cpp_attribute"
] and
exists(toString().indexOf(feature))
}
override string getMessage() {
result =
"Call to builtin preprocessor feature '" + feature +
"' is a compiler extension and is not portable to other compilers."
}
}
class CPPPreprocessorDirectiveExtension extends CPPCompilerExtension, PreprocessorDirective {
string kind;
CPPPreprocessorDirectiveExtension() {
this instanceof PreprocessorPragma and kind = "#pragma " + getHead()
or
this instanceof PreprocessorError and kind = "#error"
or
this instanceof PreprocessorWarning and kind = "#warning"
}
override string getMessage() {
result = "Use of non-standard preprocessor directive '" + kind + "' is a compiler extension."
}
}
/**
* Built-in type traits and operations such as `__is_abstract`, `__is_same`, etc.
*
* Reference: https://gcc.gnu.org/onlinedocs/gcc/Type-Traits.html
*/
class CPPBuiltinOperationExtension extends CPPCompilerExtension, BuiltInOperation {
override string getMessage() {
result = "Use of built-in operation '" + toString() + "' is a compiler extension."
}
}