Skip to content

Commit 8393b40

Browse files
committed
C++: Use the new extensionals to map template functions and classes to their fully templated versions.
1 parent 5f54a86 commit 8393b40

1 file changed

Lines changed: 68 additions & 2 deletions

File tree

cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -277,11 +277,44 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) {
277277
}
278278

279279
/** Gets the fully templated version of `f`. */
280-
private Class getFullyTemplatedClass(Class c) {
280+
private Class getFullyTemplatedClassOld(Class c) {
281281
not c.isFromUninstantiatedTemplate(_) and
282282
isClassConstructedFrom(c, result)
283283
}
284284

285+
private TemplateClass getOriginalClassTemplate(TemplateClass tc) {
286+
result = tc.getOriginalTemplate()
287+
or
288+
not exists(tc.getOriginalTemplate()) and
289+
result = tc
290+
}
291+
292+
/** Gets the fully templated version of `f`. */
293+
private Class getFullyTemplatedClassNew(Class c) {
294+
not c.isFromUninstantiatedTemplate(_) and
295+
exists(Class mid |
296+
c.isConstructedFrom(mid)
297+
or
298+
not c.isConstructedFrom(_) and c = mid
299+
|
300+
result = getOriginalClassTemplate(mid)
301+
or
302+
not mid instanceof TemplateClass and mid = result
303+
)
304+
}
305+
306+
/** Gets the fully templated version of `c`. */
307+
private Class getFullyTemplatedClass(Class c) {
308+
// The `Class::getOriginalTemplate` predicate was introduced in CodeQL
309+
// version 2.25.6 and the upgrade script leaves the
310+
// `class_template_generated_from` extensionals empty if the database
311+
// was generated with an older extractor. So we use the old implementation
312+
// if the `class_template_generated_from` extensional is empty.
313+
if class_template_generated_from(_, _)
314+
then result = getFullyTemplatedClassNew(c)
315+
else result = getFullyTemplatedClassOld(c)
316+
}
317+
285318
/**
286319
* Holds if `f` is an instantiation of a function template `templateFunc`, or
287320
* holds with `f = templateFunc` if `f` is not an instantiation of any function
@@ -298,7 +331,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
298331
}
299332

300333
/** Gets the fully templated version of `f`. */
301-
Function getFullyTemplatedFunction(Function f) {
334+
private Function getFullyTemplatedFunctionOld(Function f) {
302335
not f.isFromUninstantiatedTemplate(_) and
303336
(
304337
exists(Class c, Class templateClass, int i |
@@ -312,6 +345,39 @@ Function getFullyTemplatedFunction(Function f) {
312345
)
313346
}
314347

348+
private TemplateFunction getOriginalFunctionTemplate(TemplateFunction tf) {
349+
result = tf.getOriginalTemplate()
350+
or
351+
not exists(tf.getOriginalTemplate()) and
352+
result = tf
353+
}
354+
355+
/** Gets the fully templated version of `f`. */
356+
private Function getFullyTemplatedFunctionNew(Function f) {
357+
not f.isFromUninstantiatedTemplate(_) and
358+
exists(Function mid |
359+
f.isConstructedFrom(mid)
360+
or
361+
not f.isConstructedFrom(_) and f = mid
362+
|
363+
result = getOriginalFunctionTemplate(mid)
364+
or
365+
not mid instanceof TemplateFunction and mid = result
366+
)
367+
}
368+
369+
/** Gets the fully templated version of `f`. */
370+
Function getFullyTemplatedFunction(Function f) {
371+
// The `Function::getOriginalTemplate` predicate was introduced in CodeQL
372+
// version 2.25.6 and the upgrade script leaves the
373+
// `function_template_generated_from` extensionals empty if the database
374+
// was generated with an older extractor. So we use the old implementation
375+
// if the `function_template_generated_from` extensional is empty.
376+
if function_template_generated_from(_, _)
377+
then result = getFullyTemplatedFunctionNew(f)
378+
else result = getFullyTemplatedFunctionOld(f)
379+
}
380+
315381
/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
316382
bindingset[s, t]
317383
private string withConst(string s, Type t) {

0 commit comments

Comments
 (0)