@@ -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. */
316382bindingset [ s, t]
317383private string withConst ( string s , Type t ) {
0 commit comments