Skip to content

Commit

Permalink
Merge pull request #18353 from jketema/template-parameters-2
Browse files Browse the repository at this point in the history
C++: Handle `sizeof...` for types and template template parameters
  • Loading branch information
jketema authored Dec 20, 2024
2 parents fd7bd6b + e9b9dc2 commit b60c860
Show file tree
Hide file tree
Showing 11 changed files with 9,435 additions and 11 deletions.
2,343 changes: 2,343 additions & 0 deletions cpp/downgrades/c3881af7e5b247d126aea68a1901b4497adf3d83/old.dbscheme

Large diffs are not rendered by default.

2,343 changes: 2,343 additions & 0 deletions cpp/downgrades/c3881af7e5b247d126aea68a1901b4497adf3d83/semmlecode.cpp.dbscheme

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
description: Allow sizeof pack in sizeof_bind
compatibility: full
4 changes: 4 additions & 0 deletions cpp/ql/lib/change-notes/2024-12-20-sizeof-pack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: feature
---
* New classes `SizeofPackExprOperator` and `SizeofPackTypeOperator` were introduced, which represent the C++ `sizeof...` operator taking an expression and a type argument, respectively.
2 changes: 2 additions & 0 deletions cpp/ql/lib/semmle/code/cpp/PrintAST.qll
Original file line number Diff line number Diff line change
Expand Up @@ -1056,6 +1056,8 @@ private predicate namedExprChildPredicates(Expr expr, Element ele, string pred)
or
expr.(SizeofExprOperator).getExprOperand() = ele and pred = "getExprOperand()"
or
expr.(SizeofPackExprOperator).getExprOperand() = ele and pred = "getExprOperand()"
or
expr.(StmtExpr).getStmt() = ele and pred = "getStmt()"
or
expr.(ThrowExpr).getExpr() = ele and pred = "getExpr()"
Expand Down
52 changes: 47 additions & 5 deletions cpp/ql/lib/semmle/code/cpp/exprs/Cast.qll
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,8 @@ class TypeidOperator extends Expr, @type_id {
}

/**
* A C++11 `sizeof...` expression which determines the size of a template parameter pack.
* A C++11 `sizeof...` expression which determines the size of a template
* parameter pack.
*
* This expression only appears in templates themselves - in any actual
* instantiations, "sizeof...(x)" will be replaced by its integer value.
Expand All @@ -694,15 +695,56 @@ class TypeidOperator extends Expr, @type_id {
* ```
*/
class SizeofPackOperator extends Expr, @sizeof_pack {
override string toString() { result = "sizeof...(...)" }

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

override predicate mayBeImpure() { none() }

override predicate mayBeGloballyImpure() { none() }
}

/**
* A C++11 `sizeof...` expression which determines the size of a template
* parameter pack and whose operand is an expression.
*
* This expression only appears in templates themselves - in any actual
* instantiations, "sizeof...(x)" will be replaced by its integer value.
* ```
* template < typename... T >
* int count ( T &&... t ) { return sizeof... ( t ); }
* ```
*/
class SizeofPackExprOperator extends SizeofPackOperator {
SizeofPackExprOperator() { exists(this.getChild(0)) }

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

/** Gets the contained expression. */
Expr getExprOperand() { result = this.getChild(0) }

override string toString() { result = "sizeof...(<expr>)" }
}

/**
* A C++11 `sizeof...` expression which determines the size of a template
* parameter pack and whose operand is an type name or a template template
* parameter.
*
* This expression only appears in templates themselves - in any actual
* instantiations, "sizeof...(x)" will be replaced by its integer value.
* ```
* template < typename... T >
* int count ( T &&... t ) { return sizeof... ( T ); }
* ```
*/
class SizeofPackTypeOperator extends SizeofPackOperator {
SizeofPackTypeOperator() { sizeof_bind(underlyingElement(this), _) }

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

/** Gets the contained type. */
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }

override string toString() { result = "sizeof...(" + this.getTypeOperand().getName() + ")" }
}

/**
* A C/C++ sizeof expression.
*/
Expand Down
4 changes: 2 additions & 2 deletions cpp/ql/lib/semmlecode.cpp.dbscheme
Original file line number Diff line number Diff line change
Expand Up @@ -1994,10 +1994,10 @@ uuidof_bind(
int type_id: @type ref
);

@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof;
@sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof | @sizeof_pack;

sizeof_bind(
unique int expr: @runtime_sizeof_or_alignof ref,
unique int expr: @sizeof_or_alignof ref,
int type_id: @type ref
);

Expand Down
Loading

0 comments on commit b60c860

Please sign in to comment.