mirror of
https://github.com/github/codeql.git
synced 2025-12-16 08:43:11 +01:00
C++: Add support for more clang builtins
This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
predicate isExprWithNewBuiltin(Expr expr) {
|
||||
exists(int kind | exprs(expr, kind, _) | 385 <= kind and kind <= 388)
|
||||
}
|
||||
|
||||
from Expr expr, int kind, int kind_new, Location location
|
||||
where
|
||||
exprs(expr, kind, location) and
|
||||
if isExprWithNewBuiltin(expr) then kind_new = 1 else kind_new = kind
|
||||
select expr, kind_new, location
|
||||
2317
cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme
Normal file
2317
cpp/downgrades/02a123a1a681f98cf502f189a2a79b0dfb398e59/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
class Expr extends @expr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Type extends @type {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Expr expr, Type type, int kind
|
||||
where
|
||||
sizeof_bind(expr, type) and
|
||||
exprs(expr, kind, _) and
|
||||
(kind = 93 or kind = 94)
|
||||
select expr, type
|
||||
@@ -0,0 +1,4 @@
|
||||
description: Add new builtin operations
|
||||
compatibility: partial
|
||||
exprs.rel: run exprs.qlo
|
||||
sizeof_bind.rel: run sizeof_bind.qlo
|
||||
@@ -1885,3 +1885,59 @@ class BuiltInOperationIsWinInterface extends BuiltInOperation, @iswininterface {
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsWinInterface" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_trivially_equality_comparable` built-in operation.
|
||||
*
|
||||
* Returns `true` if comparing two objects of type `_Tp` is equivalent to
|
||||
* comparing their object representations.
|
||||
*
|
||||
* ```
|
||||
* template<typename _Tp>
|
||||
* struct is_trivially_equality_comparable
|
||||
* : public integral_constant<bool, __is_trivially_equality_comparable(_Tp)>
|
||||
* {};
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyEqualityComparable extends BuiltInOperation,
|
||||
@istriviallyequalitycomparable
|
||||
{
|
||||
override string toString() { result = "__is_trivially_equality_comparable" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyEqualityComparable" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_scoped_enum` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if a type is a scoped enum.
|
||||
* ```
|
||||
* template<typename _Tp>
|
||||
* constexpr bool is_scoped_enum = __is_scoped_enum(_Tp);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsScopedEnum extends BuiltInOperation, @isscopedenum {
|
||||
override string toString() { result = "__is_scoped_enum" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsScopedEnum" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_trivially_relocatable` built-in operation.
|
||||
*
|
||||
* Returns `true` if moving an object of type `_Tp` is equivalent to
|
||||
* copying the underlying bytes.
|
||||
*
|
||||
* ```
|
||||
* template<typename _Tp>
|
||||
* struct is_trivially_relocatable
|
||||
* : public integral_constant<bool, __is_trivially_relocatable(_Tp)>
|
||||
* {};
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyRelocatable extends BuiltInOperation, @istriviallyrelocatable {
|
||||
override string toString() { result = "__is_trivially_relocatable" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BuiltInOperationIsTriviallyRelocatable" }
|
||||
}
|
||||
|
||||
@@ -791,6 +791,53 @@ class AlignofTypeOperator extends AlignofOperator {
|
||||
override string toString() { result = "alignof(" + this.getTypeOperand().getName() + ")" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__datasizeof` expression (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* The `__datasizeof` expression behaves identical to `sizeof` except
|
||||
* that the result ignores tail padding.
|
||||
*/
|
||||
class DatasizeofOperator extends Expr, @datasizeof {
|
||||
override int getPrecedence() { result = 16 }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__datasizeof` expression whose operand is an expression.
|
||||
*/
|
||||
class DatasizeofExprOperator extends DatasizeofOperator {
|
||||
DatasizeofExprOperator() { exists(this.getChild(0)) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DatasizeofExprOperator" }
|
||||
|
||||
/** Gets the contained expression. */
|
||||
Expr getExprOperand() { result = this.getChild(0) }
|
||||
|
||||
override string toString() { result = "sizeof(<expr>)" }
|
||||
|
||||
override predicate mayBeImpure() { this.getExprOperand().mayBeImpure() }
|
||||
|
||||
override predicate mayBeGloballyImpure() { this.getExprOperand().mayBeGloballyImpure() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__datasizeof` expression whose operand is a type name.
|
||||
*/
|
||||
class DatasizeofTypeOperator extends DatasizeofOperator {
|
||||
DatasizeofTypeOperator() { sizeof_bind(underlyingElement(this), _) }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DatasizeofTypeOperator" }
|
||||
|
||||
/** Gets the contained type. */
|
||||
Type getTypeOperand() { sizeof_bind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
override string toString() { result = "sizeof(" + this.getTypeOperand().getName() + ")" }
|
||||
|
||||
override predicate mayBeImpure() { none() }
|
||||
|
||||
override predicate mayBeGloballyImpure() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ array to pointer conversion.
|
||||
*
|
||||
|
||||
@@ -304,6 +304,8 @@ class Expr extends StmtParent, @expr {
|
||||
e instanceof NoExceptExpr
|
||||
or
|
||||
e instanceof AlignofOperator
|
||||
or
|
||||
e instanceof DatasizeofOperator
|
||||
)
|
||||
or
|
||||
exists(Decltype d | d.getExpr() = this.getParentWithConversions*())
|
||||
|
||||
@@ -1788,6 +1788,10 @@ case @expr.kind of
|
||||
| 382 = @isvalidwinrttype
|
||||
| 383 = @iswinclass
|
||||
| 384 = @iswininterface
|
||||
| 385 = @istriviallyequalitycomparable
|
||||
| 386 = @isscopedenum
|
||||
| 387 = @istriviallyrelocatable
|
||||
| 388 = @datasizeof
|
||||
;
|
||||
|
||||
@var_args_expr = @vastartexpr
|
||||
@@ -1901,6 +1905,9 @@ case @expr.kind of
|
||||
| @isvalidwinrttype
|
||||
| @iswinclass
|
||||
| @iswininterface
|
||||
| @istriviallyequalitycomparable
|
||||
| @isscopedenum
|
||||
| @istriviallyrelocatable
|
||||
;
|
||||
|
||||
new_allocated_type(
|
||||
@@ -1961,7 +1968,7 @@ uuidof_bind(
|
||||
int type_id: @type ref
|
||||
);
|
||||
|
||||
@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof;
|
||||
@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof | @datasizeof;
|
||||
|
||||
sizeof_bind(
|
||||
unique int expr: @runtime_sizeof_or_alignof ref,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Add new builtin operations
|
||||
compatibility: backwards
|
||||
@@ -1,4 +1,4 @@
|
||||
// semmle-extractor-options: --clang --clang_version 180000
|
||||
// semmle-extractor-options: --clang --edg --clang_version --edg 190000
|
||||
|
||||
struct S {
|
||||
void f() {}
|
||||
@@ -108,3 +108,16 @@ bool b_is_unbounded_array2 = __is_unbounded_array(int[42]);
|
||||
|
||||
bool b_is_referenceable1 = __is_referenceable(int);
|
||||
bool b_is_referenceable2 = __is_referenceable(void);
|
||||
|
||||
bool b_is_trivially_equality_comparable1 = __is_trivially_equality_comparable(int);
|
||||
bool b_is_trivially_equality_comparable2 = __is_trivially_equality_comparable(void);
|
||||
|
||||
enum class E {
|
||||
a, b
|
||||
};
|
||||
|
||||
bool b_is_scoped_enum1 = __is_scoped_enum(E);
|
||||
bool b_is_scoped_enum2 = __is_scoped_enum(int);
|
||||
|
||||
bool b_is_trivially_relocatable1 = __is_trivially_relocatable(int);
|
||||
bool b_is_trivially_relocatable2 = __is_trivially_relocatable(void);
|
||||
|
||||
@@ -153,7 +153,21 @@
|
||||
| clang.cpp:109:28:109:50 | int | | <none> |
|
||||
| clang.cpp:110:28:110:51 | __is_referenceable | void | 0 |
|
||||
| clang.cpp:110:28:110:51 | void | | <none> |
|
||||
| clang.cpp:112:44:112:82 | __is_trivially_equality_comparable | int | 1 |
|
||||
| clang.cpp:112:44:112:82 | int | | <none> |
|
||||
| clang.cpp:113:44:113:83 | __is_trivially_equality_comparable | void | 0 |
|
||||
| clang.cpp:113:44:113:83 | void | | <none> |
|
||||
| clang.cpp:119:26:119:44 | E | | <none> |
|
||||
| clang.cpp:119:26:119:44 | __is_scoped_enum | E | 1 |
|
||||
| clang.cpp:120:26:120:46 | __is_scoped_enum | int | 0 |
|
||||
| clang.cpp:120:26:120:46 | int | | <none> |
|
||||
| clang.cpp:122:36:122:66 | __is_trivially_relocatable | int | 1 |
|
||||
| clang.cpp:122:36:122:66 | int | | <none> |
|
||||
| clang.cpp:123:36:123:67 | __is_trivially_relocatable | void | 0 |
|
||||
| clang.cpp:123:36:123:67 | void | | <none> |
|
||||
| file://:0:0:0:0 | 0 | | 0 |
|
||||
| file://:0:0:0:0 | 0 | | 0 |
|
||||
| file://:0:0:0:0 | 1 | | 1 |
|
||||
| file://:0:0:0:0 | 1 | | 1 |
|
||||
| file://:0:0:0:0 | 2 | | 2 |
|
||||
| gcc.cpp:3:25:3:25 | 8 | | 8 |
|
||||
|
||||
30
cpp/ql/test/library-tests/types/datasizeof/datasizeof.cpp
Normal file
30
cpp/ql/test/library-tests/types/datasizeof/datasizeof.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// semmle-extractor-options: --clang --edg --clang_version --edg 190000
|
||||
|
||||
typedef unsigned int size_t;
|
||||
|
||||
class MyClass
|
||||
{
|
||||
public:
|
||||
int x;
|
||||
int *ptr;
|
||||
char c;
|
||||
};
|
||||
|
||||
void func() {
|
||||
int i;
|
||||
char c;
|
||||
int * ptr;
|
||||
MyClass mc;
|
||||
int arr[10];
|
||||
|
||||
size_t sz1 = __datasizeof(int);
|
||||
size_t sz2 = __datasizeof(char);
|
||||
size_t sz3 = __datasizeof(int *);
|
||||
size_t sz4 = __datasizeof(MyClass);
|
||||
size_t sz5 = __datasizeof(i);
|
||||
size_t sz6 = __datasizeof(c);
|
||||
size_t sz7 = __datasizeof(ptr);
|
||||
size_t sz8 = __datasizeof(mc);
|
||||
size_t sz9 = __datasizeof(arr);
|
||||
size_t sz10 = __datasizeof(arr[4]);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
| datasizeof.cpp:20:15:20:31 | sizeof(int) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int |
|
||||
| datasizeof.cpp:21:15:21:32 | sizeof(char) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | char |
|
||||
| datasizeof.cpp:22:15:22:33 | sizeof(int *) | DatasizeofTypeOperator.getTypeOperand() | file://:0:0:0:0 | int * |
|
||||
| datasizeof.cpp:23:15:23:35 | sizeof(MyClass) | DatasizeofTypeOperator.getTypeOperand() | datasizeof.cpp:5:7:5:13 | MyClass |
|
||||
| datasizeof.cpp:24:15:24:29 | sizeof(<expr>) | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:24:28:24:28 | i |
|
||||
| datasizeof.cpp:25:15:25:29 | sizeof(<expr>) | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:25:28:25:28 | c |
|
||||
| datasizeof.cpp:26:15:26:31 | sizeof(<expr>) | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:26:28:26:30 | ptr |
|
||||
| datasizeof.cpp:27:15:27:30 | sizeof(<expr>) | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:27:28:27:29 | mc |
|
||||
| datasizeof.cpp:28:15:28:31 | sizeof(<expr>) | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:28:28:28:30 | arr |
|
||||
| datasizeof.cpp:29:16:29:35 | sizeof(<expr>) | DatasizeofExprOperator.getExprOperand() | datasizeof.cpp:29:29:29:34 | access to array |
|
||||
10
cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql
Normal file
10
cpp/ql/test/library-tests/types/datasizeof/datasizeof.ql
Normal file
@@ -0,0 +1,10 @@
|
||||
import cpp
|
||||
|
||||
from DatasizeofOperator sto, string elemDesc, Element e
|
||||
where
|
||||
elemDesc = "DatasizeofTypeOperator.getTypeOperand()" and
|
||||
e = sto.(DatasizeofTypeOperator).getTypeOperand()
|
||||
or
|
||||
elemDesc = "DatasizeofExprOperator.getExprOperand()" and
|
||||
e = sto.(DatasizeofExprOperator).getExprOperand()
|
||||
select sto, elemDesc, e
|
||||
Reference in New Issue
Block a user