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