mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
@@ -5,6 +5,8 @@ private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
* A C/C++ type.
|
||||
*
|
||||
* This QL class represents the root of the C/C++ type hierarchy.
|
||||
*/
|
||||
class Type extends Locatable, @type {
|
||||
Type() { isType(underlyingElement(this)) }
|
||||
@@ -289,6 +291,13 @@ class Type extends Locatable, @type {
|
||||
|
||||
/**
|
||||
* A C/C++ built-in primitive type (int, float, void, and so on). See 4.1.1.
|
||||
* In the following example, `unsigned int` and `double` denote primitive
|
||||
* built-in types:
|
||||
* ```
|
||||
* double a;
|
||||
* unsigned int ua[40];
|
||||
* typedef double LargeFloat;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInType extends Type, @builtintype {
|
||||
override string toString() { result = this.getName() }
|
||||
@@ -301,7 +310,14 @@ class BuiltInType extends Type, @builtintype {
|
||||
}
|
||||
|
||||
/**
|
||||
* An erroneous type.
|
||||
* An erroneous type. This type has no corresponding C/C++ syntax.
|
||||
*
|
||||
* `ErroneousType` is the type of `ErrorExpr`, which in turn refers to an illegal
|
||||
* language construct. In the example below, a temporary (`0`) cannot be bound
|
||||
* to an lvalue reference (`int &`):
|
||||
* ```
|
||||
* int &intref = 0;
|
||||
* ```
|
||||
*/
|
||||
class ErroneousType extends BuiltInType {
|
||||
ErroneousType() { builtintypes(underlyingElement(this), _, 1, _, _, _) }
|
||||
@@ -310,7 +326,18 @@ class ErroneousType extends BuiltInType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The unknown type.
|
||||
* The unknown type. This type has no corresponding C/C++ syntax.
|
||||
*
|
||||
* Unknown types usually occur inside _uninstantiated_ template functions.
|
||||
* In the example below, the expressions `x.a` and `x.b` have unknown type
|
||||
* in the _uninstantiated_ template.
|
||||
* ```
|
||||
* template<typename T>
|
||||
* bool check(T x) {
|
||||
* if (x.a == x.b)
|
||||
* abort();
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class UnknownType extends BuiltInType {
|
||||
UnknownType() { builtintypes(underlyingElement(this), _, 2, _, _, _) }
|
||||
@@ -326,6 +353,10 @@ private predicate isArithmeticType(@builtintype type, int kind) {
|
||||
|
||||
/**
|
||||
* The C/C++ arithmetic types. See 4.1.1.
|
||||
*
|
||||
* This includes primitive types on which arithmetic, bitwise or logical
|
||||
* operations may be performed. Examples of arithmetic types include
|
||||
* `char`, `int`, `float`, and `bool`.
|
||||
*/
|
||||
class ArithmeticType extends BuiltInType {
|
||||
ArithmeticType() { isArithmeticType(underlyingElement(this), _) }
|
||||
@@ -349,11 +380,20 @@ private predicate isIntegralType(@builtintype type, int kind) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ integral or enum type.
|
||||
* The definition of "integral type" in the C++ Standard excludes enum types,
|
||||
* but because an enum type holds a value of its underlying integral type,
|
||||
* A C/C++ integral or `enum` type.
|
||||
*
|
||||
* The definition of "integral type" in the C++ standard excludes `enum` types,
|
||||
* but because an `enum` type holds a value of its underlying integral type,
|
||||
* it is often useful to have a common category that includes both integral
|
||||
* and enum types.
|
||||
* and `enum` types.
|
||||
*
|
||||
* In the following example, `a`, `b` and `c` are all declared with an
|
||||
* integral or `enum` type:
|
||||
* ```
|
||||
* unsigned long a;
|
||||
* enum e1 { val1, val2 } b;
|
||||
* enum class e2: short { val3, val4 } c;
|
||||
* ```
|
||||
*/
|
||||
class IntegralOrEnumType extends Type {
|
||||
IntegralOrEnumType() {
|
||||
@@ -426,7 +466,17 @@ private predicate integralTypeMapping(int original, int canonical, int unsigned,
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ integral types. See 4.1.1.
|
||||
* The C/C++ integral types. See 4.1.1. These are types that are represented
|
||||
* as integers of varying sizes. Both `enum` types and floating-point types
|
||||
* are excluded.
|
||||
*
|
||||
* In the following examples, `a`, `b` and `c` are declared using integral
|
||||
* types:
|
||||
* ```
|
||||
* unsigned int a;
|
||||
* long long b;
|
||||
* char c;
|
||||
* ```
|
||||
*/
|
||||
class IntegralType extends ArithmeticType, IntegralOrEnumType {
|
||||
int kind;
|
||||
@@ -497,7 +547,12 @@ class IntegralType extends ArithmeticType, IntegralOrEnumType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ boolean type. See 4.2.
|
||||
* The C/C++ boolean type. See 4.2. This is the C `_Bool` type
|
||||
* or the C++ `bool` type. For example:
|
||||
* ```
|
||||
* extern bool a, b; // C++
|
||||
* _Bool c, d; // C
|
||||
* ```
|
||||
*/
|
||||
class BoolType extends IntegralType {
|
||||
BoolType() { builtintypes(underlyingElement(this), _, 4, _, _, _) }
|
||||
@@ -506,12 +561,23 @@ class BoolType extends IntegralType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ character types. See 4.3.
|
||||
* The C/C++ character types. See 4.3. This includes the `char`,
|
||||
* `signed char` and `unsigned char` types, all of which are
|
||||
* distinct from one another. For example:
|
||||
* ```
|
||||
* char a, b;
|
||||
* signed char c, d;
|
||||
* unsigned char e, f;
|
||||
* ```
|
||||
*/
|
||||
abstract class CharType extends IntegralType { }
|
||||
|
||||
/**
|
||||
* The C/C++ char type (which is different to signed char and unsigned char).
|
||||
* The C/C++ `char` type (which is distinct from `signed char` and
|
||||
* `unsigned char`). For example:
|
||||
* ```
|
||||
* char a, b;
|
||||
* ```
|
||||
*/
|
||||
class PlainCharType extends CharType {
|
||||
PlainCharType() { builtintypes(underlyingElement(this), _, 5, _, _, _) }
|
||||
@@ -520,7 +586,11 @@ class PlainCharType extends CharType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ unsigned char type (which is different to plain char, even when chars are unsigned by default).
|
||||
* The C/C++ `unsigned char` type (which is distinct from plain `char`
|
||||
* even when `char` is `unsigned` by default).
|
||||
* ```
|
||||
* unsigned char e, f;
|
||||
* ```
|
||||
*/
|
||||
class UnsignedCharType extends CharType {
|
||||
UnsignedCharType() { builtintypes(underlyingElement(this), _, 6, _, _, _) }
|
||||
@@ -529,7 +599,11 @@ class UnsignedCharType extends CharType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ signed char type (which is different to plain char, even when chars are signed by default).
|
||||
* The C/C++ `signed char` type (which is distinct from plain `char`
|
||||
* even when `char` is `signed` by default).
|
||||
* ```
|
||||
* signed char c, d;
|
||||
* ```
|
||||
*/
|
||||
class SignedCharType extends CharType {
|
||||
SignedCharType() { builtintypes(underlyingElement(this), _, 7, _, _, _) }
|
||||
@@ -538,7 +612,11 @@ class SignedCharType extends CharType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ short types. See 4.3.
|
||||
* The C/C++ short types. See 4.3. This includes `short`, `signed short`
|
||||
* and `unsigned short`.
|
||||
* ```
|
||||
* signed short ss;
|
||||
* ```
|
||||
*/
|
||||
class ShortType extends IntegralType {
|
||||
ShortType() {
|
||||
@@ -551,7 +629,11 @@ class ShortType extends IntegralType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ integer types. See 4.4.
|
||||
* The C/C++ integer types. See 4.4. This includes `int`, `signed int`
|
||||
* and `unsigned int`.
|
||||
* ```
|
||||
* unsigned int ui;
|
||||
* ```
|
||||
*/
|
||||
class IntType extends IntegralType {
|
||||
IntType() {
|
||||
@@ -564,7 +646,11 @@ class IntType extends IntegralType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ long types. See 4.4.
|
||||
* The C/C++ long types. See 4.4. This includes `long`, `signed long`
|
||||
* and `unsigned long`.
|
||||
* ```
|
||||
* long l;
|
||||
* ```
|
||||
*/
|
||||
class LongType extends IntegralType {
|
||||
LongType() {
|
||||
@@ -577,7 +663,11 @@ class LongType extends IntegralType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ long long types. See 4.4.
|
||||
* The C/C++ long long types. See 4.4. This includes `long long`, `signed long long`
|
||||
* and `unsigned long long`.
|
||||
* ```
|
||||
* signed long long sll;
|
||||
* ```
|
||||
*/
|
||||
class LongLongType extends IntegralType {
|
||||
LongLongType() {
|
||||
@@ -590,7 +680,12 @@ class LongLongType extends IntegralType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The GNU C __int128 types.
|
||||
* The GNU C __int128 primitive types. They are not part of standard C/C++.
|
||||
*
|
||||
* This includes `__int128`, `signed __int128` and `unsigned __int128`.
|
||||
* ```
|
||||
* unsigned __int128 ui128;
|
||||
* ```
|
||||
*/
|
||||
class Int128Type extends IntegralType {
|
||||
Int128Type() {
|
||||
@@ -598,10 +693,18 @@ class Int128Type extends IntegralType {
|
||||
builtintypes(underlyingElement(this), _, 36, _, _, _) or
|
||||
builtintypes(underlyingElement(this), _, 37, _, _, _)
|
||||
}
|
||||
|
||||
override string getCanonicalQLClass() { result = "Int128Type" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ floating point types. See 4.5.
|
||||
* The C/C++ floating point types. See 4.5. This includes `float`,
|
||||
* `double` and `long double` types.
|
||||
* ```
|
||||
* float f;
|
||||
* double d;
|
||||
* long double ld;
|
||||
* ```
|
||||
*/
|
||||
class FloatingPointType extends ArithmeticType {
|
||||
FloatingPointType() {
|
||||
@@ -619,7 +722,10 @@ class FloatingPointType extends ArithmeticType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ float type.
|
||||
* The C/C++ `float` type.
|
||||
* ```
|
||||
* float f;
|
||||
* ```
|
||||
*/
|
||||
class FloatType extends FloatingPointType {
|
||||
FloatType() { builtintypes(underlyingElement(this), _, 24, _, _, _) }
|
||||
@@ -628,7 +734,10 @@ class FloatType extends FloatingPointType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ double type.
|
||||
* The C/C++ `double` type.
|
||||
* ```
|
||||
* double d;
|
||||
* ```
|
||||
*/
|
||||
class DoubleType extends FloatingPointType {
|
||||
DoubleType() { builtintypes(underlyingElement(this), _, 25, _, _, _) }
|
||||
@@ -637,7 +746,10 @@ class DoubleType extends FloatingPointType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ long double type.
|
||||
* The C/C++ `long double` type.
|
||||
* ```
|
||||
* long double ld;
|
||||
* ```
|
||||
*/
|
||||
class LongDoubleType extends FloatingPointType {
|
||||
LongDoubleType() { builtintypes(underlyingElement(this), _, 26, _, _, _) }
|
||||
@@ -646,35 +758,58 @@ class LongDoubleType extends FloatingPointType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The GNU C __float128 type.
|
||||
* The GNU C `__float128` primitive type. This is not standard C/C++.
|
||||
* ```
|
||||
* __float128 f128;
|
||||
* ```
|
||||
*/
|
||||
class Float128Type extends FloatingPointType {
|
||||
Float128Type() { builtintypes(underlyingElement(this), _, 38, _, _, _) }
|
||||
|
||||
override string getCanonicalQLClass() { result = "Float128Type" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The GNU C _Decimal32 type.
|
||||
* The GNU C `_Decimal32` primitive type. This is not standard C/C++.
|
||||
* ```
|
||||
* _Decimal32 d32;
|
||||
* ```
|
||||
*/
|
||||
class Decimal32Type extends FloatingPointType {
|
||||
Decimal32Type() { builtintypes(underlyingElement(this), _, 40, _, _, _) }
|
||||
|
||||
override string getCanonicalQLClass() { result = "Decimal32Type" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The GNU C _Decimal64 type.
|
||||
* The GNU C `_Decimal64` primitive type. This is not standard C/C++.
|
||||
* ```
|
||||
* _Decimal64 d64;
|
||||
* ```
|
||||
*/
|
||||
class Decimal64Type extends FloatingPointType {
|
||||
Decimal64Type() { builtintypes(underlyingElement(this), _, 41, _, _, _) }
|
||||
|
||||
override string getCanonicalQLClass() { result = "Decimal64Type" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The GNU C _Decimal128 type.
|
||||
* The GNU C `_Decimal128` primitive type. This is not standard C/C++.
|
||||
* ```
|
||||
* _Decimal128 d128;
|
||||
* ```
|
||||
*/
|
||||
class Decimal128Type extends FloatingPointType {
|
||||
Decimal128Type() { builtintypes(underlyingElement(this), _, 42, _, _, _) }
|
||||
|
||||
override string getCanonicalQLClass() { result = "Decimal128Type" }
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ void type. See 4.7.
|
||||
* The C/C++ `void` type. See 4.7.
|
||||
* ```
|
||||
* void foo();
|
||||
* ```
|
||||
*/
|
||||
class VoidType extends BuiltInType {
|
||||
VoidType() { builtintypes(underlyingElement(this), _, 3, _, _, _) }
|
||||
@@ -688,6 +823,9 @@ class VoidType extends BuiltInType {
|
||||
* Note that on some platforms `wchar_t` doesn't exist as a built-in
|
||||
* type but a typedef is provided. Consider using the `Wchar_t` QL
|
||||
* class to include these types.
|
||||
* ```
|
||||
* wchar_t wc;
|
||||
* ```
|
||||
*/
|
||||
class WideCharType extends IntegralType {
|
||||
WideCharType() { builtintypes(underlyingElement(this), _, 33, _, _, _) }
|
||||
@@ -696,7 +834,10 @@ class WideCharType extends IntegralType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ `char16_t` type.
|
||||
* The C/C++ `char16_t` type. This is available starting with C11 and C++11.
|
||||
* ```
|
||||
* char16_t c16;
|
||||
* ```
|
||||
*/
|
||||
class Char16Type extends IntegralType {
|
||||
Char16Type() { builtintypes(underlyingElement(this), _, 43, _, _, _) }
|
||||
@@ -705,7 +846,10 @@ class Char16Type extends IntegralType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The C/C++ `char32_t` type.
|
||||
* The C/C++ `char32_t` type. This is available starting with C11 and C++11.
|
||||
* ```
|
||||
* char32_t c32;
|
||||
* ```
|
||||
*/
|
||||
class Char32Type extends IntegralType {
|
||||
Char32Type() { builtintypes(underlyingElement(this), _, 44, _, _, _) }
|
||||
@@ -714,13 +858,13 @@ class Char32Type extends IntegralType {
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the C++11 nullptr constant.
|
||||
*
|
||||
* Note that this is not `nullptr_t`, as `nullptr_t` is defined as:
|
||||
* The (primitive) type of the C++11 `nullptr` constant. It is a
|
||||
* distinct type, denoted by `decltype(nullptr)`, that is not itself a pointer
|
||||
* type or a pointer to member type. The `<cstddef>` header usually defines
|
||||
* the `std::nullptr_t` type as follows:
|
||||
* ```
|
||||
* typedef decltype(nullptr) nullptr_t;
|
||||
* typedef decltype(nullptr) nullptr_t;
|
||||
* ```
|
||||
* Instead, this is the unspeakable type given by `decltype(nullptr)`.
|
||||
*/
|
||||
class NullPointerType extends BuiltInType {
|
||||
NullPointerType() { builtintypes(underlyingElement(this), _, 34, _, _, _) }
|
||||
@@ -731,8 +875,13 @@ class NullPointerType extends BuiltInType {
|
||||
/**
|
||||
* A C/C++ derived type.
|
||||
*
|
||||
* These are pointer and reference types, array and vector types, and const and volatile types.
|
||||
* In all cases, the type is formed from a single base type.
|
||||
* These are pointer and reference types, array and GNU vector types, and `const` and `volatile` types.
|
||||
* In all cases, the type is formed from a single base type. For example:
|
||||
* ```
|
||||
* int *pi;
|
||||
* int &ri = *pi;
|
||||
* const float fa[40];
|
||||
* ```
|
||||
*/
|
||||
class DerivedType extends Type, @derivedtype {
|
||||
override string toString() { result = this.getName() }
|
||||
@@ -777,9 +926,15 @@ class DerivedType extends Type, @derivedtype {
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of the C++11 decltype operator.
|
||||
* An instance of the C++11 `decltype` operator. For example:
|
||||
* ```
|
||||
* int a;
|
||||
* decltype(a) b;
|
||||
* ```
|
||||
*/
|
||||
class Decltype extends Type, @decltype {
|
||||
override string getCanonicalQLClass() { result = "Decltype" }
|
||||
|
||||
/**
|
||||
* The expression whose type is being obtained by this decltype.
|
||||
*/
|
||||
@@ -790,17 +945,17 @@ class Decltype extends Type, @decltype {
|
||||
*/
|
||||
Type getBaseType() { decltypes(underlyingElement(this), _, unresolveElement(result), _) }
|
||||
|
||||
override string getCanonicalQLClass() { result = "Decltype" }
|
||||
|
||||
/**
|
||||
* Whether an extra pair of parentheses around the expression would change the semantics of this decltype.
|
||||
*
|
||||
* The following example shows the effect of an extra pair of parentheses:
|
||||
* struct A { double x; };
|
||||
* const A* a = new A();
|
||||
* decltype( a->x ); // type is double
|
||||
* decltype((a->x)); // type is const double&
|
||||
* Consult the C++11 standard for more details.
|
||||
* ```
|
||||
* struct A { double x; };
|
||||
* const A* a = new A();
|
||||
* decltype( a->x ); // type is double
|
||||
* decltype((a->x)); // type is const double&
|
||||
* ```
|
||||
* Please consult the C++11 standard for more details.
|
||||
*/
|
||||
predicate parenthesesWouldChangeMeaning() { decltypes(underlyingElement(this), _, _, true) }
|
||||
|
||||
@@ -843,6 +998,10 @@ class Decltype extends Type, @decltype {
|
||||
|
||||
/**
|
||||
* A C/C++ pointer type. See 4.9.1.
|
||||
* ```
|
||||
* void *ptr;
|
||||
* void **ptr2 = &ptr;
|
||||
* ```
|
||||
*/
|
||||
class PointerType extends DerivedType {
|
||||
PointerType() { derivedtypes(underlyingElement(this), _, 1, _) }
|
||||
@@ -865,8 +1024,8 @@ class PointerType extends DerivedType {
|
||||
/**
|
||||
* A C++ reference type. See 4.9.1.
|
||||
*
|
||||
* For C++11 code bases, this includes both lvalue references (&) and rvalue references (&&).
|
||||
* To distinguish between them, use the LValueReferenceType and RValueReferenceType classes.
|
||||
* For C++11 code bases, this includes both _lvalue_ references (`&`) and _rvalue_ references (`&&`).
|
||||
* To distinguish between them, use the LValueReferenceType and RValueReferenceType QL classes.
|
||||
*/
|
||||
class ReferenceType extends DerivedType {
|
||||
ReferenceType() {
|
||||
@@ -891,7 +1050,11 @@ class ReferenceType extends DerivedType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++11 lvalue reference type (e.g. int&).
|
||||
* A C++11 lvalue reference type (e.g. `int &`).
|
||||
* ```
|
||||
* int a;
|
||||
* int& b = a;
|
||||
* ```
|
||||
*/
|
||||
class LValueReferenceType extends ReferenceType {
|
||||
LValueReferenceType() { derivedtypes(underlyingElement(this), _, 2, _) }
|
||||
@@ -900,7 +1063,14 @@ class LValueReferenceType extends ReferenceType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++11 rvalue reference type (e.g. int&&).
|
||||
* A C++11 rvalue reference type (e.g., `int &&`). It is used to
|
||||
* implement "move" semantics for object construction and assignment.
|
||||
* ```
|
||||
* class C {
|
||||
* E e;
|
||||
* C(C&& from): e(std::move(from.e)) { }
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class RValueReferenceType extends ReferenceType {
|
||||
RValueReferenceType() { derivedtypes(underlyingElement(this), _, 8, _) }
|
||||
@@ -912,6 +1082,10 @@ class RValueReferenceType extends ReferenceType {
|
||||
|
||||
/**
|
||||
* A type with specifiers.
|
||||
* ```
|
||||
* const int a;
|
||||
* volatile char v;
|
||||
* ```
|
||||
*/
|
||||
class SpecifiedType extends DerivedType {
|
||||
SpecifiedType() { derivedtypes(underlyingElement(this), _, 3, _) }
|
||||
@@ -957,6 +1131,9 @@ class SpecifiedType extends DerivedType {
|
||||
|
||||
/**
|
||||
* A C/C++ array type. See 4.9.1.
|
||||
* ```
|
||||
* char table[32];
|
||||
* ```
|
||||
*/
|
||||
class ArrayType extends DerivedType {
|
||||
ArrayType() { derivedtypes(underlyingElement(this), _, 4, _) }
|
||||
@@ -1003,10 +1180,16 @@ class ArrayType extends DerivedType {
|
||||
* A GNU/Clang vector type.
|
||||
*
|
||||
* In both Clang and GNU compilers, vector types can be introduced using the
|
||||
* __attribute__((vector_size(byte_size))) syntax. The Clang compiler also
|
||||
* allows vector types to be introduced using the ext_vector_type,
|
||||
* neon_vector_type, and neon_polyvector_type attributes (all of which take
|
||||
* an element type rather than a byte size).
|
||||
* `__attribute__((vector_size(byte_size)))` syntax. The Clang compiler also
|
||||
* allows vector types to be introduced using the `ext_vector_type`,
|
||||
* `neon_vector_type`, and `neon_polyvector_type` attributes (all of which take
|
||||
* an element count rather than a byte size).
|
||||
*
|
||||
* In the example below, both `v4si` and `float4` are GNU vector types:
|
||||
* ```
|
||||
* typedef int v4si __attribute__ (( vector_size(4*sizeof(int)) ));
|
||||
* typedef float float4 __attribute__((ext_vector_type(4)));
|
||||
* ```
|
||||
*/
|
||||
class GNUVectorType extends DerivedType {
|
||||
GNUVectorType() { derivedtypes(underlyingElement(this), _, 5, _) }
|
||||
@@ -1045,7 +1228,10 @@ class GNUVectorType extends DerivedType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ pointer to function. See 7.7.
|
||||
* A C/C++ pointer to a function. See 7.7.
|
||||
* ```
|
||||
* int(* pointer)(const void *element1, const void *element2);
|
||||
* ```
|
||||
*/
|
||||
class FunctionPointerType extends FunctionPointerIshType {
|
||||
FunctionPointerType() { derivedtypes(underlyingElement(this), _, 6, _) }
|
||||
@@ -1060,7 +1246,10 @@ class FunctionPointerType extends FunctionPointerIshType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ reference to function.
|
||||
* A C++ reference to a function.
|
||||
* ```
|
||||
* int(& reference)(const void *element1, const void *element2);
|
||||
* ```
|
||||
*/
|
||||
class FunctionReferenceType extends FunctionPointerIshType {
|
||||
FunctionReferenceType() { derivedtypes(underlyingElement(this), _, 7, _) }
|
||||
@@ -1075,10 +1264,14 @@ class FunctionReferenceType extends FunctionPointerIshType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A block type, for example int(^)(char, float).
|
||||
* A block type, for example, `int(^)(char, float)`.
|
||||
*
|
||||
* Block types (along with blocks themselves) are a language extension
|
||||
* supported by Clang, and by Apple's branch of GCC.
|
||||
* ```
|
||||
* int(^ block)(const char *element1, const char *element2)
|
||||
* = ^int (const char *element1, const char *element2) { return element1 - element 2; }
|
||||
* ```
|
||||
*/
|
||||
class BlockType extends FunctionPointerIshType {
|
||||
BlockType() { derivedtypes(underlyingElement(this), _, 10, _) }
|
||||
@@ -1091,7 +1284,9 @@ class BlockType extends FunctionPointerIshType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ pointer to function, or a block.
|
||||
* A C/C++ pointer to a function, a C++ function reference, or a clang/Apple block.
|
||||
*
|
||||
* See `FunctionPointerType`, `FunctionReferenceType` and `BlockType` for more information.
|
||||
*/
|
||||
class FunctionPointerIshType extends DerivedType {
|
||||
FunctionPointerIshType() {
|
||||
@@ -1136,7 +1331,13 @@ class FunctionPointerIshType extends DerivedType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ pointer to member. See 15.5.
|
||||
* A C++ pointer to data member. See 15.5.
|
||||
* ```
|
||||
* class C { int m; };
|
||||
* int C::* p = &C::m; // pointer to data member m of class C
|
||||
* class C *;
|
||||
* int val = c.*p; // access data member
|
||||
* ```
|
||||
*/
|
||||
class PointerToMemberType extends Type, @ptrtomember {
|
||||
/** a printable representation of this named element */
|
||||
@@ -1173,7 +1374,14 @@ class PointerToMemberType extends Type, @ptrtomember {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ routine type. This is what results from stripping away the pointer from a function pointer type.
|
||||
* A C/C++ routine type. Conceptually, this is what results from stripping
|
||||
* away the pointer from a function pointer type. It can also occur in C++
|
||||
* code, for example the base type of `myRoutineType` in the following code:
|
||||
* ```
|
||||
* using myRoutineType = int(int);
|
||||
*
|
||||
* myRoutineType *fp = 0;
|
||||
* ```
|
||||
*/
|
||||
class RoutineType extends Type, @routinetype {
|
||||
/** a printable representation of this named element */
|
||||
@@ -1233,7 +1441,13 @@ class RoutineType extends Type, @routinetype {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ typename template parameter.
|
||||
* A C++ `typename` (or `class`) template parameter.
|
||||
*
|
||||
* In the example below, `T` is a template parameter:
|
||||
* ```
|
||||
* template <class T>
|
||||
* class C { };
|
||||
* ```
|
||||
*/
|
||||
class TemplateParameter extends UserType {
|
||||
TemplateParameter() {
|
||||
@@ -1245,7 +1459,16 @@ class TemplateParameter extends UserType {
|
||||
override predicate involvesTemplateParameter() { any() }
|
||||
}
|
||||
|
||||
/** A C++ template template parameter, e.g. template <template <typename,typename> class T>. */
|
||||
/**
|
||||
* A C++ template template parameter.
|
||||
*
|
||||
* In the example below, `T` is a template template parameter (although its name
|
||||
* may be omitted):
|
||||
* ```
|
||||
* template <template <typename T> class Container, class Elem>
|
||||
* void foo(const Container<Elem> &value) { }
|
||||
* ```
|
||||
*/
|
||||
class TemplateTemplateParameter extends TemplateParameter {
|
||||
TemplateTemplateParameter() { usertypes(underlyingElement(this), _, 8) }
|
||||
|
||||
@@ -1253,7 +1476,10 @@ class TemplateTemplateParameter extends TemplateParameter {
|
||||
}
|
||||
|
||||
/**
|
||||
* A type representing the use of the C++11 auto keyword.
|
||||
* A type representing the use of the C++11 `auto` keyword.
|
||||
* ```
|
||||
* auto val = some_typed_expr();
|
||||
* ```
|
||||
*/
|
||||
class AutoType extends TemplateParameter {
|
||||
AutoType() { usertypes(underlyingElement(this), "auto", 7) }
|
||||
|
||||
@@ -2,12 +2,11 @@ import semmle.code.cpp.Type
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
* A C/C++ typedef type. See 4.9.1.
|
||||
*
|
||||
* Represents either of the following typedef styles:
|
||||
*
|
||||
* * CTypedefType: typedef <type> <name>;
|
||||
* * UsingAliasTypedefType: using <name> = <type>;
|
||||
* A C/C++ typedef type. See 4.9.1. For example the types declared on each line of the following code:
|
||||
* ```
|
||||
* typedef int my_int;
|
||||
* using my_int2 = int;
|
||||
* ```
|
||||
*/
|
||||
class TypedefType extends UserType {
|
||||
TypedefType() {
|
||||
@@ -48,7 +47,10 @@ class TypedefType extends UserType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A traditional C/C++ typedef type. See 4.9.1.
|
||||
* A traditional C/C++ typedef type. See 4.9.1. For example the type declared in the following code:
|
||||
* ```
|
||||
* typedef int my_int;
|
||||
* ```
|
||||
*/
|
||||
class CTypedefType extends TypedefType {
|
||||
CTypedefType() { usertypes(underlyingElement(this), _, 5) }
|
||||
@@ -61,7 +63,10 @@ class CTypedefType extends TypedefType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A using alias C++ typedef type.
|
||||
* A using alias C++ typedef type. For example the type declared in the following code:
|
||||
* ```
|
||||
* using my_int2 = int;
|
||||
* ```
|
||||
*/
|
||||
class UsingAliasTypedefType extends TypedefType {
|
||||
UsingAliasTypedefType() { usertypes(underlyingElement(this), _, 14) }
|
||||
@@ -74,7 +79,11 @@ class UsingAliasTypedefType extends TypedefType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ typedef type that is directly enclosed by a function.
|
||||
* A C++ `typedef` type that is directly enclosed by a function. For example the type declared inside the function `foo` in
|
||||
* the following code:
|
||||
* ```
|
||||
* int foo(void) { typedef int local; }
|
||||
* ```
|
||||
*/
|
||||
class LocalTypedefType extends TypedefType {
|
||||
LocalTypedefType() { isLocal() }
|
||||
@@ -83,7 +92,11 @@ class LocalTypedefType extends TypedefType {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ typedef type that is directly enclosed by a class, struct or union.
|
||||
* A C++ `typedef` type that is directly enclosed by a `class`, `struct` or `union`. For example the type declared inside
|
||||
* the class `C` in the following code:
|
||||
* ```
|
||||
* class C { typedef int nested; };
|
||||
* ```
|
||||
*/
|
||||
class NestedTypedefType extends TypedefType {
|
||||
NestedTypedefType() { this.isMember() }
|
||||
|
||||
@@ -5,8 +5,14 @@ import semmle.code.cpp.Function
|
||||
private import semmle.code.cpp.internal.ResolveClass
|
||||
|
||||
/**
|
||||
* A C/C++ user-defined type. Examples include `Class`, `Struct`, `Union`,
|
||||
* `Enum`, and `TypedefType`.
|
||||
* A C/C++ user-defined type. Examples include `class`, `struct`, `union`,
|
||||
* `enum` and `typedef` types.
|
||||
* ```
|
||||
* enum e1 { val1, val2 } b;
|
||||
* enum class e2: short { val3, val4 } c;
|
||||
* typedef int my_int;
|
||||
* class C { int a, b; };
|
||||
* ```
|
||||
*/
|
||||
class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @usertype {
|
||||
/**
|
||||
@@ -88,6 +94,10 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
|
||||
|
||||
/**
|
||||
* A particular definition or forward declaration of a C/C++ user-defined type.
|
||||
* ```
|
||||
* class C;
|
||||
* typedef int ti;
|
||||
* ```
|
||||
*/
|
||||
class TypeDeclarationEntry extends DeclarationEntry, @type_decl {
|
||||
override UserType getDeclaration() { result = getType() }
|
||||
|
||||
@@ -44,7 +44,7 @@ predicate memberMayBeVarSize(Class c, MemberVariable v) {
|
||||
aoe.getAddressable() = v
|
||||
)
|
||||
or
|
||||
exists(BuiltInOperationOffsetOf oo |
|
||||
exists(BuiltInOperationBuiltInOffsetOf oo |
|
||||
// `offsetof(c, v)` using a builtin
|
||||
oo.getAChild().(VariableAccess).getTarget() = v
|
||||
)
|
||||
|
||||
@@ -132,7 +132,7 @@ private predicate excludeNodeAndNodesBelow(Expr e) {
|
||||
* control flow in them.
|
||||
*/
|
||||
private predicate excludeNodesStrictlyBelow(Node n) {
|
||||
n instanceof BuiltInOperationOffsetOf
|
||||
n instanceof BuiltInOperationBuiltInOffsetOf
|
||||
or
|
||||
n instanceof BuiltInIntAddr
|
||||
or
|
||||
|
||||
@@ -1,12 +1,17 @@
|
||||
import semmle.code.cpp.exprs.Expr
|
||||
|
||||
/**
|
||||
* A C/C++ arithmetic operation.
|
||||
* A C/C++ unary arithmetic operation.
|
||||
*
|
||||
* This is an abstract base QL class.
|
||||
*/
|
||||
abstract class UnaryArithmeticOperation extends UnaryOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ unary minus expression.
|
||||
* ```
|
||||
* b = - a;
|
||||
* ```
|
||||
*/
|
||||
class UnaryMinusExpr extends UnaryArithmeticOperation, @arithnegexpr {
|
||||
override string getOperator() { result = "-" }
|
||||
@@ -18,6 +23,9 @@ class UnaryMinusExpr extends UnaryArithmeticOperation, @arithnegexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ unary plus expression.
|
||||
* ```
|
||||
* b = + a;
|
||||
* ```
|
||||
*/
|
||||
class UnaryPlusExpr extends UnaryArithmeticOperation, @unaryplusexpr {
|
||||
override string getOperator() { result = "+" }
|
||||
@@ -28,7 +36,13 @@ class UnaryPlusExpr extends UnaryArithmeticOperation, @unaryplusexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ GNU conjugation expression.
|
||||
* A C/C++ GNU conjugation expression. It operates on `_Complex` or
|
||||
* `__complex__ `numbers, and is similar to the C99 `conj`, `conjf` and `conjl`
|
||||
* functions.
|
||||
* ```
|
||||
* _Complex double a = ( 1.0, 2.0 );
|
||||
* _Complex double b = ~ a; // ( 1.0, - 2.0 )
|
||||
* ```
|
||||
*/
|
||||
class ConjugationExpr extends UnaryArithmeticOperation, @conjugation {
|
||||
override string getOperator() { result = "~" }
|
||||
@@ -39,7 +53,9 @@ class ConjugationExpr extends UnaryArithmeticOperation, @conjugation {
|
||||
/**
|
||||
* A C/C++ `++` or `--` expression (either prefix or postfix).
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined `operator++`
|
||||
* This is the abstract base QL class for increment and decrement operations.
|
||||
*
|
||||
* Note that this does not include calls to user-defined `operator++`
|
||||
* or `operator--`.
|
||||
*/
|
||||
abstract class CrementOperation extends UnaryArithmeticOperation {
|
||||
@@ -58,35 +74,38 @@ abstract class CrementOperation extends UnaryArithmeticOperation {
|
||||
/**
|
||||
* A C/C++ `++` expression (either prefix or postfix).
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined `operator++`.
|
||||
* Note that this does not include calls to user-defined `operator++`.
|
||||
*/
|
||||
abstract class IncrementOperation extends CrementOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ `--` expression (either prefix or postfix).
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined `operator--`.
|
||||
* Note that this does not include calls to user-defined `operator--`.
|
||||
*/
|
||||
abstract class DecrementOperation extends CrementOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ `++` or `--` prefix expression.
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined operators.
|
||||
* Note that this does not include calls to user-defined operators.
|
||||
*/
|
||||
abstract class PrefixCrementOperation extends CrementOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ `++` or `--` postfix expression.
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined operators.
|
||||
* Note that this does not include calls to user-defined operators.
|
||||
*/
|
||||
abstract class PostfixCrementOperation extends CrementOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ prefix increment expression, as in `++x`.
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined `operator++`.
|
||||
* Note that this does not include calls to user-defined `operator++`.
|
||||
* ```
|
||||
* b = ++a;
|
||||
* ```
|
||||
*/
|
||||
class PrefixIncrExpr extends IncrementOperation, PrefixCrementOperation, @preincrexpr {
|
||||
override string getOperator() { result = "++" }
|
||||
@@ -99,7 +118,10 @@ class PrefixIncrExpr extends IncrementOperation, PrefixCrementOperation, @preinc
|
||||
/**
|
||||
* A C/C++ prefix decrement expression, as in `--x`.
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined `operator--`.
|
||||
* Note that this does not include calls to user-defined `operator--`.
|
||||
* ```
|
||||
* b = --a;
|
||||
* ```
|
||||
*/
|
||||
class PrefixDecrExpr extends DecrementOperation, PrefixCrementOperation, @predecrexpr {
|
||||
override string getOperator() { result = "--" }
|
||||
@@ -112,7 +134,10 @@ class PrefixDecrExpr extends DecrementOperation, PrefixCrementOperation, @predec
|
||||
/**
|
||||
* A C/C++ postfix increment expression, as in `x++`.
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined `operator++`.
|
||||
* Note that this does not include calls to user-defined `operator++`.
|
||||
* ```
|
||||
* b = a++;
|
||||
* ```
|
||||
*/
|
||||
class PostfixIncrExpr extends IncrementOperation, PostfixCrementOperation, @postincrexpr {
|
||||
override string getOperator() { result = "++" }
|
||||
@@ -127,7 +152,10 @@ class PostfixIncrExpr extends IncrementOperation, PostfixCrementOperation, @post
|
||||
/**
|
||||
* A C/C++ postfix decrement expression, as in `x--`.
|
||||
*
|
||||
* Note that this doesn't include calls to user-defined `operator--`.
|
||||
* Note that this does not include calls to user-defined `operator--`.
|
||||
* ```
|
||||
* b = a--;
|
||||
* ```
|
||||
*/
|
||||
class PostfixDecrExpr extends DecrementOperation, PostfixCrementOperation, @postdecrexpr {
|
||||
override string getOperator() { result = "--" }
|
||||
@@ -140,7 +168,12 @@ class PostfixDecrExpr extends DecrementOperation, PostfixCrementOperation, @post
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ GNU real part expression.
|
||||
* A C/C++ GNU real part expression. It operates on `_Complex` or
|
||||
* `__complex__` numbers.
|
||||
* ```
|
||||
* _Complex double f = { 2.0, 3.0 };
|
||||
* double d = __real(f); // 2.0
|
||||
* ```
|
||||
*/
|
||||
class RealPartExpr extends UnaryArithmeticOperation, @realpartexpr {
|
||||
override string getOperator() { result = "__real" }
|
||||
@@ -149,7 +182,12 @@ class RealPartExpr extends UnaryArithmeticOperation, @realpartexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ GNU imaginary part expression.
|
||||
* A C/C++ GNU imaginary part expression. It operates on `_Complex` or
|
||||
* `__complex__` numbers.
|
||||
* ```
|
||||
* _Complex double f = { 2.0, 3.0 };
|
||||
* double d = __imag(f); // 3.0
|
||||
* ```
|
||||
*/
|
||||
class ImaginaryPartExpr extends UnaryArithmeticOperation, @imagpartexpr {
|
||||
override string getOperator() { result = "__imag" }
|
||||
@@ -159,11 +197,16 @@ class ImaginaryPartExpr extends UnaryArithmeticOperation, @imagpartexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ binary arithmetic operation.
|
||||
*
|
||||
* This is an abstract base QL class for all binary arithmetic operations.
|
||||
*/
|
||||
abstract class BinaryArithmeticOperation extends BinaryOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ add expression.
|
||||
* ```
|
||||
* c = a + b;
|
||||
* ```
|
||||
*/
|
||||
class AddExpr extends BinaryArithmeticOperation, @addexpr {
|
||||
override string getOperator() { result = "+" }
|
||||
@@ -175,6 +218,9 @@ class AddExpr extends BinaryArithmeticOperation, @addexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ subtract expression.
|
||||
* ```
|
||||
* c = a - b;
|
||||
* ```
|
||||
*/
|
||||
class SubExpr extends BinaryArithmeticOperation, @subexpr {
|
||||
override string getOperator() { result = "-" }
|
||||
@@ -186,6 +232,9 @@ class SubExpr extends BinaryArithmeticOperation, @subexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ multiply expression.
|
||||
* ```
|
||||
* c = a * b;
|
||||
* ```
|
||||
*/
|
||||
class MulExpr extends BinaryArithmeticOperation, @mulexpr {
|
||||
override string getOperator() { result = "*" }
|
||||
@@ -197,6 +246,9 @@ class MulExpr extends BinaryArithmeticOperation, @mulexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ divide expression.
|
||||
* ```
|
||||
* c = a / b;
|
||||
* ```
|
||||
*/
|
||||
class DivExpr extends BinaryArithmeticOperation, @divexpr {
|
||||
override string getOperator() { result = "/" }
|
||||
@@ -208,6 +260,9 @@ class DivExpr extends BinaryArithmeticOperation, @divexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ remainder expression.
|
||||
* ```
|
||||
* c = a % b;
|
||||
* ```
|
||||
*/
|
||||
class RemExpr extends BinaryArithmeticOperation, @remexpr {
|
||||
override string getOperator() { result = "%" }
|
||||
@@ -218,7 +273,13 @@ class RemExpr extends BinaryArithmeticOperation, @remexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ multiply expression with an imaginary number.
|
||||
* A C/C++ multiply expression with an imaginary number. This is specific to
|
||||
* C99 and later.
|
||||
* ```
|
||||
* double z;
|
||||
* _Imaginary double x, y;
|
||||
* z = x * y;
|
||||
* ```
|
||||
*/
|
||||
class ImaginaryMulExpr extends BinaryArithmeticOperation, @jmulexpr {
|
||||
override string getOperator() { result = "*" }
|
||||
@@ -229,7 +290,13 @@ class ImaginaryMulExpr extends BinaryArithmeticOperation, @jmulexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ divide expression with an imaginary number.
|
||||
* A C/C++ divide expression with an imaginary number. This is specific to
|
||||
* C99 and later.
|
||||
* ```
|
||||
* double z;
|
||||
* _Imaginary double y;
|
||||
* z = z / y;
|
||||
* ```
|
||||
*/
|
||||
class ImaginaryDivExpr extends BinaryArithmeticOperation, @jdivexpr {
|
||||
override string getOperator() { result = "/" }
|
||||
@@ -240,7 +307,14 @@ class ImaginaryDivExpr extends BinaryArithmeticOperation, @jdivexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ add expression with a real term and an imaginary term.
|
||||
* A C/C++ add expression with a real term and an imaginary term. This is
|
||||
* specific to C99 and later.
|
||||
* ```
|
||||
* double z;
|
||||
* _Imaginary double x;
|
||||
* _Complex double w;
|
||||
* w = z + x;
|
||||
* ```
|
||||
*/
|
||||
class RealImaginaryAddExpr extends BinaryArithmeticOperation, @fjaddexpr {
|
||||
override string getOperator() { result = "+" }
|
||||
@@ -251,7 +325,14 @@ class RealImaginaryAddExpr extends BinaryArithmeticOperation, @fjaddexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ add expression with an imaginary term and a real term.
|
||||
* A C/C++ add expression with an imaginary term and a real term. This is
|
||||
* specific to C99 and later.
|
||||
* ```
|
||||
* double z;
|
||||
* _Imaginary double x;
|
||||
* _Complex double w;
|
||||
* w = x + z;
|
||||
* ```
|
||||
*/
|
||||
class ImaginaryRealAddExpr extends BinaryArithmeticOperation, @jfaddexpr {
|
||||
override string getOperator() { result = "+" }
|
||||
@@ -262,7 +343,14 @@ class ImaginaryRealAddExpr extends BinaryArithmeticOperation, @jfaddexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ subtract expression with a real term and an imaginary term.
|
||||
* A C/C++ subtract expression with a real term and an imaginary term. This is
|
||||
* specific to C99 and later.
|
||||
* ```
|
||||
* double z;
|
||||
* _Imaginary double x;
|
||||
* _Complex double w;
|
||||
* w = z - x;
|
||||
* ```
|
||||
*/
|
||||
class RealImaginarySubExpr extends BinaryArithmeticOperation, @fjsubexpr {
|
||||
override string getOperator() { result = "-" }
|
||||
@@ -273,7 +361,14 @@ class RealImaginarySubExpr extends BinaryArithmeticOperation, @fjsubexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ subtract expression with an imaginary term and a real term.
|
||||
* A C/C++ subtract expression with an imaginary term and a real term. This is
|
||||
* specific to C99 and later.
|
||||
* ```
|
||||
* double z;
|
||||
* _Imaginary double x;
|
||||
* _Complex double w;
|
||||
* w = x - z;
|
||||
* ```
|
||||
*/
|
||||
class ImaginaryRealSubExpr extends BinaryArithmeticOperation, @jfsubexpr {
|
||||
override string getOperator() { result = "-" }
|
||||
@@ -285,6 +380,9 @@ class ImaginaryRealSubExpr extends BinaryArithmeticOperation, @jfsubexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ GNU min expression.
|
||||
* ```
|
||||
* c = a <? b;
|
||||
* ```
|
||||
*/
|
||||
class MinExpr extends BinaryArithmeticOperation, @minexpr {
|
||||
override string getOperator() { result = "<?" }
|
||||
@@ -294,6 +392,9 @@ class MinExpr extends BinaryArithmeticOperation, @minexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ GNU max expression.
|
||||
* ```
|
||||
* c = a >? b;
|
||||
* ```
|
||||
*/
|
||||
class MaxExpr extends BinaryArithmeticOperation, @maxexpr {
|
||||
override string getOperator() { result = ">?" }
|
||||
@@ -308,6 +409,10 @@ abstract class PointerArithmeticOperation extends BinaryArithmeticOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ pointer add expression.
|
||||
* ```
|
||||
* foo *ptr = &f[0];
|
||||
* ptr = ptr + 2;
|
||||
* ```
|
||||
*/
|
||||
class PointerAddExpr extends PointerArithmeticOperation, @paddexpr {
|
||||
override string getOperator() { result = "+" }
|
||||
@@ -319,6 +424,10 @@ class PointerAddExpr extends PointerArithmeticOperation, @paddexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ pointer subtract expression.
|
||||
* ```
|
||||
* foo *ptr = &f[3];
|
||||
* ptr = ptr - 2;
|
||||
* ```
|
||||
*/
|
||||
class PointerSubExpr extends PointerArithmeticOperation, @psubexpr {
|
||||
override string getOperator() { result = "-" }
|
||||
@@ -330,6 +439,10 @@ class PointerSubExpr extends PointerArithmeticOperation, @psubexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ pointer difference expression.
|
||||
* ```
|
||||
* foo *start = &f[0], *end = &f[4];
|
||||
* int size = end - size;
|
||||
* ```
|
||||
*/
|
||||
class PointerDiffExpr extends PointerArithmeticOperation, @pdiffexpr {
|
||||
override string getOperator() { result = "-" }
|
||||
|
||||
@@ -4,11 +4,13 @@ import semmle.code.cpp.exprs.BitwiseOperation
|
||||
|
||||
/**
|
||||
* A non-overloaded binary assignment operation, including `=`, `+=`, `&=`,
|
||||
* etc. A C++ overloaded operation looks syntactically identical but is instead
|
||||
* etc. A C++ overloaded assignment operation looks syntactically identical but is instead
|
||||
* a `FunctionCall`.
|
||||
*
|
||||
* This is an abstract root QL class for all (non-overloaded) assignments.
|
||||
*/
|
||||
abstract class Assignment extends Operation {
|
||||
/** Gets the lvalue of this assignment. */
|
||||
/** Gets the _lvalue_ of this assignment. */
|
||||
Expr getLValue() { this.hasChild(result, 0) }
|
||||
|
||||
/** Gets the rvalue of this assignment. */
|
||||
@@ -30,6 +32,9 @@ abstract class Assignment extends Operation {
|
||||
|
||||
/**
|
||||
* A non-overloaded assignment operation with the operator `=`.
|
||||
* ```
|
||||
* a = b;
|
||||
* ```
|
||||
*/
|
||||
class AssignExpr extends Assignment, @assignexpr {
|
||||
override string getOperator() { result = "=" }
|
||||
@@ -48,13 +53,16 @@ abstract class AssignOperation extends Assignment {
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-overloaded arithmetic assignment operation on a non-pointer lvalue:
|
||||
* A non-overloaded arithmetic assignment operation on a non-pointer _lvalue_:
|
||||
* `+=`, `-=`, `*=`, `/=` and `%=`.
|
||||
*/
|
||||
abstract class AssignArithmeticOperation extends AssignOperation { }
|
||||
|
||||
/**
|
||||
* A non-overloaded `+=` assignment expression on a non-pointer lvalue.
|
||||
* A non-overloaded `+=` assignment expression on a non-pointer _lvalue_.
|
||||
* ```
|
||||
* a += b;
|
||||
* ```
|
||||
*/
|
||||
class AssignAddExpr extends AssignArithmeticOperation, @assignaddexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignAddExpr" }
|
||||
@@ -63,7 +71,10 @@ class AssignAddExpr extends AssignArithmeticOperation, @assignaddexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-overloaded `-=` assignment expression on a non-pointer lvalue.
|
||||
* A non-overloaded `-=` assignment expression on a non-pointer _lvalue_.
|
||||
* ```
|
||||
* a -= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignSubExpr extends AssignArithmeticOperation, @assignsubexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignSubExpr" }
|
||||
@@ -73,6 +84,9 @@ class AssignSubExpr extends AssignArithmeticOperation, @assignsubexpr {
|
||||
|
||||
/**
|
||||
* A non-overloaded `*=` assignment expression.
|
||||
* ```
|
||||
* a *= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignMulExpr extends AssignArithmeticOperation, @assignmulexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignMulExpr" }
|
||||
@@ -82,6 +96,9 @@ class AssignMulExpr extends AssignArithmeticOperation, @assignmulexpr {
|
||||
|
||||
/**
|
||||
* A non-overloaded `/=` assignment expression.
|
||||
* ```
|
||||
* a /= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignDivExpr extends AssignArithmeticOperation, @assigndivexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignDivExpr" }
|
||||
@@ -91,6 +108,9 @@ class AssignDivExpr extends AssignArithmeticOperation, @assigndivexpr {
|
||||
|
||||
/**
|
||||
* A non-overloaded `%=` assignment expression.
|
||||
* ```
|
||||
* a %= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignRemExpr extends AssignArithmeticOperation, @assignremexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignRemExpr" }
|
||||
@@ -105,7 +125,10 @@ class AssignRemExpr extends AssignArithmeticOperation, @assignremexpr {
|
||||
abstract class AssignBitwiseOperation extends AssignOperation { }
|
||||
|
||||
/**
|
||||
* A non-overloaded `&=` assignment expression.
|
||||
* A non-overloaded AND (`&=`) assignment expression.
|
||||
* ```
|
||||
* a &= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignAndExpr extends AssignBitwiseOperation, @assignandexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignAndExpr" }
|
||||
@@ -114,7 +137,10 @@ class AssignAndExpr extends AssignBitwiseOperation, @assignandexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-overloaded `|=` assignment expression.
|
||||
* A non-overloaded OR (`|=`) assignment expression.
|
||||
* ```
|
||||
* a |= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignOrExpr extends AssignBitwiseOperation, @assignorexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignOrExpr" }
|
||||
@@ -123,7 +149,10 @@ class AssignOrExpr extends AssignBitwiseOperation, @assignorexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A non-overloaded `^=` assignment expression.
|
||||
* A non-overloaded XOR (`^=`) assignment expression.
|
||||
* ```
|
||||
* a ^= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignXorExpr extends AssignBitwiseOperation, @assignxorexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignXorExpr" }
|
||||
@@ -133,6 +162,9 @@ class AssignXorExpr extends AssignBitwiseOperation, @assignxorexpr {
|
||||
|
||||
/**
|
||||
* A non-overloaded `<<=` assignment expression.
|
||||
* ```
|
||||
* a <<= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignLShiftExpr extends AssignBitwiseOperation, @assignlshiftexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignLShiftExpr" }
|
||||
@@ -142,6 +174,9 @@ class AssignLShiftExpr extends AssignBitwiseOperation, @assignlshiftexpr {
|
||||
|
||||
/**
|
||||
* A non-overloaded `>>=` assignment expression.
|
||||
* ```
|
||||
* a >>= b;
|
||||
* ```
|
||||
*/
|
||||
class AssignRShiftExpr extends AssignBitwiseOperation, @assignrshiftexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignRShiftExpr" }
|
||||
@@ -151,6 +186,9 @@ class AssignRShiftExpr extends AssignBitwiseOperation, @assignrshiftexpr {
|
||||
|
||||
/**
|
||||
* A non-overloaded `+=` pointer assignment expression.
|
||||
* ```
|
||||
* ptr += index;
|
||||
* ```
|
||||
*/
|
||||
class AssignPointerAddExpr extends AssignOperation, @assignpaddexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignPointerAddExpr" }
|
||||
@@ -160,6 +198,9 @@ class AssignPointerAddExpr extends AssignOperation, @assignpaddexpr {
|
||||
|
||||
/**
|
||||
* A non-overloaded `-=` pointer assignment expression.
|
||||
* ```
|
||||
* ptr -= index;
|
||||
* ```
|
||||
*/
|
||||
class AssignPointerSubExpr extends AssignOperation, @assignpsubexpr {
|
||||
override string getCanonicalQLClass() { result = "AssignPointerSubExpr" }
|
||||
@@ -168,11 +209,16 @@ class AssignPointerSubExpr extends AssignOperation, @assignpsubexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ variable declaration in an expression where a condition is expected.
|
||||
* For example, on the `ConditionDeclExpr` in `if (bool c = x < y)`,
|
||||
* `getVariableAccess()` is an access to `c` (with possible casts),
|
||||
* `getVariable()` is the variable `c` (which has an initializer `x < y`), and
|
||||
* `getInitializingExpr()` is `x < y`.
|
||||
* A C++ variable declaration inside the conditional expression of a `while`, `if` or
|
||||
* `for` compound statement. Declaring a variable this way narrows its lifetime and
|
||||
* scope to be strictly the compound statement itself. For example:
|
||||
* ```
|
||||
* extern int x, y;
|
||||
* if (bool c = x < y) { do_something_with(c); }
|
||||
* // c is no longer in scope
|
||||
* while (int d = x - y) { do_something_else_with(d); }
|
||||
* // d is no longer is scope
|
||||
* ```
|
||||
*/
|
||||
class ConditionDeclExpr extends Expr, @condition_decl {
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,9 @@ abstract class UnaryBitwiseOperation extends UnaryOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ complement expression.
|
||||
* ```
|
||||
* unsigned c = ~a;
|
||||
* ```
|
||||
*/
|
||||
class ComplementExpr extends UnaryBitwiseOperation, @complementexpr {
|
||||
override string getOperator() { result = "~" }
|
||||
@@ -23,6 +26,9 @@ abstract class BinaryBitwiseOperation extends BinaryOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ left shift expression.
|
||||
* ```
|
||||
* unsigned c = a << b;
|
||||
* ```
|
||||
*/
|
||||
class LShiftExpr extends BinaryBitwiseOperation, @lshiftexpr {
|
||||
override string getOperator() { result = "<<" }
|
||||
@@ -34,6 +40,9 @@ class LShiftExpr extends BinaryBitwiseOperation, @lshiftexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ right shift expression.
|
||||
* ```
|
||||
* unsigned c = a >> b;
|
||||
* ```
|
||||
*/
|
||||
class RShiftExpr extends BinaryBitwiseOperation, @rshiftexpr {
|
||||
override string getOperator() { result = ">>" }
|
||||
@@ -44,7 +53,10 @@ class RShiftExpr extends BinaryBitwiseOperation, @rshiftexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ bitwise and expression.
|
||||
* A C/C++ bitwise AND expression.
|
||||
* ```
|
||||
* unsigned c = a & b;
|
||||
* ```
|
||||
*/
|
||||
class BitwiseAndExpr extends BinaryBitwiseOperation, @andexpr {
|
||||
override string getOperator() { result = "&" }
|
||||
@@ -55,7 +67,10 @@ class BitwiseAndExpr extends BinaryBitwiseOperation, @andexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ bitwise or expression.
|
||||
* A C/C++ bitwise OR expression.
|
||||
* ```
|
||||
* unsigned c = a | b;
|
||||
* ```
|
||||
*/
|
||||
class BitwiseOrExpr extends BinaryBitwiseOperation, @orexpr {
|
||||
override string getOperator() { result = "|" }
|
||||
@@ -66,7 +81,10 @@ class BitwiseOrExpr extends BinaryBitwiseOperation, @orexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ bitwise xor expression.
|
||||
* A C/C++ bitwise XOR expression.
|
||||
* ```
|
||||
* unsigned c = a ^ b;
|
||||
* ```
|
||||
*/
|
||||
class BitwiseXorExpr extends BinaryBitwiseOperation, @xorexpr {
|
||||
override string getOperator() { result = "^" }
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
import semmle.code.cpp.exprs.Expr
|
||||
|
||||
/**
|
||||
* A C/C++ builtin operation.
|
||||
* A C/C++ builtin operation. This is the root QL class encompassing
|
||||
* built-in functionality.
|
||||
*/
|
||||
abstract class BuiltInOperation extends Expr {
|
||||
override string getCanonicalQLClass() { result = "BuiltInOperation" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ `__builtin_va_start` expression (used by some implementations of `va_start`).
|
||||
* A C/C++ `__builtin_va_start` built-in operation (used by some
|
||||
* implementations of `va_start`).
|
||||
* ```
|
||||
* __builtin_va_list ap;
|
||||
* __builtin_va_start(ap, last_named_param);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInVarArgsStart extends BuiltInOperation, @vastartexpr {
|
||||
override string toString() { result = "__builtin_va_start" }
|
||||
@@ -17,7 +23,13 @@ class BuiltInVarArgsStart extends BuiltInOperation, @vastartexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ `__builtin_va_end` expression (used by some implementations of `va_end`).
|
||||
* A C/C++ `__builtin_va_end` built-in operation (used by some implementations
|
||||
* of `va_end`).
|
||||
* ```
|
||||
* __builtin_va_start(ap, last_named_param);
|
||||
* ap = __builtin_va_arg(ap, long);
|
||||
* __builtin_va_end(ap);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInVarArgsEnd extends BuiltInOperation, @vaendexpr {
|
||||
override string toString() { result = "__builtin_va_end" }
|
||||
@@ -26,7 +38,11 @@ class BuiltInVarArgsEnd extends BuiltInOperation, @vaendexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ `__builtin_va_arg` expression (used by some implementations of `va_arg`).
|
||||
* A C/C++ `__builtin_va_arg` built-in operation (used by some implementations
|
||||
* of `va_arg`).
|
||||
* ```
|
||||
* ap = __builtin_va_arg(ap, long);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInVarArg extends BuiltInOperation, @vaargexpr {
|
||||
override string toString() { result = "__builtin_va_arg" }
|
||||
@@ -35,7 +51,13 @@ class BuiltInVarArg extends BuiltInOperation, @vaargexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ `__builtin_va_copy` expression (used by some implementations of `va_copy`).
|
||||
* A C/C++ `__builtin_va_copy` built-in operation (used by some implementations
|
||||
* of `va_copy`).
|
||||
* ```
|
||||
* va_list ap, aq;
|
||||
* __builtin_va_start(ap, last_named_param);
|
||||
* va_copy(aq, ap);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInVarArgCopy extends BuiltInOperation, @vacopyexpr {
|
||||
override string toString() { result = "__builtin_va_copy" }
|
||||
@@ -45,6 +67,9 @@ class BuiltInVarArgCopy extends BuiltInOperation, @vacopyexpr {
|
||||
|
||||
/**
|
||||
* A Microsoft C/C++ `__noop` expression, which does nothing.
|
||||
* ```
|
||||
* __noop;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInNoOp extends BuiltInOperation, @noopexpr {
|
||||
override string toString() { result = "__noop" }
|
||||
@@ -53,16 +78,37 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__offsetof` expression (used by some implementations of offsetof in the presence of user-defined `operator&`).
|
||||
* DEPRECATED: Use `BuiltInOperationBuiltInOffsetOf` instead.
|
||||
*/
|
||||
class BuiltInOperationOffsetOf extends BuiltInOperation, @offsetofexpr {
|
||||
override string toString() { result = "__offsetof" }
|
||||
deprecated class BuiltInOperationOffsetOf = BuiltInOperationBuiltInOffsetOf;
|
||||
|
||||
override string getCanonicalQLClass() { result = "BuiltInOperationOffsetOf" }
|
||||
/**
|
||||
* A C/C++ `__builtin_offsetof` built-in operation (used by some implementations
|
||||
* of `offsetof`). The operation retains its semantics even in the presence
|
||||
* of an overloaded `operator &`). This is a GNU/Clang extension.
|
||||
* ```
|
||||
* struct S {
|
||||
* int a, b;
|
||||
* };
|
||||
* int d = __builtin_offsetof(struct S, b); // usually 4
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationBuiltInOffsetOf extends BuiltInOperation, @offsetofexpr {
|
||||
override string toString() { result = "__builtin_offsetof" }
|
||||
|
||||
override string getCanonicalQLClass() { result = "BuiltInOperationBuiltInOffsetOf" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ `__INTADDR__` expression, used by EDG to implement `offsetof` in the presence of user-defined `operator&`.
|
||||
* A C/C++ `__INTADDR__` built-in operation (used by some implementations
|
||||
* of `offsetof`). The operation retains its semantics even in the presence
|
||||
* of an overloaded `operator &`). This is an EDG extension.
|
||||
* ```
|
||||
* struct S {
|
||||
* int a, b;
|
||||
* };
|
||||
* int d = __INTADDR__(struct S, b); // usually 4
|
||||
* ```
|
||||
*/
|
||||
class BuiltInIntAddr extends BuiltInOperation, @intaddrexpr {
|
||||
override string toString() { result = "__INTADDR__" }
|
||||
@@ -71,7 +117,13 @@ class BuiltInIntAddr extends BuiltInOperation, @intaddrexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_assign` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_assign` built-in operation (used by some implementations of
|
||||
* the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has a copy assignment operator.
|
||||
* ```
|
||||
* bool v = __has_assign(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasAssign extends BuiltInOperation, @hasassignexpr {
|
||||
override string toString() { result = "__has_assign" }
|
||||
@@ -80,7 +132,13 @@ class BuiltInOperationHasAssign extends BuiltInOperation, @hasassignexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_copy` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_copy` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has a copy constructor.
|
||||
* ```
|
||||
* std::integral_constant< bool, __has_copy(_Tp)> hc;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr {
|
||||
override string toString() { result = "__has_copy" }
|
||||
@@ -89,7 +147,14 @@ class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_nothrow_assign` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_nothrow_assign` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if a copy assignment operator has an empty exception
|
||||
* specification.
|
||||
* ```
|
||||
* std::integral_constant< bool, __has_nothrow_assign(_Tp)> hnta;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasNoThrowAssign extends BuiltInOperation, @hasnothrowassign {
|
||||
override string toString() { result = "__has_nothrow_assign" }
|
||||
@@ -98,7 +163,14 @@ class BuiltInOperationHasNoThrowAssign extends BuiltInOperation, @hasnothrowassi
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_nothrow_constructor` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_nothrow_constructor` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the default constructor has an empty exception
|
||||
* specification.
|
||||
* ```
|
||||
* bool v = __has_nothrow_constructor(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasNoThrowConstructor extends BuiltInOperation, @hasnothrowconstr {
|
||||
override string toString() { result = "__has_nothrow_constructor" }
|
||||
@@ -107,7 +179,13 @@ class BuiltInOperationHasNoThrowConstructor extends BuiltInOperation, @hasnothro
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_nothrow_copy` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_nothrow_copy` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the copy constructor has an empty exception specification.
|
||||
* ```
|
||||
* std::integral_constant< bool, __has_nothrow_copy(MyType) >;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasNoThrowCopy extends BuiltInOperation, @hasnothrowcopy {
|
||||
override string toString() { result = "__has_nothrow_copy" }
|
||||
@@ -116,7 +194,14 @@ class BuiltInOperationHasNoThrowCopy extends BuiltInOperation, @hasnothrowcopy {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_trivial_assign` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_trivial_assign` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has a trivial assignment
|
||||
* operator (`operator =`).
|
||||
* ```
|
||||
* bool v = __has_trivial_assign(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasTrivialAssign extends BuiltInOperation, @hastrivialassign {
|
||||
override string toString() { result = "__has_trivial_assign" }
|
||||
@@ -125,7 +210,13 @@ class BuiltInOperationHasTrivialAssign extends BuiltInOperation, @hastrivialassi
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_trivial_constructor` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_trivial_constructor` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has a trivial constructor.
|
||||
* ```
|
||||
* bool v = __has_trivial_constructor(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasTrivialConstructor extends BuiltInOperation, @hastrivialconstr {
|
||||
override string toString() { result = "__has_trivial_constructor" }
|
||||
@@ -134,7 +225,13 @@ class BuiltInOperationHasTrivialConstructor extends BuiltInOperation, @hastrivia
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_trivial_copy` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_trivial_copy` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns true if the type has a trivial copy constructor.
|
||||
* ```
|
||||
* std::integral_constant< bool, __has_trivial_copy(MyType) > htc;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasTrivialCopy extends BuiltInOperation, @hastrivialcopy {
|
||||
override string toString() { result = "__has_trivial_copy" }
|
||||
@@ -143,7 +240,13 @@ class BuiltInOperationHasTrivialCopy extends BuiltInOperation, @hastrivialcopy {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_trivial_destructor` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_trivial_destructor` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has a trivial destructor.
|
||||
* ```
|
||||
* bool v = __has_trivial_destructor(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasTrivialDestructor extends BuiltInOperation, @hastrivialdestructor {
|
||||
override string toString() { result = "__has_trivial_destructor" }
|
||||
@@ -152,7 +255,13 @@ class BuiltInOperationHasTrivialDestructor extends BuiltInOperation, @hastrivial
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_user_destructor` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_user_destructor` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns true if the type has a user-declared destructor.
|
||||
* ```
|
||||
* bool v = __has_user_destructor(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasUserDestructor extends BuiltInOperation, @hasuserdestr {
|
||||
override string toString() { result = "__has_user_destructor" }
|
||||
@@ -161,7 +270,16 @@ class BuiltInOperationHasUserDestructor extends BuiltInOperation, @hasuserdestr
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__has_virtual_destructor` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__has_virtual_destructor` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has a virtual destructor.
|
||||
* ```
|
||||
* template<typename _Tp>
|
||||
* struct has_virtual_destructor
|
||||
* : public integral_constant<bool, __has_virtual_destructor(_Tp)>
|
||||
* { };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasVirtualDestructor extends BuiltInOperation, @hasvirtualdestr {
|
||||
override string toString() { result = "__has_virtual_destructor" }
|
||||
@@ -170,7 +288,13 @@ class BuiltInOperationHasVirtualDestructor extends BuiltInOperation, @hasvirtual
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_abstract` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_abstract` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the class has at least one pure virtual function.
|
||||
* ```
|
||||
* bool v = __is_abstract(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsAbstract extends BuiltInOperation, @isabstractexpr {
|
||||
override string toString() { result = "__is_abstract" }
|
||||
@@ -179,7 +303,13 @@ class BuiltInOperationIsAbstract extends BuiltInOperation, @isabstractexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_base_of` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_base_of` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the first type is a base class of the second type, of if both types are the same.
|
||||
* ```
|
||||
* bool v = __is_base_of(MyType, OtherType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsBaseOf extends BuiltInOperation, @isbaseofexpr {
|
||||
override string toString() { result = "__is_base_of" }
|
||||
@@ -188,7 +318,13 @@ class BuiltInOperationIsBaseOf extends BuiltInOperation, @isbaseofexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_class` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_class` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type is a `class` or a `struct`.
|
||||
* ```
|
||||
* bool v = __is_class(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsClass extends BuiltInOperation, @isclassexpr {
|
||||
override string toString() { result = "__is_class" }
|
||||
@@ -197,7 +333,13 @@ class BuiltInOperationIsClass extends BuiltInOperation, @isclassexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_convertible_to` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_convertible_to` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the first type can be converted to the second type.
|
||||
* ```
|
||||
* bool v = __is_convertible_to(MyType, OtherType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsConvertibleTo extends BuiltInOperation, @isconvtoexpr {
|
||||
override string toString() { result = "__is_convertible_to" }
|
||||
@@ -206,7 +348,13 @@ class BuiltInOperationIsConvertibleTo extends BuiltInOperation, @isconvtoexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_empty` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_empty` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has no instance data members.
|
||||
* ```
|
||||
* bool v = __is_empty(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsEmpty extends BuiltInOperation, @isemptyexpr {
|
||||
override string toString() { result = "__is_empty" }
|
||||
@@ -215,7 +363,13 @@ class BuiltInOperationIsEmpty extends BuiltInOperation, @isemptyexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_enum` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_enum` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns true if the type is an `enum`.
|
||||
* ```
|
||||
* bool v = __is_enum(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsEnum extends BuiltInOperation, @isenumexpr {
|
||||
override string toString() { result = "__is_enum" }
|
||||
@@ -224,7 +378,15 @@ class BuiltInOperationIsEnum extends BuiltInOperation, @isenumexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_pod` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_pod` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type is a `class`, `struct` or `union`, WITHOUT
|
||||
* (1) constructors, (2) private or protected non-static members, (3) base
|
||||
* classes, or (4) virtual functions.
|
||||
* ```
|
||||
* bool v = __is_pod(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsPod extends BuiltInOperation, @ispodexpr {
|
||||
override string toString() { result = "__is_pod" }
|
||||
@@ -233,7 +395,13 @@ class BuiltInOperationIsPod extends BuiltInOperation, @ispodexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_polymorphic` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_polymorphic` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has at least one virtual function.
|
||||
* ```
|
||||
* bool v = __is_polymorphic(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsPolymorphic extends BuiltInOperation, @ispolyexpr {
|
||||
override string toString() { result = "__is_polymorphic" }
|
||||
@@ -242,7 +410,13 @@ class BuiltInOperationIsPolymorphic extends BuiltInOperation, @ispolyexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `__is_union` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__is_union` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type is a `union`.
|
||||
* ```
|
||||
* bool v = __is_union(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr {
|
||||
override string toString() { result = "__is_union" }
|
||||
@@ -256,7 +430,16 @@ class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr {
|
||||
deprecated class BuiltInOperationBuiltInTypes = BuiltInOperationBuiltInTypesCompatibleP;
|
||||
|
||||
/**
|
||||
* A C++ `__builtin_types_compatible_p` expression (used by some implementations of the type_traits header).
|
||||
* A C++ `__builtin_types_compatible_p` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the two types are the same (modulo qualifiers).
|
||||
* ```
|
||||
* template<typename _Tp1, typename _Tp2>
|
||||
* struct types_compatible
|
||||
* : public integral_constant<bool, __builtin_types_compatible_p(_Tp1, _Tp2) >
|
||||
* { };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationBuiltInTypesCompatibleP extends BuiltInOperation, @typescompexpr {
|
||||
override string toString() { result = "__builtin_types_compatible_p" }
|
||||
@@ -264,6 +447,15 @@ class BuiltInOperationBuiltInTypesCompatibleP extends BuiltInOperation, @typesco
|
||||
|
||||
/**
|
||||
* A clang `__builtin_shufflevector` expression.
|
||||
*
|
||||
* It outputs a permutation of elements from one or two input vectors.
|
||||
* Please see
|
||||
* https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#langext-builtin-shufflevector
|
||||
* for more information.
|
||||
* ```
|
||||
* // Concatenate every other element of 4-element vectors V1 and V2.
|
||||
* V3 = __builtin_shufflevector(V1, V2, 0, 2, 4, 6);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationBuiltInShuffleVector extends BuiltInOperation, @builtinshufflevector {
|
||||
override string toString() { result = "__builtin_shufflevector" }
|
||||
@@ -273,6 +465,17 @@ class BuiltInOperationBuiltInShuffleVector extends BuiltInOperation, @builtinshu
|
||||
|
||||
/**
|
||||
* A clang `__builtin_convertvector` expression.
|
||||
*
|
||||
* Allows for conversion of vectors of equal element count and compatible
|
||||
* element types. Please see
|
||||
* https://releases.llvm.org/3.7.0/tools/clang/docs/LanguageExtensions.html#builtin-convertvector
|
||||
* for more information.
|
||||
* ```
|
||||
* float vf __attribute__((__vector_size__(16)));
|
||||
* typedef double vector4double __attribute__((__vector_size__(32)));
|
||||
* // convert from a vector of 4 floats to a vector of 4 doubles.
|
||||
* vector4double vd = __builtin_convertvector(vf, vector4double);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationBuiltInConvertVector extends BuiltInOperation, @builtinconvertvector {
|
||||
override string toString() { result = "__builtin_convertvector" }
|
||||
@@ -281,7 +484,14 @@ class BuiltInOperationBuiltInConvertVector extends BuiltInOperation, @builtincon
|
||||
}
|
||||
|
||||
/**
|
||||
* A clang `__builtin_addressof` expression (can be used to implement C++'s std::addressof).
|
||||
* A clang `__builtin_addressof` function (can be used to implement C++'s
|
||||
* `std::addressof`).
|
||||
*
|
||||
* This function disregards any overloads created for `operator &`.
|
||||
* ```
|
||||
* int a = 1;
|
||||
* int *b = __builtin_addressof(a);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationBuiltInAddressOf extends UnaryOperation, BuiltInOperation, @builtinaddressof {
|
||||
/** Gets the function or variable whose address is taken. */
|
||||
@@ -298,7 +508,17 @@ class BuiltInOperationBuiltInAddressOf extends UnaryOperation, BuiltInOperation,
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_trivially_constructible` type trait.
|
||||
* The `__is_trivially_constructible` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has a trivial default
|
||||
* constructor, copy constructor or move constructor.
|
||||
* ```
|
||||
* template<typename T, typename... Args>
|
||||
* struct is_trivially_constructible
|
||||
* : public integral_constant<bool, __is_trivially_constructible(T, Args...) >
|
||||
* { };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyConstructible extends BuiltInOperation,
|
||||
@istriviallyconstructibleexpr {
|
||||
@@ -308,7 +528,15 @@ class BuiltInOperationIsTriviallyConstructible extends BuiltInOperation,
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_destructible` type trait.
|
||||
* The `__is_destructible` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type's destructor is not `delete`d and is accessible
|
||||
* in derived `class`es, and whose base `class` and all non-static data members
|
||||
* are also destructible.
|
||||
* ```
|
||||
* bool v = __is_destructible(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsDestructible extends BuiltInOperation, @isdestructibleexpr {
|
||||
override string toString() { result = "__is_destructible" }
|
||||
@@ -317,7 +545,15 @@ class BuiltInOperationIsDestructible extends BuiltInOperation, @isdestructibleex
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_nothrow_destructible` type trait.
|
||||
* The `__is_nothrow_destructible` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type is destructible and whose destructor, and those
|
||||
* of member data and any super`class`es all have an empty exception
|
||||
* specification.
|
||||
* ```
|
||||
* bool v = __is_nothrow_destructible(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsNothrowDestructible extends BuiltInOperation, @isnothrowdestructibleexpr {
|
||||
override string toString() { result = "__is_nothrow_destructible" }
|
||||
@@ -326,7 +562,14 @@ class BuiltInOperationIsNothrowDestructible extends BuiltInOperation, @isnothrow
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_trivially_destructible` type trait.
|
||||
* The `__is_trivially_destructible` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type is destructible and whose destructor, and those
|
||||
* of member data and any superclasses are all trivial.
|
||||
* ```
|
||||
* bool v = __is_trivially_destructible(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyDestructible extends BuiltInOperation, @istriviallydestructibleexpr {
|
||||
override string toString() { result = "__is_trivially_destructible" }
|
||||
@@ -335,7 +578,17 @@ class BuiltInOperationIsTriviallyDestructible extends BuiltInOperation, @istrivi
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_trivially_assignable` type trait.
|
||||
* The `__is_trivially_assignable` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the assignment operator `C::operator =(const C& c)` is
|
||||
* trivial.
|
||||
* ```
|
||||
* template<typename T>
|
||||
* struct is_trivially_assignable
|
||||
* : public integral_constant<bool, __is_trivially_assignable(T) >
|
||||
* { };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istriviallyassignableexpr {
|
||||
override string toString() { result = "__is_trivially_assignable" }
|
||||
@@ -344,7 +597,14 @@ class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istrivial
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_nothrow_assignable` type trait.
|
||||
* The `__is_nothrow_assignable` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns true if there exists a `C::operator =(const C& c) nothrow`
|
||||
* assignment operator (i.e, with an empty exception specification).
|
||||
* ```
|
||||
* bool v = __is_nothrow_assignable(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowassignableexpr {
|
||||
override string toString() { result = "__is_nothrow_assignable" }
|
||||
@@ -353,7 +613,18 @@ class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowas
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_standard_layout` type trait.
|
||||
* The `__is_standard_layout` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type is a primitive type, or a `class`, `struct` or
|
||||
* `union` WITHOUT (1) virtual functions or base classes, (2) reference member
|
||||
* variable or (3) multiple occurrences of base `class` objects, among other
|
||||
* restrictions. Please see
|
||||
* https://en.cppreference.com/w/cpp/named_req/StandardLayoutType
|
||||
* for more information.
|
||||
* ```
|
||||
* bool v = __is_standard_layout(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsStandardLayout extends BuiltInOperation, @isstandardlayoutexpr {
|
||||
override string toString() { result = "__is_standard_layout" }
|
||||
@@ -362,7 +633,12 @@ class BuiltInOperationIsStandardLayout extends BuiltInOperation, @isstandardlayo
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_trivially_copyable` type trait.
|
||||
* The `__is_trivially_copyable` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if instances of this type can be copied by trivial
|
||||
* means. The copying is done in a manner similar to the `memcpy`
|
||||
* function.
|
||||
*/
|
||||
class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istriviallycopyableexpr {
|
||||
override string toString() { result = "__is_trivially_copyable" }
|
||||
@@ -371,7 +647,18 @@ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istrivially
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_literal_type` type trait.
|
||||
* The `__is_literal_type` built-in operation (used by some implementations of
|
||||
* the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type is a scalar type, a reference type or an array of
|
||||
* literal types, among others. Please see
|
||||
* https://en.cppreference.com/w/cpp/named_req/LiteralType
|
||||
* for more information.
|
||||
*
|
||||
* ```
|
||||
* template <typename _Tp>
|
||||
* std::integral_constant< bool, __is_literal_type(_Tp)> ilt;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr {
|
||||
override string toString() { result = "__is_literal_type" }
|
||||
@@ -380,7 +667,15 @@ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__has_trivial_move_constructor` type trait.
|
||||
* The `__has_trivial_move_constructor` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns true if the move (`&&`) constructor can be generated by the
|
||||
* compiler, with semantics of the `memcpy` operation.
|
||||
* ```
|
||||
* template <typename _Tp>
|
||||
* std::integral_constant< bool, __has_trivial_move_constructor(_Tp)> htmc;
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation,
|
||||
@hastrivialmoveconstructorexpr {
|
||||
@@ -390,7 +685,16 @@ class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation,
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__has_trivial_move_assign` type trait.
|
||||
* The `__has_trivial_move_assign` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns if the move-assign operator `C::operator =(C &&c)` is trivial.
|
||||
* ```
|
||||
* template<typename T>
|
||||
* struct has_trivial_move_assign
|
||||
* : public integral_constant<bool, __has_trivial_move_assign(T) >
|
||||
* { };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasTrivialMoveAssign extends BuiltInOperation, @hastrivialmoveassignexpr {
|
||||
override string toString() { result = "__has_trivial_move_assign" }
|
||||
@@ -399,7 +703,14 @@ class BuiltInOperationHasTrivialMoveAssign extends BuiltInOperation, @hastrivial
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__has_nothrow_move_assign` type trait.
|
||||
* The `__has_nothrow_move_assign` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type has a `C::operator=(C&& c) nothrow`, that is,
|
||||
* an assignment operator with an empty exception specification.
|
||||
* ```
|
||||
* bool v = __has_nothrow_move_assign(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasNothrowMoveAssign extends BuiltInOperation, @hasnothrowmoveassignexpr {
|
||||
override string toString() { result = "__has_nothrow_move_assign" }
|
||||
@@ -408,7 +719,17 @@ class BuiltInOperationHasNothrowMoveAssign extends BuiltInOperation, @hasnothrow
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_constructible` type trait.
|
||||
* The `__is_constructible` built-in operation (used by some implementations
|
||||
* of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type can be constructed using specified arguments
|
||||
* (or none).
|
||||
* ```
|
||||
* template<typename T, typename... Args>
|
||||
* struct is_constructible
|
||||
* : public integral_constant<bool, __is_constructible(T, Args...) >
|
||||
* { };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsConstructible extends BuiltInOperation, @isconstructibleexpr {
|
||||
override string toString() { result = "__is_constructible" }
|
||||
@@ -417,7 +738,14 @@ class BuiltInOperationIsConstructible extends BuiltInOperation, @isconstructible
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_nothrow_constructible` type trait.
|
||||
* The `__is_nothrow_constructible` built-in operation (used by some
|
||||
* implementations of the `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the type is constructable and all its constructors have an
|
||||
* empty exception specification (i.e., are declared with `nothrow`);
|
||||
* ```
|
||||
* bool v = __is_nothrow_constructible(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsNothrowConstructible extends BuiltInOperation, @isnothrowconstructibleexpr {
|
||||
override string toString() { result = "__is_nothrow_constructible" }
|
||||
@@ -426,7 +754,13 @@ class BuiltInOperationIsNothrowConstructible extends BuiltInOperation, @isnothro
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__has_finalizer` type trait.
|
||||
* The `__has_finalizer` built-in operation. This is a Microsoft extension.
|
||||
*
|
||||
* Returns `true` if the type defines a _finalizer_ `C::!C(void)`, to be called
|
||||
* from either the regular destructor or the garbage collector.
|
||||
* ```
|
||||
* bool v = __has_finalizer(MyType);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationHasFinalizer extends BuiltInOperation, @hasfinalizerexpr {
|
||||
override string toString() { result = "__has_finalizer" }
|
||||
@@ -435,7 +769,12 @@ class BuiltInOperationHasFinalizer extends BuiltInOperation, @hasfinalizerexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_delegate` type trait.
|
||||
* The `__is_delegate` built-in operation. This is a Microsoft extension.
|
||||
*
|
||||
* Returns `true` if the function has been declared as a `delegate`, used in
|
||||
* message forwarding. Please see
|
||||
* https://docs.microsoft.com/en-us/cpp/extensions/delegate-cpp-component-extensions
|
||||
* for more information.
|
||||
*/
|
||||
class BuiltInOperationIsDelegate extends BuiltInOperation, @isdelegateexpr {
|
||||
override string toString() { result = "__is_delegate" }
|
||||
@@ -444,7 +783,11 @@ class BuiltInOperationIsDelegate extends BuiltInOperation, @isdelegateexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_interface_class` type trait.
|
||||
* The `__is_interface_class` built-in operation. This is a Microsoft extension.
|
||||
*
|
||||
* Returns `true` if the type has been declared as an `interface`. Please see
|
||||
* https://docs.microsoft.com/en-us/cpp/extensions/interface-class-cpp-component-extensions
|
||||
* for more information.
|
||||
*/
|
||||
class BuiltInOperationIsInterfaceClass extends BuiltInOperation, @isinterfaceclassexpr {
|
||||
override string toString() { result = "__is_interface_class" }
|
||||
@@ -453,7 +796,15 @@ class BuiltInOperationIsInterfaceClass extends BuiltInOperation, @isinterfacecla
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_ref_array` type trait.
|
||||
* The `__is_ref_array` built-in operation. This is a Microsoft extension.
|
||||
*
|
||||
* Returns `true` if the object passed in is a _platform array_. Please see
|
||||
* https://docs.microsoft.com/en-us/cpp/extensions/arrays-cpp-component-extensions
|
||||
* for more information.
|
||||
* ```
|
||||
* array<int>^ x = gcnew array<int>(10);
|
||||
* bool b = __is_ref_array(array<int>);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsRefArray extends BuiltInOperation, @isrefarrayexpr {
|
||||
override string toString() { result = "__is_ref_array" }
|
||||
@@ -462,7 +813,15 @@ class BuiltInOperationIsRefArray extends BuiltInOperation, @isrefarrayexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_ref_class` type trait.
|
||||
* The `__is_ref_class` built-in operation. This is a Microsoft extension.
|
||||
*
|
||||
* Returns `true` if the type is a _reference class_. Please see
|
||||
* https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions
|
||||
* for more information.
|
||||
* ```
|
||||
* ref class R {};
|
||||
* bool b = __is_ref_class(R);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsRefClass extends BuiltInOperation, @isrefclassexpr {
|
||||
override string toString() { result = "__is_ref_class" }
|
||||
@@ -471,7 +830,16 @@ class BuiltInOperationIsRefClass extends BuiltInOperation, @isrefclassexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_sealed` type trait.
|
||||
* The `__is_sealed` built-in operation. This is a Microsoft extension.
|
||||
*
|
||||
* Returns `true` if a given class or virtual function is marked as `sealed`,
|
||||
* meaning that it cannot be extended or overridden. The `sealed` keyword
|
||||
* is similar to the C++11 `final` keyword.
|
||||
* ```
|
||||
* ref class X sealed {
|
||||
* virtual void f() sealed { }
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsSealed extends BuiltInOperation, @issealedexpr {
|
||||
override string toString() { result = "__is_sealed" }
|
||||
@@ -480,7 +848,17 @@ class BuiltInOperationIsSealed extends BuiltInOperation, @issealedexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_simple_value_class` type trait.
|
||||
* The `__is_simple_value_class` built-in operation. This is a Microsoft extension.
|
||||
*
|
||||
* Returns `true` if passed a value type that contains no references to the
|
||||
* garbage-collected heap.
|
||||
* ```
|
||||
* ref class R {}; // __is_simple_value_class(R) == false
|
||||
* value struct V {}; // __is_simple_value_class(V) == true
|
||||
* value struct V2 { // __is_simple_value_class(V2) == false
|
||||
* R ^ r; // not a simple value type
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsSimpleValueClass extends BuiltInOperation, @issimplevalueclassexpr {
|
||||
override string toString() { result = "__is_simple_value_class" }
|
||||
@@ -489,7 +867,15 @@ class BuiltInOperationIsSimpleValueClass extends BuiltInOperation, @issimplevalu
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_value_class` type trait.
|
||||
* The `__is_value_class` built-in operation. This is a Microsoft extension.
|
||||
*
|
||||
* Returns `true` if passed a value type. Please see
|
||||
* https://docs.microsoft.com/en-us/cpp/extensions/classes-and-structs-cpp-component-extensions
|
||||
* For more information.
|
||||
* ```
|
||||
* value struct V {};
|
||||
* bool v = __is_value_class(V);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsValueClass extends BuiltInOperation, @isvalueclassexpr {
|
||||
override string toString() { result = "__is_value_class" }
|
||||
@@ -498,7 +884,16 @@ class BuiltInOperationIsValueClass extends BuiltInOperation, @isvalueclassexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__is_final` type trait.
|
||||
* The `__is_final` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* Returns `true` if the `class` has been marked with the `final` specifier.
|
||||
* ```
|
||||
* template<typename T>
|
||||
* struct is_final
|
||||
* : public integral_constant<bool, __is_final(T) >
|
||||
* { };
|
||||
* ```
|
||||
*/
|
||||
class BuiltInOperationIsFinal extends BuiltInOperation, @isfinalexpr {
|
||||
override string toString() { result = "__is_final" }
|
||||
@@ -507,17 +902,35 @@ class BuiltInOperationIsFinal extends BuiltInOperation, @isfinalexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* The `__builtin_choose_expr` type trait.
|
||||
* The `__builtin_choose_expr` expression. This is a GNU/Clang extension.
|
||||
*
|
||||
* The expression functions similarly to the ternary `?:` operator, except
|
||||
* that it is evaluated at compile-time.
|
||||
* ```
|
||||
* int sz = __builtin_choose_expr(__builtin_types_compatible_p(int, long), 4, 8);
|
||||
* ```
|
||||
*/
|
||||
class BuiltInChooseExpr extends BuiltInOperation, @builtinchooseexpr {
|
||||
override string toString() { result = "__builtin_choose_expr" }
|
||||
|
||||
override string getCanonicalQLClass() { result = "BuiltInChooseExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill operation on a GNU vector.
|
||||
* Fill operation on a vector. This is a GNU extension.
|
||||
*
|
||||
* A single scalar value is used to populate all the elements in a vector.
|
||||
* In the example below, the scalar value is `25`:
|
||||
* ```
|
||||
* typedef int v16i __attribute__((vector_size(16)));
|
||||
* v16i src, dst;
|
||||
* dst = src << 25;
|
||||
* ```
|
||||
*/
|
||||
class VectorFillOperation extends UnaryOperation, @vec_fill {
|
||||
override string getOperator() { result = "(vector fill)" }
|
||||
|
||||
override string getCanonicalQLClass() { result = "VectorFillOperation" }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,8 @@ private import semmle.code.cpp.dataflow.EscapesTree
|
||||
|
||||
/**
|
||||
* A C/C++ call.
|
||||
*
|
||||
* This is the abstract root QL class for all types of calls.
|
||||
*/
|
||||
abstract class Call extends Expr, NameQualifiableElement {
|
||||
/**
|
||||
@@ -228,7 +230,7 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
* Gets the function called by this call.
|
||||
*
|
||||
* In the case of virtual function calls, the result is the most-specific function in the override tree (as
|
||||
* determined by the compiler) such that the target at runtime will be one of result.getAnOverridingFunction*().
|
||||
* determined by the compiler) such that the target at runtime will be one of `result.getAnOverridingFunction*()`.
|
||||
*/
|
||||
override Function getTarget() { funbind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
@@ -273,7 +275,11 @@ class FunctionCall extends Call, @funbindexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of unary operator * applied to a user-defined type.
|
||||
* An instance of a _user-defined_ unary `operator*` applied to its argument.
|
||||
* ```
|
||||
* T1 operator*(const T2 &);
|
||||
* T1 a; T2 b;
|
||||
* a = *b;
|
||||
*/
|
||||
class OverloadedPointerDereferenceExpr extends FunctionCall {
|
||||
OverloadedPointerDereferenceExpr() {
|
||||
@@ -281,6 +287,8 @@ class OverloadedPointerDereferenceExpr extends FunctionCall {
|
||||
getTarget().getEffectiveNumberOfParameters() = 1
|
||||
}
|
||||
|
||||
override string getCanonicalQLClass() { result = "OverloadedPointerDereferenceExpr" }
|
||||
|
||||
/**
|
||||
* Gets the expression this operator * applies to.
|
||||
*/
|
||||
@@ -317,11 +325,18 @@ class OverloadedPointerDereferenceExpr extends FunctionCall {
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of operator [] applied to a user-defined type.
|
||||
* An instance of a _user-defined_ binary `operator[]` applied to its arguments.
|
||||
* ```
|
||||
* struct T2 { T1 operator[](const T3 &); };
|
||||
* T1 a; T2 b; T3 c;
|
||||
* a = b[c];
|
||||
* ```
|
||||
*/
|
||||
class OverloadedArrayExpr extends FunctionCall {
|
||||
OverloadedArrayExpr() { getTarget().hasName("operator[]") }
|
||||
|
||||
override string getCanonicalQLClass() { result = "OverloadedArrayExpr" }
|
||||
|
||||
/**
|
||||
* Gets the expression being subscripted.
|
||||
*/
|
||||
@@ -339,6 +354,12 @@ class OverloadedArrayExpr extends FunctionCall {
|
||||
|
||||
/**
|
||||
* A C/C++ call which is performed through a function pointer.
|
||||
*
|
||||
* In the call below, `(*funcptr)` may be simplified to just `funcptr`.
|
||||
* ```
|
||||
* extern int (*funcptr)(int a, int b);
|
||||
* int c = (*funcptr)(1, 2);
|
||||
* ```
|
||||
*/
|
||||
class ExprCall extends Call, @callexpr {
|
||||
/**
|
||||
@@ -361,6 +382,11 @@ class ExprCall extends Call, @callexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ call which is performed through a variable of function pointer type.
|
||||
* ```
|
||||
* int call_via_ptr(int (*pfn)(int)) {
|
||||
* return pfn(5);
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class VariableCall extends ExprCall {
|
||||
VariableCall() { this.getExpr() instanceof VariableAccess }
|
||||
@@ -375,6 +401,10 @@ class VariableCall extends ExprCall {
|
||||
|
||||
/**
|
||||
* A call to a constructor.
|
||||
* ```
|
||||
* struct S { S(void) {} };
|
||||
* S s;
|
||||
* ```
|
||||
*/
|
||||
class ConstructorCall extends FunctionCall {
|
||||
ConstructorCall() { super.getTarget() instanceof Constructor }
|
||||
@@ -387,6 +417,9 @@ class ConstructorCall extends FunctionCall {
|
||||
|
||||
/**
|
||||
* A C++ `throw` expression.
|
||||
* ```
|
||||
* throw Exc(2);
|
||||
* ```
|
||||
*/
|
||||
class ThrowExpr extends Expr, @throw_expr {
|
||||
/**
|
||||
@@ -404,6 +437,9 @@ class ThrowExpr extends Expr, @throw_expr {
|
||||
|
||||
/**
|
||||
* A C++ `throw` expression with no argument (which causes the current exception to be re-thrown).
|
||||
* ```
|
||||
* throw;
|
||||
* ```
|
||||
*/
|
||||
class ReThrowExpr extends ThrowExpr {
|
||||
ReThrowExpr() { this.getType() instanceof VoidType }
|
||||
@@ -415,6 +451,10 @@ class ReThrowExpr extends ThrowExpr {
|
||||
|
||||
/**
|
||||
* A call to a destructor.
|
||||
* ```
|
||||
* struct S { ~S(void) {} } *s;
|
||||
* s->~S();
|
||||
* ```
|
||||
*/
|
||||
class DestructorCall extends FunctionCall {
|
||||
DestructorCall() { super.getTarget() instanceof Destructor }
|
||||
@@ -431,6 +471,11 @@ class DestructorCall extends FunctionCall {
|
||||
* For example, given a plain old data type `pod_t`, the syntax `ptr->~pod_t()` is
|
||||
* a vacuous destructor call, as `~pod_t` isn't actually a function. This can also
|
||||
* occur in instantiated templates, as `ptr->~T()` becomes vacuous when `T` is `int`.
|
||||
* ```
|
||||
* typedef int pod_t;
|
||||
* pod_t *s;
|
||||
* s->~pod_t();
|
||||
* ```
|
||||
*/
|
||||
class VacuousDestructorCall extends Expr, @vacuous_destructor_call {
|
||||
/**
|
||||
@@ -446,6 +491,9 @@ class VacuousDestructorCall extends Expr, @vacuous_destructor_call {
|
||||
/**
|
||||
* An initialization of a base class or member variable performed as part
|
||||
* of a constructor's explicit initializer list or implicit actions.
|
||||
*
|
||||
* This is a QL root class for reprenting various types of constructor
|
||||
* initializations.
|
||||
*/
|
||||
class ConstructorInit extends Expr, @ctorinit {
|
||||
override string getCanonicalQLClass() { result = "ConstructorInit" }
|
||||
@@ -462,6 +510,15 @@ class ConstructorBaseInit extends ConstructorInit, ConstructorCall {
|
||||
/**
|
||||
* A call to a constructor of a direct non-virtual base class as part of a
|
||||
* constructor's initializer list or compiler-generated actions.
|
||||
* ```
|
||||
* struct S {
|
||||
* int a;
|
||||
* S(int b): a(b) {}
|
||||
* };
|
||||
* struct T: S {
|
||||
* T(): S(33) {} // S(33) is a constructor call
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class ConstructorDirectInit extends ConstructorBaseInit, @ctordirectinit {
|
||||
override string getCanonicalQLClass() { result = "ConstructorDirectInit" }
|
||||
@@ -473,6 +530,15 @@ class ConstructorDirectInit extends ConstructorBaseInit, @ctordirectinit {
|
||||
*
|
||||
* If the virtual base class has already been initialized, then this
|
||||
* call won't be performed.
|
||||
* ```
|
||||
* struct S {
|
||||
* int a;
|
||||
* S(int b): a(b) {}
|
||||
* };
|
||||
* struct T: virtual S {
|
||||
* T(): S(33) {} // S(33) is a call to a virtual base constructor
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class ConstructorVirtualInit extends ConstructorBaseInit, @ctorvirtualinit {
|
||||
override string getCanonicalQLClass() { result = "ConstructorVirtualInit" }
|
||||
@@ -481,6 +547,13 @@ class ConstructorVirtualInit extends ConstructorBaseInit, @ctorvirtualinit {
|
||||
/**
|
||||
* A call to a constructor of the same class as part of a constructor's
|
||||
* initializer list, which delegates object construction (C++11 only).
|
||||
* ```
|
||||
* struct S {
|
||||
* int a;
|
||||
* S(int b): a(b) { }
|
||||
* S(): S(0) { } // delegation to another constructor
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class ConstructorDelegationInit extends ConstructorBaseInit, @ctordelegatinginit {
|
||||
override string getCanonicalQLClass() { result = "ConstructorDelegationInit" }
|
||||
@@ -489,6 +562,14 @@ class ConstructorDelegationInit extends ConstructorBaseInit, @ctordelegatinginit
|
||||
/**
|
||||
* An initialization of a member variable performed as part of a
|
||||
* constructor's explicit initializer list or implicit actions.
|
||||
* In the example below, member variable `b` is being initialized by
|
||||
* constructor parameter `a`:
|
||||
* ```
|
||||
* struct S {
|
||||
* int b;
|
||||
* S(int a): b(a) {}
|
||||
* } s(2);
|
||||
* ```
|
||||
*/
|
||||
class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit {
|
||||
/** Gets the field being initialized. */
|
||||
@@ -530,6 +611,12 @@ class DestructorBaseDestruction extends DestructorCall, DestructorDestruction {
|
||||
/**
|
||||
* A call to a destructor of a direct non-virtual base class as part of a
|
||||
* destructor's compiler-generated actions.
|
||||
* ```
|
||||
* struct S { ~S(void) {} };
|
||||
* struct T: S {
|
||||
* ~T(void) {} // will call ~S()
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class DestructorDirectDestruction extends DestructorBaseDestruction, @dtordirectdestruct {
|
||||
override string getCanonicalQLClass() { result = "DestructorDirectDestruction" }
|
||||
@@ -541,6 +628,12 @@ class DestructorDirectDestruction extends DestructorBaseDestruction, @dtordirect
|
||||
*
|
||||
* If the virtual base class wasn't initialized by the ConstructorVirtualInit
|
||||
* in the corresponding constructor, then this call won't be performed.
|
||||
* ```
|
||||
* struct S { ~S(void) {} };
|
||||
* struct T: virtual S {
|
||||
* ~T(void) {} // will call ~S()
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class DestructorVirtualDestruction extends DestructorBaseDestruction, @dtorvirtualdestruct {
|
||||
override string getCanonicalQLClass() { result = "DestructorVirtualDestruction" }
|
||||
@@ -549,6 +642,13 @@ class DestructorVirtualDestruction extends DestructorBaseDestruction, @dtorvirtu
|
||||
/**
|
||||
* A destruction of a member variable performed as part of a
|
||||
* destructor's compiler-generated actions.
|
||||
* ```
|
||||
* struct S { ~S(void) {} };
|
||||
* struct T {
|
||||
* S s;
|
||||
* ~T(void) {} // will call s.~S()
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class DestructorFieldDestruction extends DestructorDestruction, @dtorfielddestruct {
|
||||
/** Gets the field being destructed. */
|
||||
|
||||
@@ -22,7 +22,7 @@ abstract class Conversion extends Expr {
|
||||
/**
|
||||
* A C/C++ cast expression.
|
||||
*
|
||||
* To get the type which the expression is being cast to, use getType().
|
||||
* To get the type which the expression is being cast to, use `Cast::getType()`.
|
||||
*
|
||||
* There are two groups of subtypes of `Cast`. The first group differentiates
|
||||
* between the different cast syntax forms, e.g. `CStyleCast`, `StaticCast`,
|
||||
@@ -33,6 +33,9 @@ abstract class Conversion extends Expr {
|
||||
* cast that is syntactically as `CStyleCast` may also be an `IntegralConversion`,
|
||||
* a `PointerBaseClassConversion`, or some other semantic conversion. Similarly,
|
||||
* a `PointerDerivedClassConversion` may also be a `CStyleCast` or a `StaticCast`.
|
||||
*
|
||||
* This is an abstract root QL class representing the different casts. For
|
||||
* specific examples, consult the documentation for any of QL classes mentioned above.
|
||||
*/
|
||||
abstract class Cast extends Conversion, @cast {
|
||||
/**
|
||||
@@ -71,6 +74,10 @@ module CastSanity {
|
||||
|
||||
/**
|
||||
* A cast expression in C, or a C-style cast expression in C++.
|
||||
* ```
|
||||
* float f = 3.0f;
|
||||
* int i = (int)f;
|
||||
* ```
|
||||
*/
|
||||
class CStyleCast extends Cast, @c_style_cast {
|
||||
override string toString() { result = "(" + this.getType().getName() + ")..." }
|
||||
@@ -82,6 +89,14 @@ class CStyleCast extends Cast, @c_style_cast {
|
||||
|
||||
/**
|
||||
* A C++ `static_cast` expression.
|
||||
*
|
||||
* Please see https://en.cppreference.com/w/cpp/language/static_cast for
|
||||
* more information.
|
||||
* ```
|
||||
* struct T: S {};
|
||||
* struct S *s = get_S();
|
||||
* struct T *t = static_cast<struct T *>(s); // downcast
|
||||
* ```
|
||||
*/
|
||||
class StaticCast extends Cast, @static_cast {
|
||||
override string toString() { result = "static_cast<" + this.getType().getName() + ">..." }
|
||||
@@ -93,6 +108,13 @@ class StaticCast extends Cast, @static_cast {
|
||||
|
||||
/**
|
||||
* A C++ `const_cast` expression.
|
||||
*
|
||||
* Please see https://en.cppreference.com/w/cpp/language/const_cast for
|
||||
* more information.
|
||||
* ```
|
||||
* const struct S *s = get_S();
|
||||
* struct S *t = const_cast<struct S *>(s);
|
||||
* ```
|
||||
*/
|
||||
class ConstCast extends Cast, @const_cast {
|
||||
override string toString() { result = "const_cast<" + this.getType().getName() + ">..." }
|
||||
@@ -104,6 +126,13 @@ class ConstCast extends Cast, @const_cast {
|
||||
|
||||
/**
|
||||
* A C++ `reinterpret_cast` expression.
|
||||
*
|
||||
* Please see https://en.cppreference.com/w/cpp/language/reinterpret_cast for
|
||||
* more information.
|
||||
* ```
|
||||
* struct S *s = get_S();
|
||||
* std::uintptr_t p = reinterpret_cast<std::uintptr_t>(s);
|
||||
* ```
|
||||
*/
|
||||
class ReinterpretCast extends Cast, @reinterpret_cast {
|
||||
override string toString() { result = "reinterpret_cast<" + this.getType().getName() + ">..." }
|
||||
@@ -135,7 +164,11 @@ private predicate isPointerToMemberOrNullPointer(Type type) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversion from one arithmetic or enum type to another.
|
||||
* A conversion from one arithmetic or `enum` type to another.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class ArithmeticConversion extends Cast {
|
||||
ArithmeticConversion() {
|
||||
@@ -149,6 +182,10 @@ class ArithmeticConversion extends Cast {
|
||||
|
||||
/**
|
||||
* A conversion from one integral or enum type to another.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class IntegralConversion extends ArithmeticConversion {
|
||||
IntegralConversion() {
|
||||
@@ -164,7 +201,11 @@ class IntegralConversion extends ArithmeticConversion {
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversion from one floating point type to another.
|
||||
* A conversion from one floating point type.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class FloatingPointConversion extends ArithmeticConversion {
|
||||
FloatingPointConversion() {
|
||||
@@ -181,6 +222,10 @@ class FloatingPointConversion extends ArithmeticConversion {
|
||||
|
||||
/**
|
||||
* A conversion from a floating point type to an integral or enum type.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class FloatingPointToIntegralConversion extends ArithmeticConversion {
|
||||
FloatingPointToIntegralConversion() {
|
||||
@@ -197,6 +242,10 @@ class FloatingPointToIntegralConversion extends ArithmeticConversion {
|
||||
|
||||
/**
|
||||
* A conversion from an integral or enum type to a floating point type.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class IntegralToFloatingPointConversion extends ArithmeticConversion {
|
||||
IntegralToFloatingPointConversion() {
|
||||
@@ -212,9 +261,15 @@ class IntegralToFloatingPointConversion extends ArithmeticConversion {
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversion from one pointer type to another. The conversion does
|
||||
* A conversion from one pointer type to another.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*
|
||||
* The conversion does
|
||||
* not modify the value of the pointer. For pointer conversions involving
|
||||
* casts between base and derived classes, see `BaseClassConversion` and
|
||||
* casts between base and derived classes, please see see `BaseClassConversion` or
|
||||
* `DerivedClassConversion`.
|
||||
*/
|
||||
class PointerConversion extends Cast {
|
||||
@@ -232,10 +287,16 @@ class PointerConversion extends Cast {
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversion from one pointer-to-member type to another. The conversion
|
||||
* does not modify the value of the pointer-to-member. For pointer-to-member
|
||||
* conversions involving casts between base and derived classes, see
|
||||
* `PointerToMemberBaseClassConversion` and `PointerToMemberDerivedClassConversion`.
|
||||
* A conversion from one pointer-to-member type to another.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*
|
||||
* The conversion does not modify the value of the pointer-to-member.
|
||||
* For pointer-to-member conversions involving casts between base and
|
||||
* derived classes, please see `PointerToMemberBaseClassConversion`
|
||||
* or `PointerToMemberDerivedClassConversion`.
|
||||
*/
|
||||
class PointerToMemberConversion extends Cast {
|
||||
PointerToMemberConversion() {
|
||||
@@ -263,6 +324,10 @@ class PointerToMemberConversion extends Cast {
|
||||
|
||||
/**
|
||||
* A conversion from a pointer type to an integral or enum type.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class PointerToIntegralConversion extends Cast {
|
||||
PointerToIntegralConversion() {
|
||||
@@ -280,6 +345,10 @@ class PointerToIntegralConversion extends Cast {
|
||||
|
||||
/**
|
||||
* A conversion from an integral or enum type to a pointer type.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class IntegralToPointerConversion extends Cast {
|
||||
IntegralToPointerConversion() {
|
||||
@@ -297,7 +366,11 @@ class IntegralToPointerConversion extends Cast {
|
||||
|
||||
/**
|
||||
* A conversion to `bool`. Returns `false` if the source value is zero,
|
||||
* false, or nullptr. Returns `true` otherwise.
|
||||
* `false`, or `nullptr`. Returns `true` otherwise.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class BoolConversion extends Cast {
|
||||
BoolConversion() { conversionkinds(underlyingElement(this), 1) }
|
||||
@@ -309,6 +382,10 @@ class BoolConversion extends Cast {
|
||||
|
||||
/**
|
||||
* A conversion to `void`.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class VoidConversion extends Cast {
|
||||
VoidConversion() {
|
||||
@@ -322,11 +399,16 @@ class VoidConversion extends Cast {
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversion between two pointers or glvalues related by inheritance. The
|
||||
* base class will always be either a direct base class of the derived class,
|
||||
* A conversion between two pointers or _glvalue_s related by inheritance.
|
||||
*
|
||||
* The base class will always be either a direct base class of the derived class,
|
||||
* or a virtual base class of the derived class. A conversion to an indirect
|
||||
* non-virtual base class will be represented as a sequence of conversions to
|
||||
* direct base classes.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class InheritanceConversion extends Cast {
|
||||
InheritanceConversion() {
|
||||
@@ -377,8 +459,12 @@ private Class getConversionClass(Expr expr) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversion from a pointer or glvalue of a derived class to a pointer or
|
||||
* glvalue of a direct or virtual base class.
|
||||
* A conversion from a pointer or _glvalue_ of a derived class to a pointer or
|
||||
* _glvalue_ of a direct or virtual base class.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class BaseClassConversion extends InheritanceConversion {
|
||||
BaseClassConversion() { conversionkinds(underlyingElement(this), 2) }
|
||||
@@ -400,8 +486,12 @@ class BaseClassConversion extends InheritanceConversion {
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversion from a pointer or glvalue to a base class to a pointer or glvalue
|
||||
* A conversion from a pointer or _glvalue_ to a base class to a pointer or _glvalue_
|
||||
* to a direct derived class.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class DerivedClassConversion extends InheritanceConversion {
|
||||
DerivedClassConversion() { conversionkinds(underlyingElement(this), 3) }
|
||||
@@ -420,6 +510,10 @@ class DerivedClassConversion extends InheritanceConversion {
|
||||
/**
|
||||
* A conversion from a pointer-to-member of a derived class to a pointer-to-member
|
||||
* of an immediate base class.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class PointerToMemberBaseClassConversion extends Cast {
|
||||
PointerToMemberBaseClassConversion() { conversionkinds(underlyingElement(this), 4) }
|
||||
@@ -436,6 +530,10 @@ class PointerToMemberBaseClassConversion extends Cast {
|
||||
/**
|
||||
* A conversion from a pointer-to-member of a base class to a pointer-to-member
|
||||
* of an immediate derived class.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class PointerToMemberDerivedClassConversion extends Cast {
|
||||
PointerToMemberDerivedClassConversion() { conversionkinds(underlyingElement(this), 5) }
|
||||
@@ -450,9 +548,13 @@ class PointerToMemberDerivedClassConversion extends Cast {
|
||||
}
|
||||
|
||||
/**
|
||||
* A conversion of a glvalue from one type to another. The conversion does not
|
||||
* modify the address of the glvalue. For glvalue conversions involving base and
|
||||
* A conversion of a _glvalue_ from one type to another. The conversion does not
|
||||
* modify the address of the _glvalue_. For _glvalue_ conversions involving base and
|
||||
* derived classes, see `BaseClassConversion` and `DerivedClassConversion`.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class GlvalueConversion extends Cast {
|
||||
GlvalueConversion() { conversionkinds(underlyingElement(this), 6) }
|
||||
@@ -465,18 +567,22 @@ class GlvalueConversion extends Cast {
|
||||
}
|
||||
|
||||
/**
|
||||
* The adjustment of the type of a class prvalue. Most commonly seen in code
|
||||
* The adjustment of the type of a class _prvalue_. Most commonly seen in code
|
||||
* similar to:
|
||||
*
|
||||
* ```
|
||||
* class String { ... };
|
||||
* String func();
|
||||
* void caller() {
|
||||
* const String& r = func();
|
||||
* }
|
||||
*
|
||||
* In the above example, the result of the call to `func` is a prvalue of type
|
||||
* ```
|
||||
* In the above example, the result of the call to `func` is a _prvalue_ of type
|
||||
* `String`, which will be adjusted to type `const String` before being bound
|
||||
* to the reference.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class PrvalueAdjustmentConversion extends Cast {
|
||||
PrvalueAdjustmentConversion() { conversionkinds(underlyingElement(this), 7) }
|
||||
@@ -490,6 +596,14 @@ class PrvalueAdjustmentConversion extends Cast {
|
||||
|
||||
/**
|
||||
* A C++ `dynamic_cast` expression.
|
||||
*
|
||||
* Please see https://en.cppreference.com/w/cpp/language/dynamic_cast for
|
||||
* more information.
|
||||
* ```
|
||||
* struct T: S {};
|
||||
* struct S *s = get_S();
|
||||
* struct T *t = dynamic_cast<struct T *>(s); // downcast
|
||||
* ```
|
||||
*/
|
||||
class DynamicCast extends Cast, @dynamic_cast {
|
||||
override string toString() { result = "dynamic_cast<" + this.getType().getName() + ">..." }
|
||||
@@ -504,6 +618,11 @@ class DynamicCast extends Cast, @dynamic_cast {
|
||||
/**
|
||||
* A Microsoft C/C++ `__uuidof` expression that returns the UUID of a type, as
|
||||
* specified by the `__declspec(uuid)` attribute.
|
||||
* ```
|
||||
* struct UUID { char a[16]; };
|
||||
* struct __declspec(uuid("{01234567-89ab-cdef-0123-456789ABCDEF}")) S {};
|
||||
* UUID uuid = __uuidof(S);
|
||||
* ```
|
||||
*/
|
||||
class UuidofOperator extends Expr, @uuidof {
|
||||
override string toString() {
|
||||
@@ -519,22 +638,18 @@ class UuidofOperator extends Expr, @uuidof {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `typeid` expression which provides runtime type information
|
||||
* about an expression or type.
|
||||
* A C++ `typeid` expression which provides run-time type information (RTTI)
|
||||
* about its argument.
|
||||
*
|
||||
* Please see https://en.cppreference.com/w/cpp/language/typeid for more
|
||||
* information.
|
||||
* ```
|
||||
* Base *ptr = new Derived;
|
||||
* const std::type_info &info1 = typeid(ptr);
|
||||
* printf("the type of ptr is: %s\n", typeid(ptr).name());
|
||||
* ```
|
||||
*/
|
||||
class TypeidOperator extends Expr, @type_id {
|
||||
/**
|
||||
* Gets the type that is returned by this typeid expression.
|
||||
*
|
||||
* For example in the following code the `typeid` returns the
|
||||
* type `MyClass *`.
|
||||
*
|
||||
* ```
|
||||
* MyClass *ptr;
|
||||
*
|
||||
* printf("the type of ptr is: %s\n", typeid(ptr).name);
|
||||
* ```
|
||||
*/
|
||||
Type getResultType() { typeid_bind(underlyingElement(this), unresolveElement(result)) }
|
||||
|
||||
/**
|
||||
@@ -566,6 +681,10 @@ class TypeidOperator extends Expr, @type_id {
|
||||
*
|
||||
* 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 SizeofPackOperator extends Expr, @sizeof_pack {
|
||||
override string toString() { result = "sizeof...(...)" }
|
||||
@@ -586,6 +705,9 @@ abstract class SizeofOperator extends Expr, @runtime_sizeof {
|
||||
|
||||
/**
|
||||
* A C/C++ sizeof expression whose operand is an expression.
|
||||
* ```
|
||||
* if (sizeof(a) == sizeof(b)) { c = (b)a; }
|
||||
* ```
|
||||
*/
|
||||
class SizeofExprOperator extends SizeofOperator {
|
||||
SizeofExprOperator() { exists(Expr e | this.getChild(0) = e) }
|
||||
@@ -611,6 +733,9 @@ class SizeofExprOperator extends SizeofOperator {
|
||||
|
||||
/**
|
||||
* A C/C++ sizeof expression whose operand is a type name.
|
||||
* ```
|
||||
* int szlong = sizeof(int) == sizeof(long)? 4 : 8;
|
||||
* ```
|
||||
*/
|
||||
class SizeofTypeOperator extends SizeofOperator {
|
||||
SizeofTypeOperator() { sizeof_bind(underlyingElement(this), _) }
|
||||
@@ -643,6 +768,9 @@ abstract class AlignofOperator extends Expr, @runtime_alignof {
|
||||
|
||||
/**
|
||||
* A C++11 `alignof` expression whose operand is an expression.
|
||||
* ```
|
||||
* int addrMask = ~(alignof(expr) - 1);
|
||||
* ```
|
||||
*/
|
||||
class AlignofExprOperator extends AlignofOperator {
|
||||
AlignofExprOperator() { exists(Expr e | this.getChild(0) = e) }
|
||||
@@ -662,6 +790,9 @@ class AlignofExprOperator extends AlignofOperator {
|
||||
|
||||
/**
|
||||
* A C++11 `alignof` expression whose operand is a type name.
|
||||
* ```
|
||||
* bool proper_alignment = (alingof(T) == alignof(T[0]);
|
||||
* ```
|
||||
*/
|
||||
class AlignofTypeOperator extends AlignofOperator {
|
||||
AlignofTypeOperator() { sizeof_bind(underlyingElement(this), _) }
|
||||
@@ -679,6 +810,10 @@ class AlignofTypeOperator extends AlignofOperator {
|
||||
|
||||
/**
|
||||
* A C/C++ array to pointer conversion.
|
||||
*
|
||||
* The conversion is either implicit or underlies a particular cast.
|
||||
* Please see `CStyleCast`, `StaticCast`, `ConstCast`
|
||||
* or `ReinterpretCast` for more information.
|
||||
*/
|
||||
class ArrayToPointerConversion extends Conversion, @array_to_pointer {
|
||||
/** Gets a textual representation of this conversion. */
|
||||
|
||||
@@ -2,6 +2,8 @@ import semmle.code.cpp.exprs.Expr
|
||||
|
||||
/**
|
||||
* A C/C++ comparison operation, that is, either an equality operation or a relational operation.
|
||||
*
|
||||
* This is a QL abstract base class for all comparisons.
|
||||
*/
|
||||
abstract class ComparisonOperation extends BinaryOperation { }
|
||||
|
||||
@@ -14,6 +16,9 @@ abstract class EqualityOperation extends ComparisonOperation {
|
||||
|
||||
/**
|
||||
* A C/C++ equal expression.
|
||||
* ```
|
||||
* bool c = (a == b);
|
||||
* ```
|
||||
*/
|
||||
class EQExpr extends EqualityOperation, @eqexpr {
|
||||
override string getCanonicalQLClass() { result = "EQExpr" }
|
||||
@@ -23,6 +28,9 @@ class EQExpr extends EqualityOperation, @eqexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ not equal expression.
|
||||
* ```
|
||||
* bool c = (a != b);
|
||||
* ```
|
||||
*/
|
||||
class NEExpr extends EqualityOperation, @neexpr {
|
||||
override string getCanonicalQLClass() { result = "NEExpr" }
|
||||
@@ -65,6 +73,9 @@ abstract class RelationalOperation extends ComparisonOperation {
|
||||
|
||||
/**
|
||||
* A C/C++ greater than expression.
|
||||
* ```
|
||||
* bool c = (a > b);
|
||||
* ```
|
||||
*/
|
||||
class GTExpr extends RelationalOperation, @gtexpr {
|
||||
override string getCanonicalQLClass() { result = "GTExpr" }
|
||||
@@ -77,7 +88,10 @@ class GTExpr extends RelationalOperation, @gtexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ lesser than expression.
|
||||
* A C/C++ less than expression.
|
||||
* ```
|
||||
* bool c = (a < b);
|
||||
* ```
|
||||
*/
|
||||
class LTExpr extends RelationalOperation, @ltexpr {
|
||||
override string getCanonicalQLClass() { result = "LTExpr" }
|
||||
@@ -91,6 +105,9 @@ class LTExpr extends RelationalOperation, @ltexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ greater than or equal expression.
|
||||
* ```
|
||||
* bool c = (a >= b);
|
||||
* ```
|
||||
*/
|
||||
class GEExpr extends RelationalOperation, @geexpr {
|
||||
override string getCanonicalQLClass() { result = "GEExpr" }
|
||||
@@ -103,7 +120,10 @@ class GEExpr extends RelationalOperation, @geexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ lesser than or equal expression.
|
||||
* A C/C++ less than or equal expression.
|
||||
* ```
|
||||
* bool c = (a <= b);
|
||||
* ```
|
||||
*/
|
||||
class LEExpr extends RelationalOperation, @leexpr {
|
||||
override string getCanonicalQLClass() { result = "LEExpr" }
|
||||
|
||||
@@ -5,6 +5,8 @@ private import semmle.code.cpp.internal.AddressConstantExpression
|
||||
|
||||
/**
|
||||
* A C/C++ expression.
|
||||
*
|
||||
* This is the root QL class for all expressions.
|
||||
*/
|
||||
class Expr extends StmtParent, @expr {
|
||||
/** Gets the nth child of this expression. */
|
||||
@@ -163,36 +165,36 @@ class Expr extends StmtParent, @expr {
|
||||
predicate mayBeGloballyImpure() { any() }
|
||||
|
||||
/**
|
||||
* Holds if this expression is an lvalue. An lvalue is an expression that
|
||||
* Holds if this expression is an _lvalue_. An _lvalue_ is an expression that
|
||||
* represents a location, rather than a value.
|
||||
* See [basic.lval] for more about lvalues.
|
||||
*/
|
||||
predicate isLValueCategory() { expr_types(underlyingElement(this), _, 3) }
|
||||
|
||||
/**
|
||||
* Holds if this expression is an xvalue. An xvalue is a location whose
|
||||
* lifetime is about to end (e.g. an rvalue reference returned from a function
|
||||
* Holds if this expression is an _xvalue_. An _xvalue_ is a location whose
|
||||
* lifetime is about to end (e.g. an _rvalue_ reference returned from a function
|
||||
* call).
|
||||
* See [basic.lval] for more about xvalues.
|
||||
*/
|
||||
predicate isXValueCategory() { expr_types(underlyingElement(this), _, 2) }
|
||||
|
||||
/**
|
||||
* Holds if this expression is a prvalue. A prvalue is an expression that
|
||||
* Holds if this expression is a _prvalue_. A _prvalue_ is an expression that
|
||||
* represents a value, rather than a location.
|
||||
* See [basic.lval] for more about prvalues.
|
||||
*/
|
||||
predicate isPRValueCategory() { expr_types(underlyingElement(this), _, 1) }
|
||||
|
||||
/**
|
||||
* Holds if this expression is a glvalue. A glvalue is either an lvalue or an
|
||||
* xvalue.
|
||||
* Holds if this expression is a _glvalue_. A _glvalue_ is either an _lvalue_ or an
|
||||
* _xvalue_.
|
||||
*/
|
||||
predicate isGLValueCategory() { isLValueCategory() or isXValueCategory() }
|
||||
|
||||
/**
|
||||
* Holds if this expression is an rvalue. An rvalue is either a prvalue or an
|
||||
* xvalue.
|
||||
* Holds if this expression is an _rvalue_. An _rvalue_ is either a _prvalue_ or an
|
||||
* _xvalue_.
|
||||
*/
|
||||
predicate isRValueCategory() { isPRValueCategory() or isXValueCategory() }
|
||||
|
||||
@@ -205,7 +207,7 @@ class Expr extends StmtParent, @expr {
|
||||
* - "prvalue"
|
||||
* - "prvalue(load)"
|
||||
*
|
||||
* The "prvalue(load)" string is used when the expression is a prvalue, but
|
||||
* The "prvalue(load)" string is used when the expression is a _prvalue_, but
|
||||
* `hasLValueToRvalueConversion()` holds.
|
||||
*/
|
||||
string getValueCategoryString() {
|
||||
@@ -252,32 +254,32 @@ class Expr extends StmtParent, @expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this expression has undergone an lvalue-to-rvalue conversion to
|
||||
* Holds if this expression has undergone an _lvalue_-to-_rvalue_ conversion to
|
||||
* extract its value.
|
||||
* for example:
|
||||
* ```
|
||||
* y = x;
|
||||
* ```
|
||||
* The VariableAccess for `x` is a prvalue, and hasLValueToRValueConversion()
|
||||
* The `VariableAccess` for `x` is a _prvalue_, and `hasLValueToRValueConversion()`
|
||||
* holds because the value of `x` was loaded from the location of `x`.
|
||||
* The VariableAccess for `y` is an lvalue, and hasLValueToRValueConversion()
|
||||
* The `VariableAccess` for `y` is an _lvalue_, and `hasLValueToRValueConversion()`
|
||||
* does not hold because the value of `y` was not extracted.
|
||||
*
|
||||
* See [conv.lval] for more about the lvalue-to-rvalue conversion
|
||||
* See [conv.lval] for more about the _lvalue_-to-_rvalue_ conversion
|
||||
*/
|
||||
predicate hasLValueToRValueConversion() { expr_isload(underlyingElement(this)) }
|
||||
|
||||
/**
|
||||
* Holds if this expression is an LValue, in the sense of having an address.
|
||||
* Holds if this expression is an _lvalue_, in the sense of having an address.
|
||||
*
|
||||
* Being an LValue is best approximated as having an address.
|
||||
* This is a strict superset of modifiable LValues, which are best approximated by things which could be on the left-hand side of an assignment.
|
||||
* This is also a strict superset of expressions which provide an LValue, which is best approximated by things whose address is important.
|
||||
* Being an _lvalue_ is best approximated as having an address.
|
||||
* This is a strict superset of modifiable _lvalue_s, which are best approximated by things which could be on the left-hand side of an assignment.
|
||||
* This is also a strict superset of expressions which provide an _lvalue_, which is best approximated by things whose address is important.
|
||||
*
|
||||
* See [basic.lval] in the C++ language specification.
|
||||
* In C++03, every expression is either an LValue or an RValue.
|
||||
* In C++11, every expression is exactly one of an LValue, an XValue, or a PRValue (with RValues being the union of XValues and PRValues).
|
||||
* Using the C++11 terminology, this predicate selects expressions whose value category is lvalue.
|
||||
* In C++03, every expression is either an _lvalue_ or an _rvalue_.
|
||||
* In C++11, every expression is exactly one of an _lvalue_, an _xvalue_, or a _prvalue_ (with _rvalue_s being the union of _xvalue_s and _prvalue_s).
|
||||
* Using the C++11 terminology, this predicate selects expressions whose value category is _lvalue_.
|
||||
*/
|
||||
predicate isLValue() {
|
||||
// C++ n3337 - 5.1.1 clause 1
|
||||
@@ -458,6 +460,8 @@ class Expr extends StmtParent, @expr {
|
||||
|
||||
/**
|
||||
* A C/C++ operation.
|
||||
*
|
||||
* This is the QL abstract root class for all operations.
|
||||
*/
|
||||
abstract class Operation extends Expr {
|
||||
/** Gets the operator of this operation. */
|
||||
@@ -509,7 +513,14 @@ abstract class BinaryOperation extends Operation {
|
||||
*
|
||||
* This is used to represent particular syntax within templates where the final
|
||||
* form of the expression is not known. In actual instantiations, it will have
|
||||
* been turned into a constructor call or aggregate initializer or similar.
|
||||
* been turned into either a constructor call or an aggregate initializer or similar.
|
||||
* ```
|
||||
* template <typename T>
|
||||
* struct S {
|
||||
* T member;
|
||||
* S() { member = T({ arg1, arg2 }); }
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
class ParenthesizedBracedInitializerList extends Expr, @braced_init_list {
|
||||
override string toString() { result = "({...})" }
|
||||
@@ -519,6 +530,12 @@ class ParenthesizedBracedInitializerList extends Expr, @braced_init_list {
|
||||
|
||||
/**
|
||||
* A C/C++ parenthesis expression.
|
||||
*
|
||||
* It is typically used to raise the syntactic precedence of the subexpression that
|
||||
* it contains. For example:
|
||||
* ```
|
||||
* int d = a & ( b | c );
|
||||
* ```
|
||||
*/
|
||||
class ParenthesisExpr extends Conversion, @parexpr {
|
||||
override string toString() { result = "(...)" }
|
||||
@@ -528,6 +545,8 @@ class ParenthesisExpr extends Conversion, @parexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ expression that has not been resolved.
|
||||
*
|
||||
* It is assigned `ErroneousType` as its type.
|
||||
*/
|
||||
class ErrorExpr extends Expr, @errorexpr {
|
||||
override string toString() { result = "<error expr>" }
|
||||
@@ -537,6 +556,12 @@ class ErrorExpr extends Expr, @errorexpr {
|
||||
|
||||
/**
|
||||
* A Microsoft C/C++ __assume expression.
|
||||
*
|
||||
* Unlike `assert`, `__assume` is evaluated at compile time and
|
||||
* is treated as a hint to the optimizer
|
||||
* ```
|
||||
* __assume(ptr < end_buf);
|
||||
* ```
|
||||
*/
|
||||
class AssumeExpr extends Expr, @assume {
|
||||
override string toString() { result = "__assume(...)" }
|
||||
@@ -551,6 +576,9 @@ class AssumeExpr extends Expr, @assume {
|
||||
|
||||
/**
|
||||
* A C/C++ comma expression.
|
||||
* ```
|
||||
* int c = compute1(), compute2(), resulting_value;
|
||||
* ```
|
||||
*/
|
||||
class CommaExpr extends Expr, @commaexpr {
|
||||
override string getCanonicalQLClass() { result = "CommaExpr" }
|
||||
@@ -583,6 +611,9 @@ class CommaExpr extends Expr, @commaexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ address-of expression.
|
||||
* ```
|
||||
* int *ptr = &var;
|
||||
* ```
|
||||
*/
|
||||
class AddressOfExpr extends UnaryOperation, @address_of {
|
||||
override string getCanonicalQLClass() { result = "AddressOfExpr" }
|
||||
@@ -605,11 +636,14 @@ class AddressOfExpr extends UnaryOperation, @address_of {
|
||||
}
|
||||
|
||||
/**
|
||||
* An implicit conversion from type T to type T&.
|
||||
* An implicit conversion from type `T` to type `T &`.
|
||||
*
|
||||
* This typically occurs when an expression of type T is used to initialize a variable or parameter of
|
||||
* type T&, and is to reference types what AddressOfExpr is to pointer types - though this class is
|
||||
* This typically occurs when an expression of type `T` is used to initialize a variable or parameter of
|
||||
* type `T &`, and is to reference types what `AddressOfExpr` is to pointer types, though this class is
|
||||
* considered to be a conversion rather than an operation, and as such doesn't occur in the main AST.
|
||||
* ```
|
||||
* int &var_ref = var;
|
||||
* ```
|
||||
*/
|
||||
class ReferenceToExpr extends Conversion, @reference_to {
|
||||
override string toString() { result = "(reference to)" }
|
||||
@@ -620,9 +654,12 @@ class ReferenceToExpr extends Conversion, @reference_to {
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance of unary operator * applied to a built-in type.
|
||||
* An instance of the built-in unary `operator *` applied to a type.
|
||||
*
|
||||
* For user-defined types, see OverloadedPointerDereferenceExpr.
|
||||
* For user-defined overloads of `operator *`, see `OverloadedPointerDereferenceExpr`.
|
||||
* ```
|
||||
* int var = *varptr;
|
||||
* ```
|
||||
*/
|
||||
class PointerDereferenceExpr extends UnaryOperation, @indirect {
|
||||
override string getCanonicalQLClass() { result = "PointerDereferenceExpr" }
|
||||
@@ -650,11 +687,15 @@ class PointerDereferenceExpr extends UnaryOperation, @indirect {
|
||||
}
|
||||
|
||||
/**
|
||||
* An implicit conversion from type T& to type T.
|
||||
* An implicit conversion from type `T &` to type `T`.
|
||||
*
|
||||
* This typically occurs when an variable of type T& is used in a context which expects type T, and
|
||||
* is to reference types what PointerDereferenceExpr is to pointer types - though this class is
|
||||
* This typically occurs when an variable of type `T &` is used in a context which expects type `T`, and
|
||||
* is to reference types what `PointerDereferenceExpr` is to pointer types - though this class is
|
||||
* considered to be a conversion rather than an operation, and as such doesn't occur in the main AST.
|
||||
* ```
|
||||
* float &f_ref = get_ref();
|
||||
* float f = f_ref;
|
||||
* ```
|
||||
*/
|
||||
class ReferenceDereferenceExpr extends Conversion, @ref_indirect {
|
||||
override string toString() { result = "(reference dereference)" }
|
||||
@@ -756,6 +797,9 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
|
||||
|
||||
/**
|
||||
* A C++ `new` (non-array) expression.
|
||||
* ```
|
||||
* Foo *ptr = new Foo(3);
|
||||
* ```
|
||||
*/
|
||||
class NewExpr extends NewOrNewArrayExpr, @new_expr {
|
||||
override string toString() { result = "new" }
|
||||
@@ -782,6 +826,10 @@ class NewExpr extends NewOrNewArrayExpr, @new_expr {
|
||||
|
||||
/**
|
||||
* A C++ `new[]` (array) expression.
|
||||
* ```
|
||||
* Foo *foo = new Foo[]{1, 3, 5};
|
||||
* Bar *bar = new Bar[5];
|
||||
* ```
|
||||
*/
|
||||
class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
|
||||
override string toString() { result = "new[]" }
|
||||
@@ -827,6 +875,9 @@ class NewArrayExpr extends NewOrNewArrayExpr, @new_array_expr {
|
||||
|
||||
/**
|
||||
* A C++ `delete` (non-array) expression.
|
||||
* ```
|
||||
* delete ptr;
|
||||
* ```
|
||||
*/
|
||||
class DeleteExpr extends Expr, @delete_expr {
|
||||
override string toString() { result = "delete" }
|
||||
@@ -902,6 +953,9 @@ class DeleteExpr extends Expr, @delete_expr {
|
||||
|
||||
/**
|
||||
* A C++ `delete[]` (array) expression.
|
||||
* ```
|
||||
* delete[] arr;
|
||||
* ```
|
||||
*/
|
||||
class DeleteArrayExpr extends Expr, @delete_array_expr {
|
||||
override string toString() { result = "delete[]" }
|
||||
@@ -977,6 +1031,10 @@ class DeleteArrayExpr extends Expr, @delete_array_expr {
|
||||
|
||||
/**
|
||||
* A compound statement enclosed in parentheses used as an expression (a GNU extension to C/C++).
|
||||
* In the example below, `b` is the return value from the compound statement.
|
||||
* ```
|
||||
* int a = ({ int b = c + d; b; });
|
||||
* ```
|
||||
*/
|
||||
class StmtExpr extends Expr, @expr_stmt {
|
||||
override string toString() { result = "(statement expression)" }
|
||||
@@ -1006,7 +1064,7 @@ private Expr getStmtResultExpr(Stmt stmt) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ this expression.
|
||||
* A C++ `this` expression.
|
||||
*/
|
||||
class ThisExpr extends Expr, @thisaccess {
|
||||
override string toString() { result = "this" }
|
||||
@@ -1019,8 +1077,10 @@ class ThisExpr extends Expr, @thisaccess {
|
||||
}
|
||||
|
||||
/**
|
||||
* A code block expression, for example `^ int (int x, int y) {return x + y;}`.
|
||||
*
|
||||
* A code block expression, for example:
|
||||
* ```
|
||||
* ^ int (int x, int y) {return x + y;}
|
||||
* ```
|
||||
* Blocks are a language extension supported by Clang, and by Apple's
|
||||
* branch of GCC.
|
||||
*/
|
||||
@@ -1036,7 +1096,11 @@ class BlockExpr extends Literal {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++11 `noexcept` expression, for example `noexcept(1 + 2)`.
|
||||
* A C++11 `noexcept` expression, returning `true` if its subexpression is guaranteed
|
||||
* not to `throw` exceptions. For example:
|
||||
* ```
|
||||
* if (noexcept(func_1() + func_2())) { }
|
||||
* ```
|
||||
*/
|
||||
class NoExceptExpr extends Expr, @noexceptexpr {
|
||||
override string toString() { result = "noexcept(...)" }
|
||||
@@ -1052,6 +1116,10 @@ class NoExceptExpr extends Expr, @noexceptexpr {
|
||||
/**
|
||||
* A C++17 fold expression. This will only appear in an uninstantiated template; any instantiations
|
||||
* of the template will instead contain the sequence of expressions given by expanding the fold.
|
||||
* ```
|
||||
* template < typename... T >
|
||||
* auto sum ( T... t ) { return ( t + ... + 0 ); }
|
||||
* ```
|
||||
*/
|
||||
class FoldExpr extends Expr, @foldexpr {
|
||||
override string toString() {
|
||||
|
||||
@@ -2,6 +2,8 @@ import semmle.code.cpp.exprs.Expr
|
||||
|
||||
/**
|
||||
* A C/C++ literal.
|
||||
*
|
||||
* The is the QL root class for all literals.
|
||||
*/
|
||||
class Literal extends Expr, @literal {
|
||||
/** Gets a textual representation of this literal. */
|
||||
@@ -26,9 +28,7 @@ class Literal extends Expr, @literal {
|
||||
* For example:
|
||||
* ```
|
||||
* void *label_ptr = &&myLabel; // &&myLabel is a LabelLiteral
|
||||
*
|
||||
* goto *label_ptr; // this is a ComputedGotoStmt
|
||||
*
|
||||
* myLabel: // this is a LabelStmt
|
||||
* ```
|
||||
*/
|
||||
@@ -84,7 +84,11 @@ abstract class TextLiteral extends Literal {
|
||||
}
|
||||
|
||||
/**
|
||||
* A character literal, for example `'a'` or `L'a'`.
|
||||
* A character literal. For example:
|
||||
* ```
|
||||
* char c1 = 'a';
|
||||
* wchar_t c2 = L'b';
|
||||
* ```
|
||||
*/
|
||||
class CharLiteral extends TextLiteral {
|
||||
CharLiteral() { this.getValueText().regexpMatch("(?s)\\s*L?'.*") }
|
||||
@@ -98,7 +102,11 @@ class CharLiteral extends TextLiteral {
|
||||
}
|
||||
|
||||
/**
|
||||
* A string literal, for example `"abcdef"` or `L"123456"`.
|
||||
* A string literal. For example:
|
||||
* ```
|
||||
* const char *s1 = "abcdef";
|
||||
* const wchar_t *s2 = L"123456";
|
||||
* ```
|
||||
*/
|
||||
class StringLiteral extends TextLiteral {
|
||||
StringLiteral() {
|
||||
@@ -111,7 +119,11 @@ class StringLiteral extends TextLiteral {
|
||||
}
|
||||
|
||||
/**
|
||||
* An octal literal.
|
||||
* An octal literal. For example:
|
||||
* ```
|
||||
* char esc = 033;
|
||||
* ```
|
||||
* Octal literals must always start with the digit `0`.
|
||||
*/
|
||||
class OctalLiteral extends Literal {
|
||||
OctalLiteral() { super.getValueText().regexpMatch("\\s*0[0-7]+[uUlL]*\\s*") }
|
||||
@@ -121,6 +133,9 @@ class OctalLiteral extends Literal {
|
||||
|
||||
/**
|
||||
* A hexadecimal literal.
|
||||
* ```
|
||||
* unsigned int32_t minus2 = 0xfffffffe;
|
||||
* ```
|
||||
*/
|
||||
class HexLiteral extends Literal {
|
||||
HexLiteral() { super.getValueText().regexpMatch("\\s*0[xX][0-9a-fA-F]+[uUlL]*\\s*") }
|
||||
@@ -130,6 +145,8 @@ class HexLiteral extends Literal {
|
||||
|
||||
/**
|
||||
* A C/C++ aggregate literal.
|
||||
*
|
||||
* For example:
|
||||
*/
|
||||
class AggregateLiteral extends Expr, @aggregateliteral {
|
||||
override string getCanonicalQLClass() { result = "AggregateLiteral" }
|
||||
@@ -153,7 +170,11 @@ class AggregateLiteral extends Expr, @aggregateliteral {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ aggregate literal that initializes a class, struct, or union
|
||||
* A C/C++ aggregate literal that initializes a `class`, `struct`, or `union`.
|
||||
* For example:
|
||||
* ```
|
||||
* S s = { arg1, arg2, { arg3, arg4 }, arg5 };
|
||||
* ```
|
||||
*/
|
||||
class ClassAggregateLiteral extends AggregateLiteral {
|
||||
Class classType;
|
||||
@@ -271,6 +292,9 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
|
||||
|
||||
/**
|
||||
* A C/C++ aggregate literal that initializes an array
|
||||
* ```
|
||||
* S s[4] = { s_1, s_2, s_3, s_n };
|
||||
* ```
|
||||
*/
|
||||
class ArrayAggregateLiteral extends ArrayOrVectorAggregateLiteral {
|
||||
ArrayType arrayType;
|
||||
@@ -286,6 +310,15 @@ class ArrayAggregateLiteral extends ArrayOrVectorAggregateLiteral {
|
||||
|
||||
/**
|
||||
* A C/C++ aggregate literal that initializes a GNU vector type.
|
||||
*
|
||||
* Braced initializer lists are used, similarly to what is done
|
||||
* for arrays.
|
||||
* ```
|
||||
* typedef int v4si __attribute__ (( vector_size(4*sizeof(int)) ));
|
||||
* v4si v = (v4si){ 1, 2, 3, 4 };
|
||||
* typedef float float4 __attribute__((ext_vector_type(4)));
|
||||
* float4 vf = {1.0f, 2.0f, 3.0f, 4.0f};
|
||||
* ```
|
||||
*/
|
||||
class VectorAggregateLiteral extends ArrayOrVectorAggregateLiteral {
|
||||
GNUVectorType vectorType;
|
||||
|
||||
@@ -7,6 +7,9 @@ abstract class UnaryLogicalOperation extends UnaryOperation { }
|
||||
|
||||
/**
|
||||
* A C/C++ logical not expression.
|
||||
* ```
|
||||
* c = !a;
|
||||
* ```
|
||||
*/
|
||||
class NotExpr extends UnaryLogicalOperation, @notexpr {
|
||||
override string getOperator() { result = "!" }
|
||||
@@ -35,7 +38,10 @@ abstract class BinaryLogicalOperation extends BinaryOperation {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ logical and expression.
|
||||
* A C/C++ logical AND expression.
|
||||
* ```
|
||||
* if (a && b) { }
|
||||
* ```
|
||||
*/
|
||||
class LogicalAndExpr extends BinaryLogicalOperation, @andlogicalexpr {
|
||||
override string getOperator() { result = "&&" }
|
||||
@@ -53,7 +59,10 @@ class LogicalAndExpr extends BinaryLogicalOperation, @andlogicalexpr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A C/C++ logical or expression.
|
||||
* A C/C++ logical OR expression.
|
||||
* ```
|
||||
* if (a || b) { }
|
||||
* ```
|
||||
*/
|
||||
class LogicalOrExpr extends BinaryLogicalOperation, @orlogicalexpr {
|
||||
override string getOperator() { result = "||" }
|
||||
@@ -72,6 +81,9 @@ class LogicalOrExpr extends BinaryLogicalOperation, @orlogicalexpr {
|
||||
|
||||
/**
|
||||
* A C/C++ conditional ternary expression.
|
||||
* ```
|
||||
* a = (b > c ? d : e);
|
||||
* ```
|
||||
*/
|
||||
class ConditionalExpr extends Operation, @conditionalexpr {
|
||||
/** Gets the condition of this conditional expression. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
| edg.c:12:14:12:51 | (int)... | 0 | 0 |
|
||||
| edg.c:12:14:12:51 | __offsetof | 1 | 1 |
|
||||
| edg.c:12:14:12:51 | __builtin_offsetof | 1 | 1 |
|
||||
| edg.c:12:49:12:50 | f2 | 0 | 0 |
|
||||
| edg.c:13:14:13:45 | 0 | 0 | 0 |
|
||||
| edg.c:13:14:13:45 | & ... | 0 | 0 |
|
||||
|
||||
Reference in New Issue
Block a user