From 84775b71c357074b34e5c7f0e82135d5324cebf6 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Sun, 22 Dec 2024 22:57:27 +0100 Subject: [PATCH 1/5] C++: Support arguments and instantiations of template template parameters --- cpp/ql/lib/semmle/code/cpp/Class.qll | 9 ++-- cpp/ql/lib/semmle/code/cpp/Declaration.qll | 4 ++ .../lib/semmle/code/cpp/TemplateParameter.qll | 41 +++++++++++++++++++ cpp/ql/lib/semmlecode.cpp.dbscheme | 15 +++++++ 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/cpp/ql/lib/semmle/code/cpp/Class.qll b/cpp/ql/lib/semmle/code/cpp/Class.qll index 42c46e94fe66..2fe62d1ac164 100644 --- a/cpp/ql/lib/semmle/code/cpp/Class.qll +++ b/cpp/ql/lib/semmle/code/cpp/Class.qll @@ -570,10 +570,13 @@ class Class extends UserType { /** * Holds if this class, struct or union is constructed from another class as * a result of template instantiation. It originates either from a class - * template or from a class nested in a class template. + * template, a class nested in a class template, or a template template + * parameter. */ - predicate isConstructedFrom(Class c) { - class_instantiation(underlyingElement(this), unresolveElement(c)) + predicate isConstructedFrom(UserType t) { + class_instantiation(underlyingElement(this), unresolveElement(t)) + or + template_template_instantiation(underlyingElement(this), unresolveElement(t)) } /** diff --git a/cpp/ql/lib/semmle/code/cpp/Declaration.qll b/cpp/ql/lib/semmle/code/cpp/Declaration.qll index 60d391b65971..3aa2c130448d 100644 --- a/cpp/ql/lib/semmle/code/cpp/Declaration.qll +++ b/cpp/ql/lib/semmle/code/cpp/Declaration.qll @@ -277,6 +277,8 @@ class Declaration extends Locatable, @declaration { function_template_argument(underlyingElement(this), index, unresolveElement(result)) or variable_template_argument(underlyingElement(this), index, unresolveElement(result)) + or + template_template_argument(underlyingElement(this), index, unresolveElement(result)) } private Expr getTemplateArgumentValue(int index) { @@ -285,6 +287,8 @@ class Declaration extends Locatable, @declaration { function_template_argument_value(underlyingElement(this), index, unresolveElement(result)) or variable_template_argument_value(underlyingElement(this), index, unresolveElement(result)) + or + template_template_argument_value(underlyingElement(this), index, unresolveElement(result)) } } diff --git a/cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll b/cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll index 6c10f648825d..c127af22a9d6 100644 --- a/cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll +++ b/cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll @@ -75,6 +75,18 @@ class TemplateTemplateParameter extends TypeTemplateParameter { TemplateTemplateParameter() { usertypes(underlyingElement(this), _, 8) } override string getAPrimaryQlClass() { result = "TemplateTemplateParameter" } + + /** + * Gets a class instantiated from this template template parameter. + * + * For example for `Container` in the following code, the results is + * `Container`: + * ``` + * template