Skip to content

Commit 7aaab05

Browse files
committed
Add first draft of Template.qll
1 parent e8b910e commit 7aaab05

File tree

1 file changed

+207
-0
lines changed

1 file changed

+207
-0
lines changed
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
import cpp
2+
3+
newtype TTemplateElement =
4+
TTemplateClass(TemplateClass c) or
5+
TTemplateFunction(TemplateFunction f) or
6+
TTemplateVariable(TemplateVariable v)
7+
8+
/**
9+
* A templated element. These are either templated classes, templated functions,
10+
* or templated variables.
11+
*/
12+
class TemplateElement extends TTemplateElement {
13+
TemplateClass asTemplateClass() { this = TTemplateClass(result) }
14+
15+
TemplateFunction asTemplateFunction() { this = TTemplateFunction(result) }
16+
17+
TemplateVariable asTemplateVariable() { this = TTemplateVariable(result) }
18+
19+
string toString() {
20+
result = this.asTemplateClass().toString() or
21+
result = this.asTemplateFunction().toString() or
22+
result = this.asTemplateVariable().toString()
23+
}
24+
25+
Location getLocation() {
26+
result = this.asTemplateClass().getLocation() or
27+
result = this.asTemplateFunction().getLocation() or
28+
result = this.asTemplateVariable().getLocation()
29+
}
30+
31+
string getName() {
32+
result = this.asTemplateClass().getName() or
33+
result = this.asTemplateFunction().getName() or
34+
result = this.asTemplateVariable().getName()
35+
}
36+
}
37+
38+
newtype TTemplateInstantiation =
39+
TClassTemplateInstantiation(ClassTemplateInstantiation c) or
40+
TFunctionTemplateInstantiation(FunctionTemplateInstantiation f) or
41+
TVariableTemplateInstantiation(VariableTemplateInstantiation v)
42+
43+
/**
44+
* An instantiation of a templated element, either a templated class, templated
45+
* function, or templated variable.
46+
*/
47+
class TemplateInstantiation extends TTemplateInstantiation {
48+
ClassTemplateInstantiation asClassTemplateInstantiation() {
49+
this = TClassTemplateInstantiation(result)
50+
}
51+
52+
FunctionTemplateInstantiation asFunctionTemplateInstantiation() {
53+
this = TFunctionTemplateInstantiation(result)
54+
}
55+
56+
VariableTemplateInstantiation asVariableTemplateInstantiation() {
57+
this = TVariableTemplateInstantiation(result)
58+
}
59+
60+
string toString() {
61+
result = this.asClassTemplateInstantiation().toString() or
62+
result = this.asFunctionTemplateInstantiation().toString() or
63+
result = this.asVariableTemplateInstantiation().toString()
64+
}
65+
66+
Location getLocation() {
67+
result = this.asClassTemplateInstantiation().getLocation() or
68+
result = this.asFunctionTemplateInstantiation().getLocation() or
69+
result = this.asVariableTemplateInstantiation().getLocation()
70+
}
71+
72+
Element asElement() {
73+
result = this.asClassTemplateInstantiation() or
74+
result = this.asFunctionTemplateInstantiation() or
75+
result = this.asVariableTemplateInstantiation()
76+
}
77+
78+
/**
79+
* Gets the template this instantiation is from, depending on the kind of the element
80+
* this instantiation is for.
81+
*/
82+
TemplateElement getTemplate() {
83+
result.asTemplateClass() = this.asClassTemplateInstantiation().getTemplate() or
84+
result.asTemplateFunction() = this.asFunctionTemplateInstantiation().getTemplate() or
85+
result.asTemplateVariable() = this.asVariableTemplateInstantiation().getTemplate()
86+
}
87+
88+
/**
89+
* Gets a use of an instantiation of this template. i.e.
90+
* 1. For a class template, it's where the instantiated type is used by the name.
91+
* 2. For a function template, it's where the instantiated function is called.
92+
* 3. For a variable template, it's where the instantiated variable is initialized.
93+
*/
94+
Element getAUse() {
95+
result = this.asClassTemplateInstantiation().getATypeNameUse() or
96+
result = this.asFunctionTemplateInstantiation().getACallToThisFunction() or
97+
result = this.asVariableTemplateInstantiation()
98+
}
99+
}
100+
101+
/**
102+
* An implicit conversion from a plain char type to an explicitly signed or unsigned char
103+
* type. `std::uint8_t` and `std::int8_t` are also considered as these char types.
104+
*
105+
* Note that this class only includes implicit conversions and does not include explicit
106+
* type conversions, i.e. casts.
107+
*/
108+
class ImplicitConversionFromPlainCharType extends Conversion {
109+
ImplicitConversionFromPlainCharType() {
110+
this.isImplicit() and
111+
this.getExpr().getUnspecifiedType() instanceof PlainCharType and
112+
(
113+
this.getUnspecifiedType() instanceof SignedCharType or
114+
this.getUnspecifiedType() instanceof UnsignedCharType
115+
)
116+
}
117+
}
118+
119+
newtype TImplicitConversionElement =
120+
TImplicitConversionOutsideTemplate(ImplicitConversionFromPlainCharType implicitConversion) {
121+
not exists(TemplateInstantiation instantiation |
122+
implicitConversion.isFromTemplateInstantiation(instantiation.asElement())
123+
)
124+
} or
125+
TInstantiationOfImplicitConversionTemplate(
126+
TemplateInstantiation templateInstantiation,
127+
ImplicitConversionFromPlainCharType implicitConversion
128+
) {
129+
implicitConversion.getEnclosingElement+() = templateInstantiation.asElement()
130+
}
131+
132+
/**
133+
* The locations where the implicit conversion from a plain char to an explicitly signed / unsigned
134+
* char is taking place on a high level. It splits case on whether the conversion is caused by
135+
* instantiating a template:
136+
*
137+
* - For conversions not due to template usage (i.e. outside a templated element), this refers to
138+
* the same element as the one associated with the conversion.
139+
* - For conversions due to template usage, this refers to the element that uses the instantiation
140+
* of a template where an implicit char conversion happens.
141+
*/
142+
class ImplicitConversionLocation extends TImplicitConversionElement {
143+
ImplicitConversionFromPlainCharType asImplicitConversionOutsideTemplate() {
144+
this = TImplicitConversionOutsideTemplate(result)
145+
}
146+
147+
TemplateInstantiation asInstantiationOfImplicitConversionTemplate(
148+
ImplicitConversionFromPlainCharType implicitConversion
149+
) {
150+
this = TInstantiationOfImplicitConversionTemplate(result, implicitConversion)
151+
}
152+
153+
/**
154+
* Holds if this is a location of a conversion happening outside of a template.
155+
*/
156+
predicate isImplicitConversionOutsideTemplate() {
157+
exists(this.asImplicitConversionOutsideTemplate())
158+
}
159+
160+
/**
161+
* Holds if this is a location of a conversion happening due to instantiating a
162+
* template.
163+
*/
164+
predicate isInstantiationOfImplicitConversionTemplate() {
165+
exists(
166+
TemplateInstantiation templateInstantiation,
167+
ImplicitConversionFromPlainCharType implicitConversion
168+
|
169+
templateInstantiation = this.asInstantiationOfImplicitConversionTemplate(implicitConversion)
170+
)
171+
}
172+
173+
/**
174+
* Gets the implicit conversion that this location is associated with.
175+
* - In cases of conversions not involving a template, this is the same as the
176+
* location associated with the conversion.
177+
* - In cases of conversions due to using a template, this is the conversion that
178+
* happens in the instantiated template.
179+
*/
180+
ImplicitConversionFromPlainCharType getImplicitConversion() {
181+
result = this.asImplicitConversionOutsideTemplate() or
182+
exists(TemplateInstantiation templateInstantiation |
183+
this = TInstantiationOfImplicitConversionTemplate(templateInstantiation, result)
184+
)
185+
}
186+
187+
string toString() {
188+
result = this.asImplicitConversionOutsideTemplate().toString() or
189+
exists(ImplicitConversionFromPlainCharType implicitConversion |
190+
result = this.asInstantiationOfImplicitConversionTemplate(implicitConversion).toString()
191+
)
192+
}
193+
194+
Location getLocation() {
195+
result = this.asImplicitConversionOutsideTemplate().getLocation() or
196+
exists(ImplicitConversionFromPlainCharType implicitConversion |
197+
result = this.asInstantiationOfImplicitConversionTemplate(implicitConversion).getLocation()
198+
)
199+
}
200+
201+
Element asElement() {
202+
result = this.asImplicitConversionOutsideTemplate() or
203+
exists(ImplicitConversionFromPlainCharType implicitConversion |
204+
result = this.asInstantiationOfImplicitConversionTemplate(implicitConversion).getAUse()
205+
)
206+
}
207+
}

0 commit comments

Comments
 (0)