@@ -277,11 +277,43 @@ 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+ private Class getFullyTemplatedClass ( Class c ) {
307+ // The `Class::getOriginalTemplate` predicate was introduced in CodeQL
308+ // version 2.25.6 and the upgrade script leaves the
309+ // `class_template_generated_from` extensionals empty if the database
310+ // was generated with an older extractor. So we use the old implementation
311+ // if the `class_template_generated_from` extensional is empty.
312+ if class_template_generated_from ( _, _)
313+ then result = getFullyTemplatedClassNew ( c )
314+ else result = getFullyTemplatedClassOld ( c )
315+ }
316+
285317/**
286318 * Holds if `f` is an instantiation of a function template `templateFunc`, or
287319 * holds with `f = templateFunc` if `f` is not an instantiation of any function
@@ -298,7 +330,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
298330}
299331
300332/** Gets the fully templated version of `f`. */
301- Function getFullyTemplatedFunction ( Function f ) {
333+ private Function getFullyTemplatedFunctionOld ( Function f ) {
302334 not f .isFromUninstantiatedTemplate ( _) and
303335 (
304336 exists ( Class c , Class templateClass , int i |
@@ -312,6 +344,38 @@ Function getFullyTemplatedFunction(Function f) {
312344 )
313345}
314346
347+ private TemplateFunction getOriginalFunctionTemplate ( TemplateFunction tf ) {
348+ result = tf .getOriginalTemplate ( )
349+ or
350+ not exists ( tf .getOriginalTemplate ( ) ) and
351+ result = tf
352+ }
353+
354+ /** Gets the fully templated version of `f`. */
355+ private Function getFullyTemplatedFunctionNew ( Function f ) {
356+ not f .isFromUninstantiatedTemplate ( _) and
357+ exists ( Function mid |
358+ f .isConstructedFrom ( mid )
359+ or
360+ not f .isConstructedFrom ( _) and f = mid
361+ |
362+ result = getOriginalFunctionTemplate ( mid )
363+ or
364+ not mid instanceof TemplateFunction and mid = result
365+ )
366+ }
367+
368+ private Function getFullyTemplatedFunction ( Function f ) {
369+ // The `Function::getOriginalTemplate` predicate was introduced in CodeQL
370+ // version 2.25.6 and the upgrade script leaves the
371+ // `function_template_generated_from` extensionals empty if the database
372+ // was generated with an older extractor. So we use the old implementation
373+ // if the `function_template_generated_from` extensional is empty.
374+ if function_template_generated_from ( _, _)
375+ then result = getFullyTemplatedFunctionNew ( f )
376+ else result = getFullyTemplatedFunctionOld ( f )
377+ }
378+
315379/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
316380bindingset [ s, t]
317381private string withConst ( string s , Type t ) {
0 commit comments