Merge pull request #2309 from geoffw0/cpp418

CPP: QLDoc enhancements
This commit is contained in:
Jonas Jensen
2019-11-15 08:46:08 +01:00
committed by GitHub
16 changed files with 1455 additions and 248 deletions

View File

@@ -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&amp;
* 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 (&amp;) and rvalue references (&amp;&amp;).
* 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&amp;).
* 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&amp;&amp;).
* 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 &lt;template &lt;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) }

View File

@@ -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() }

View File

@@ -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() }

View File

@@ -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
)

View File

@@ -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

View File

@@ -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 = "-" }

View File

@@ -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 {
/**

View File

@@ -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 = "^" }

View File

@@ -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" }
}
/**

View File

@@ -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. */

View File

@@ -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. */

View File

@@ -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" }

View File

@@ -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&amp;.
* 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&amp;, 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&amp; to type T.
* An implicit conversion from type `T &` to type `T`.
*
* This typically occurs when an variable of type T&amp; 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() {

View File

@@ -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;

View File

@@ -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. */

View File

@@ -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 |