Skip to content

Commit

Permalink
Merge pull request #18368 from github/jketema/template-parameters-7
Browse files Browse the repository at this point in the history
C++: Handle requires clauses and type template type constraints
  • Loading branch information
jketema authored Jan 10, 2025
2 parents a7fb73a + 0a292fb commit 8c3e5b6
Show file tree
Hide file tree
Showing 13 changed files with 10,225 additions and 297 deletions.
2,409 changes: 2,409 additions & 0 deletions cpp/downgrades/dd32242a870867a532bb0b2a88a6a917a5b4c26f/old.dbscheme

Large diffs are not rendered by default.

2,383 changes: 2,383 additions & 0 deletions cpp/downgrades/dd32242a870867a532bb0b2a88a6a917a5b4c26f/semmlecode.cpp.dbscheme

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
description: Support requires clauses and type constraints
compatibility: full
fun_requires.rel: delete
var_requires.rel: delete
type_requires.rel: delete
type_template_type_constraint.rel: delete
7 changes: 7 additions & 0 deletions cpp/ql/lib/change-notes/2024-12-26-requires-clause.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
category: feature
---
* New predicates `getARequiresClause`, `getTemplateRequiresClause` and `getFunctionRequiresClause` were added to the `FunctionDeclarationEntry` class, which yield the requires clauses when the entry represents a function template declaration with requires clauses.
* A new predicate `getRequiresClause` was added to the `TypeDeclarationEntry` class, which yields the requires clause when the entry represents a class template declaration with a requires clause.
* A new predicate `getRequiresClause` was added to the `VariableDeclarationEntry` class, which yields the requires clause when the entry represents a variable template declaration with a requires clause.
* A new predicate `getTypeConstraint` was added to the `TypeTemplateParameter` class, which yields the type constraint of the parameter if it exists.
21 changes: 21 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/Function.qll
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,27 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
* specification.
*/
predicate isNoExcept() { fun_decl_empty_noexcept(underlyingElement(this)) }

/**
* Gets a requires clause if this declaration is a template with such a clause.
*/
Expr getARequiresClause() { fun_requires(underlyingElement(this), _, unresolveElement(result)) }

/**
* Gets the requires clause that appears after the template argument list if this
* declaration is a template with such a clause.
*/
Expr getTemplateRequiresClause() {
fun_requires(underlyingElement(this), 1, unresolveElement(result))
}

/**
* Gets the requires clause that appears after the declarator if this declaration
* is a template with such a clause.
*/
Expr getFunctionRequiresClause() {
fun_requires(underlyingElement(this), 2, unresolveElement(result))
}
}

/**
Expand Down
7 changes: 7 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/TemplateParameter.qll
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ class TypeTemplateParameter extends UserType, TemplateParameterImpl {
override string getAPrimaryQlClass() { result = "TypeTemplateParameter" }

override predicate involvesTemplateParameter() { any() }

/**
* Get the type constraint of this type template parameter.
*/
Expr getTypeConstraint() {
type_template_type_constraint(underlyingElement(this), unresolveElement(result))
}
}

/**
Expand Down
5 changes: 5 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/UserType.qll
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,9 @@ class TypeDeclarationEntry extends DeclarationEntry, @type_decl {
* class or typedef.
*/
predicate isTopLevel() { type_decl_top(underlyingElement(this)) }

/**
* Gets the requires clause if this declaration is a template with such a clause.
*/
Expr getRequiresClause() { type_requires(underlyingElement(this), unresolveElement(result)) }
}
5 changes: 5 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/Variable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,11 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {

/** Holds if this declaration is a template specialization. */
predicate isSpecialization() { var_specialized(underlyingElement(this)) }

/**
* Gets the requires clause if this declaration is a template with such a clause.
*/
Expr getRequiresClause() { var_requires(underlyingElement(this), unresolveElement(result)) }
}

/**
Expand Down
26 changes: 26 additions & 0 deletions cpp/ql/lib/semmlecode.cpp.dbscheme
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,19 @@ fun_decl_typedef_type(
int typedeftype_id: @usertype ref
);

/*
case @fun_requires.kind of
1 = @template_attached
| 2 = @function_attached
;
*/

fun_requires(
int id: @fun_decl ref,
int kind: int ref,
int constraint: @expr ref
);

param_decl_bind(
unique int id: @var_decl ref,
int index: int ref,
Expand All @@ -501,6 +514,10 @@ var_decl_specifiers(
string name: string ref
)
is_structured_binding(unique int id: @variable ref);
var_requires(
int id: @var_decl ref,
int constraint: @expr ref
);

type_decls(
unique int id: @type_decl,
Expand All @@ -511,6 +528,10 @@ type_def(unique int id: @type_decl ref);
type_decl_top(
unique int type_decl: @type_decl ref
);
type_requires(
int id: @type_decl ref,
int constraint: @expr ref
);

namespace_decls(
unique int id: @namespace_decl,
Expand Down Expand Up @@ -790,6 +811,11 @@ nontype_template_parameters(
int id: @expr ref
);

type_template_type_constraint(
int id: @usertype ref,
int constraint: @expr ref
);

mangled_name(
unique int id: @declaration ref,
int mangled_name : @mangledname,
Expand Down
Loading

0 comments on commit 8c3e5b6

Please sign in to comment.