Skip to content

Commit

Permalink
Merge pull request #18367 from github/jketema/template-parameters-6
Browse files Browse the repository at this point in the history
C++: Handle template variable specializations
  • Loading branch information
jketema authored Jan 9, 2025
2 parents 928c66a + 347edc4 commit 204afab
Show file tree
Hide file tree
Showing 11 changed files with 9,749 additions and 173 deletions.
2,383 changes: 2,383 additions & 0 deletions cpp/downgrades/1a4bbe5ded083b9de87911c155fc99ca22ecb0ce/old.dbscheme

Large diffs are not rendered by default.

2,382 changes: 2,382 additions & 0 deletions cpp/downgrades/1a4bbe5ded083b9de87911c155fc99ca22ecb0ce/semmlecode.cpp.dbscheme

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
description: Support variable template specializations
compatibility: full
var_specialized.rel: delete
5 changes: 5 additions & 0 deletions cpp/ql/lib/change-notes/2024-12-25-variable-specialization.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
category: feature
---
* A new class `VariableTemplateSpecialization` was introduced, which represents explicit specializations of variable templates.
* A new predicate `isSpecialization` was added to the `Variable` class, which holds if the variable is a template specialization.
4 changes: 2 additions & 2 deletions cpp/ql/lib/semmle/code/cpp/Function.qll
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
*/
override Location getADeclarationLocation() { result = this.getADeclarationEntry().getLocation() }

/** Holds if this Function is a Template specialization. */
/** Holds if this function is a template specialization. */
predicate isSpecialization() {
exists(FunctionDeclarationEntry fde |
fun_decls(unresolveElement(fde), underlyingElement(this), _, _, _) and
Expand Down Expand Up @@ -665,7 +665,7 @@ class FunctionDeclarationEntry extends DeclarationEntry, @fun_decl {
/** Holds if this declaration is also a definition of its function. */
override predicate isDefinition() { fun_def(underlyingElement(this)) }

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

/**
Expand Down
31 changes: 30 additions & 1 deletion cpp/ql/lib/semmle/code/cpp/Variable.qll
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ class Variable extends Declaration, @variable {
* `for (char c : str) { ... }`
*/
predicate isCompilerGenerated() { compgenerated(underlyingElement(this)) }

/** Holds if this variable is a template specialization. */
predicate isSpecialization() {
exists(VariableDeclarationEntry vde |
var_decls(unresolveElement(vde), underlyingElement(this), _, _, _) and
vde.isSpecialization()
)
}
}

/**
Expand Down Expand Up @@ -267,6 +275,9 @@ class VariableDeclarationEntry extends DeclarationEntry, @var_decl {
override predicate isDefinition() { var_def(underlyingElement(this)) }

override string getASpecifier() { var_decl_specifiers(underlyingElement(this), result) }

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

/**
Expand Down Expand Up @@ -594,7 +605,10 @@ class TemplateVariable extends Variable {
/**
* Gets an instantiation of this variable template.
*/
Variable getAnInstantiation() { result.isConstructedFrom(this) }
Variable getAnInstantiation() {
result.isConstructedFrom(this) and
not result.isSpecialization()
}
}

/**
Expand Down Expand Up @@ -624,6 +638,21 @@ class VariableTemplateInstantiation extends Variable {
TemplateVariable getTemplate() { result = tv }
}

/**
* An explicit specialization of a C++ variable template.
*/
class VariableTemplateSpecialization extends Variable {
VariableTemplateSpecialization() { this.isSpecialization() }

override string getAPrimaryQlClass() { result = "VariableTemplateSpecialization" }

/**
* Gets the primary template for the specialization (the function template
* this specializes).
*/
TemplateVariable getPrimaryTemplate() { this.isConstructedFrom(result) }
}

/**
* A non-static local variable or parameter that is not part of an
* uninstantiated template. Uninstantiated templates are purely syntax, and
Expand Down
1 change: 1 addition & 0 deletions cpp/ql/lib/semmlecode.cpp.dbscheme
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ var_decls(
int location: @location_default ref
);
var_def(unique int id: @var_decl ref);
var_specialized(int id: @var_decl ref);
var_decl_specifiers(
int id: @var_decl ref,
string name: string ref
Expand Down
Loading

0 comments on commit 204afab

Please sign in to comment.