diff --git a/cpp/ql/src/semmle/code/cpp/UserType.qll b/cpp/ql/src/semmle/code/cpp/UserType.qll index ad65bb21185..cbb7f39adbd 100644 --- a/cpp/ql/src/semmle/code/cpp/UserType.qll +++ b/cpp/ql/src/semmle/code/cpp/UserType.qll @@ -97,7 +97,6 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @ * ``` * class C; * typedef int ti; - * extern void foo(int); * ``` */ class TypeDeclarationEntry extends DeclarationEntry, @type_decl { diff --git a/cpp/ql/src/semmle/code/cpp/exprs/ArithmeticOperation.qll b/cpp/ql/src/semmle/code/cpp/exprs/ArithmeticOperation.qll index 9822495746f..310c7147d37 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/ArithmeticOperation.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/ArithmeticOperation.qll @@ -37,7 +37,7 @@ class UnaryPlusExpr extends UnaryArithmeticOperation, @unaryplusexpr { /** * A C/C++ GNU conjugation expression. It operates on `_Complex` or - * `__complex_`numbers, and is similar to the C99 `conj`, `conjf` and `conjl` + * `__complex__ `numbers, and is similar to the C99 `conj`, `conjf` and `conjl` * functions. * ``` * _Complex double a = ( 1.0, 2.0 ); @@ -55,7 +55,7 @@ class ConjugationExpr extends UnaryArithmeticOperation, @conjugation { * * This is the abstract base QL class for increment and decrement operations. * - * Note that this doesn't include calls to _user-defined_ `operator++` + * Note that this does not include calls to _user-defined_ `operator++` * or `operator--`. */ abstract class CrementOperation extends UnaryArithmeticOperation { @@ -74,35 +74,35 @@ 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; * ``` @@ -118,7 +118,7 @@ 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; * ``` @@ -134,7 +134,7 @@ 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++; * ``` @@ -152,7 +152,7 @@ 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--; * ``` diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Assignment.qll b/cpp/ql/src/semmle/code/cpp/exprs/Assignment.qll index 7690fd7b620..06f9c4de5b0 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Assignment.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Assignment.qll @@ -4,12 +4,14 @@ 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 `operator` 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. */ - Expr getLValue() { this.hasChild(result, 0) } + /** Gets the *lvalue* of this assignment. */ + Expr get*lvalue*() { this.hasChild(result, 0) } /** Gets the rvalue of this assignment. */ Expr getRValue() { this.hasChild(result, 1) } @@ -20,7 +22,7 @@ abstract class Assignment extends Operation { this.getRValue().mayBeGloballyImpure() or not exists(VariableAccess va, LocalScopeVariable v | - va = this.getLValue() and + va = this.get*lvalue*() and v = va.getTarget() and not va.getConversion+() instanceof ReferenceDereferenceExpr and not v.isStatic() @@ -51,13 +53,13 @@ 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; * ``` @@ -69,7 +71,7 @@ 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; * ``` @@ -207,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` or `if` + * 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 { /** diff --git a/cpp/ql/src/semmle/code/cpp/exprs/BuiltInOperations.qll b/cpp/ql/src/semmle/code/cpp/exprs/BuiltInOperations.qll index 59ee8656106..de178b32ca8 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/BuiltInOperations.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/BuiltInOperations.qll @@ -2,18 +2,18 @@ import semmle.code.cpp.exprs.Expr /** * A C/C++ builtin operation. This is the root QL class encompassing - * built-in functionality. + * built-in operationality. */ abstract class BuiltInOperation extends Expr { override string getCanonicalQLClass() { result = "BuiltInOperation" } } /** - * A C/C++ `__builtin_va_start` built-in function (used by some + * 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); + * __builtin_va_list ap; + * __builtin_va_start(ap, last_named_param); * ``` */ class BuiltInVarArgsStart extends BuiltInOperation, @vastartexpr { @@ -23,13 +23,13 @@ class BuiltInVarArgsStart extends BuiltInOperation, @vastartexpr { } /** - * A C/C++ `__builtin_va_end` built-in function (used by some implementations + * 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" } @@ -38,7 +38,7 @@ class BuiltInVarArgsEnd extends BuiltInOperation, @vaendexpr { } /** - * A C/C++ `__builtin_va_arg` built-in function (used by some implementations + * A C/C++ `__builtin_va_arg` built-in operation (used by some implementations * of `va_arg`). * ``` * ap = __builtin_va_arg(ap, long); @@ -51,7 +51,7 @@ class BuiltInVarArg extends BuiltInOperation, @vaargexpr { } /** - * A C/C++ `__builtin_va_copy` built-in function (used by some implementations + * A C/C++ `__builtin_va_copy` built-in operation (used by some implementations * of `va_copy`). * ``` * va_list ap, aq; @@ -78,7 +78,7 @@ class BuiltInNoOp extends BuiltInOperation, @noopexpr { } /** - * A C++ `__offsetof` built-in function (used by some implementations + * A C++ `__offsetof` built-in operation (used by some implementations * of `offsetof` in the presence of user-defined `operator &`). * * It computes the offset (in bytes) of data member `m` from the beginning @@ -110,7 +110,7 @@ class BuiltInIntAddr extends BuiltInOperation, @intaddrexpr { } /** - * A C++ `__has_assign` built-in function (used by some implementations of + * A C++ `__has_assign` built-in operation (used by some implementations of * the `` header). * * Returns `true` if the type has a copy assignment operator. @@ -125,7 +125,7 @@ class BuiltInOperationHasAssign extends BuiltInOperation, @hasassignexpr { } /** - * A C++ `__has_copy` built-in function (used by some implementations of the + * A C++ `__has_copy` built-in operation (used by some implementations of the * `` header). * * Returns `true` if the type has a copy constructor. @@ -140,7 +140,7 @@ class BuiltInOperationHasCopy extends BuiltInOperation, @hascopyexpr { } /** - * A C++ `__has_nothrow_assign` built-in function (used by some + * A C++ `__has_nothrow_assign` built-in operation (used by some * implementations of the `` header). * * Returns `true` if a copy assignment operator has an empty exception @@ -156,7 +156,7 @@ class BuiltInOperationHasNoThrowAssign extends BuiltInOperation, @hasnothrowassi } /** - * A C++ `__has_nothrow_constructor` built-in function (used by some + * A C++ `__has_nothrow_constructor` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the default constructor has an empty exception @@ -172,7 +172,7 @@ class BuiltInOperationHasNoThrowConstructor extends BuiltInOperation, @hasnothro } /** - * A C++ `__has_nothrow_copy` built-in function (used by some implementations + * A C++ `__has_nothrow_copy` built-in operation (used by some implementations * of the `` header). * * Returns `true` if the copy constructor has an empty exception specification. @@ -187,7 +187,7 @@ class BuiltInOperationHasNoThrowCopy extends BuiltInOperation, @hasnothrowcopy { } /** - * A C++ `__has_trivial_assign` built-in function (used by some implementations + * A C++ `__has_trivial_assign` built-in operation (used by some implementations * of the `` header). * * Returns `true` if the type has a trivial (compiler-generated) assignment @@ -203,7 +203,7 @@ class BuiltInOperationHasTrivialAssign extends BuiltInOperation, @hastrivialassi } /** - * A C++ `__has_trivial_constructor` built-in function (used by some + * A C++ `__has_trivial_constructor` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the type has a trivial (compiler-generated) constructor. @@ -218,7 +218,7 @@ class BuiltInOperationHasTrivialConstructor extends BuiltInOperation, @hastrivia } /** - * A C++ `__has_trivial_copy` built-in function (used by some implementations + * A C++ `__has_trivial_copy` built-in operation (used by some implementations * of the `` header). * * Returns true if the type has a trivial (compiler-generated) copy constructor. @@ -233,7 +233,7 @@ class BuiltInOperationHasTrivialCopy extends BuiltInOperation, @hastrivialcopy { } /** - * A C++ `__has_trivial_destructor` built-in function (used by some + * A C++ `__has_trivial_destructor` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the type has a trivial (compiler-generated) destructor. @@ -248,7 +248,7 @@ class BuiltInOperationHasTrivialDestructor extends BuiltInOperation, @hastrivial } /** - * A C++ `__has_user_destructor` built-in function (used by some + * A C++ `__has_user_destructor` built-in operation (used by some * implementations of the `` header). * * Returns true if the type has a user-declared destructor. @@ -263,7 +263,7 @@ class BuiltInOperationHasUserDestructor extends BuiltInOperation, @hasuserdestr } /** - * A C++ `__has_virtual_destructor` built-in function (used by some + * A C++ `__has_virtual_destructor` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the type has a virtual destructor. @@ -281,7 +281,7 @@ class BuiltInOperationHasVirtualDestructor extends BuiltInOperation, @hasvirtual } /** - * A C++ `__is_abstract` built-in function (used by some implementations of the + * A C++ `__is_abstract` built-in operation (used by some implementations of the * `` header). * * Returns `true` if the class has at least one pure virtual function. @@ -296,7 +296,7 @@ class BuiltInOperationIsAbstract extends BuiltInOperation, @isabstractexpr { } /** - * A C++ `__is_base_of` built-in function (used by some implementations of the + * A C++ `__is_base_of` built-in operation (used by some implementations of the * `` header). * * Returns `true` if the first type is a base class of the second type, of if both types are the same. @@ -311,7 +311,7 @@ class BuiltInOperationIsBaseOf extends BuiltInOperation, @isbaseofexpr { } /** - * A C++ `__is_class` built-in function (used by some implementations of the + * A C++ `__is_class` built-in operation (used by some implementations of the * `` header). * * Returns `true` if the type is a `class` or a `struct`. @@ -326,7 +326,7 @@ class BuiltInOperationIsClass extends BuiltInOperation, @isclassexpr { } /** - * A C++ `__is_convertible_to` built-in function (used by some implementations + * A C++ `__is_convertible_to` built-in operation (used by some implementations * of the `` header). * * Returns `true` if the first type can be converted to the second type. @@ -341,7 +341,7 @@ class BuiltInOperationIsConvertibleTo extends BuiltInOperation, @isconvtoexpr { } /** - * A C++ `__is_empty` built-in function (used by some implementations of the + * A C++ `__is_empty` built-in operation (used by some implementations of the * `` header). * * Returns `true` if the type has no instance data members. @@ -356,7 +356,7 @@ class BuiltInOperationIsEmpty extends BuiltInOperation, @isemptyexpr { } /** - * A C++ `__is_enum` built-in function (used by some implementations of the + * A C++ `__is_enum` built-in operation (used by some implementations of the * `` header). * * Returns true if the type is an `enum`. @@ -371,12 +371,12 @@ class BuiltInOperationIsEnum extends BuiltInOperation, @isenumexpr { } /** - * A C++ `__is_pod` built-in function (used by some implementations of the + * A C++ `__is_pod` built-in operation (used by some implementations of the * `` 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. + * classes, or (4) virtual functions. * ``` * bool v = __is_pod(MyType); * ``` @@ -388,7 +388,7 @@ class BuiltInOperationIsPod extends BuiltInOperation, @ispodexpr { } /** - * A C++ `__is_polymorphic` built-in function (used by some implementations + * A C++ `__is_polymorphic` built-in operation (used by some implementations * of the `` header). * * Returns `true` if the type has at least one virtual function. @@ -403,7 +403,7 @@ class BuiltInOperationIsPolymorphic extends BuiltInOperation, @ispolyexpr { } /** - * A C++ `__is_union` built-in function (used by some implementations of the + * A C++ `__is_union` built-in operation (used by some implementations of the * `` header). * * Returns `true` if the type is a `union`. @@ -423,7 +423,7 @@ class BuiltInOperationIsUnion extends BuiltInOperation, @isunionexpr { deprecated class BuiltInOperationBuiltInTypes = BuiltInOperationBuiltInTypesCompatibleP; /** - * A C++ `__builtin_types_compatible_p` built-in function (used by some + * A C++ `__builtin_types_compatible_p` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the two types are the same (modulo qualifiers). @@ -501,7 +501,7 @@ class BuiltInOperationBuiltInAddressOf extends UnaryOperation, BuiltInOperation, } /** - * The `__is_trivially_constructible` built-in function (used by some + * The `__is_trivially_constructible` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the type has a trivial (compiler-generated) default @@ -521,7 +521,7 @@ class BuiltInOperationIsTriviallyConstructible extends BuiltInOperation, } /** - * The `__is_destructible` built-in function (used by some implementations + * The `__is_destructible` built-in operation (used by some implementations * of the `` header). * * Returns `true` if the type's destructor is not `delete`d and is accessible @@ -538,7 +538,7 @@ class BuiltInOperationIsDestructible extends BuiltInOperation, @isdestructibleex } /** - * The `__is_nothrow_destructible` built-in function (used by some + * The `__is_nothrow_destructible` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the type is destructible and whose constructor, and those @@ -555,7 +555,7 @@ class BuiltInOperationIsNothrowDestructible extends BuiltInOperation, @isnothrow } /** - * The `__is_trivially_destructible` built-in function (used by some + * The `__is_trivially_destructible` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the type is destructible and whose constructor, and those @@ -571,7 +571,7 @@ class BuiltInOperationIsTriviallyDestructible extends BuiltInOperation, @istrivi } /** - * The `__is_trivially_assignable` built-in function (used by some + * The `__is_trivially_assignable` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the assignment operator `C::operator =(const C& c)` is @@ -591,7 +591,7 @@ class BuiltInOperationIsTriviallyAssignable extends BuiltInOperation, @istrivial } /** - * The `__is_nothrow_assignable` built-in function (used by some + * The `__is_nothrow_assignable` built-in operation (used by some * implementations of the `` header). * * Returns true if there exists a `C::operator =(const C& c) nothrow` @@ -607,7 +607,7 @@ class BuiltInOperationIsNothrowAssignable extends BuiltInOperation, @isnothrowas } /** - * The `__is_standard_layout` built-in function (used by some implementations + * The `__is_standard_layout` built-in operation (used by some implementations * of the `` header). * * Returns `true` if the type is a primitive type, or a `class`, `struct` or @@ -627,7 +627,7 @@ class BuiltInOperationIsStandardLayout extends BuiltInOperation, @isstandardlayo } /** - * The `__is_trivially_copyable` built-in function (used by some + * The `__is_trivially_copyable` built-in operation (used by some * implementations of the `` header). * * Returns `true` if instances of this type can be copied by trivial (compiler- @@ -641,7 +641,7 @@ class BuiltInOperationIsTriviallyCopyable extends BuiltInOperation, @istrivially } /** - * The `__is_literal_type` built-in function (used by some implementations of + * The `__is_literal_type` built-in operation (used by some implementations of * the `` header). * * Returns `true` if the type is a scalar type, a reference type or an array of @@ -661,7 +661,7 @@ class BuiltInOperationIsLiteralType extends BuiltInOperation, @isliteraltypeexpr } /** - * The `__has_trivial_move_constructor` built-in function (used by some + * The `__has_trivial_move_constructor` built-in operation (used by some * implementations of the `` header). * * Returns true if the move (`&&`) constructor can be generated by the @@ -679,7 +679,7 @@ class BuiltInOperationHasTrivialMoveConstructor extends BuiltInOperation, } /** - * The `__has_trivial_move_assign` built-in function (used by some + * The `__has_trivial_move_assign` built-in operation (used by some * implementations of the `` header). * * Returns if the move-assign operator `C::operator =(C &&c)` is trivial @@ -698,7 +698,7 @@ class BuiltInOperationHasTrivialMoveAssign extends BuiltInOperation, @hastrivial } /** - * The `__has_nothrow_move_assign` built-in function (used by some + * The `__has_nothrow_move_assign` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the type has a `C::operator=(C&& c) nothrow`, that is, @@ -714,7 +714,7 @@ class BuiltInOperationHasNothrowMoveAssign extends BuiltInOperation, @hasnothrow } /** - * The `__is_constructible` built-in function (used by some implementations + * The `__is_constructible` built-in operation (used by some implementations * of the `` header). * * Returns `true` if the type can be constructed using specified arguments @@ -733,7 +733,7 @@ class BuiltInOperationIsConstructible extends BuiltInOperation, @isconstructible } /** - * The `__is_nothrow_constructible` built-in function (used by some + * The `__is_nothrow_constructible` built-in operation (used by some * implementations of the `` header). * * Returns `true` if the type is constructable and all its constructors have an @@ -749,7 +749,7 @@ class BuiltInOperationIsNothrowConstructible extends BuiltInOperation, @isnothro } /** - * The `__has_finalizer` built-in function. This is a Microsoft extension. + * 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. @@ -764,7 +764,7 @@ class BuiltInOperationHasFinalizer extends BuiltInOperation, @hasfinalizerexpr { } /** - * The `__is_delegate` built-in function. This is a Microsoft extension. + * 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 @@ -778,7 +778,7 @@ class BuiltInOperationIsDelegate extends BuiltInOperation, @isdelegateexpr { } /** - * The `__is_interface_class` built-in function. This is a Microsoft extension. + * 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 @@ -791,7 +791,7 @@ class BuiltInOperationIsInterfaceClass extends BuiltInOperation, @isinterfacecla } /** - * The `__is_ref_array` built-in function. This is a Microsoft extension. + * 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 @@ -808,7 +808,7 @@ class BuiltInOperationIsRefArray extends BuiltInOperation, @isrefarrayexpr { } /** - * The `__is_ref_class` built-in function. This is a Microsoft extension. + * 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 @@ -825,7 +825,7 @@ class BuiltInOperationIsRefClass extends BuiltInOperation, @isrefclassexpr { } /** - * The `__is_sealed` built-in function. This is a Microsoft extension. + * 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 @@ -843,7 +843,7 @@ class BuiltInOperationIsSealed extends BuiltInOperation, @issealedexpr { } /** - * The `__is_simple_value_class` built-in function. This is a Microsoft extension. + * 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. @@ -862,7 +862,7 @@ class BuiltInOperationIsSimpleValueClass extends BuiltInOperation, @issimplevalu } /** - * The `__is_value_class` built-in function. This is a Microsoft extension. + * 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 @@ -879,7 +879,7 @@ class BuiltInOperationIsValueClass extends BuiltInOperation, @isvalueclassexpr { } /** - * The `__is_final` built-in function (used by some implementations of the + * The `__is_final` built-in operation (used by some implementations of the * `` header). * * Returns `true` if the `class` has been marked with the `final` specifier. @@ -913,6 +913,14 @@ class BuiltInChooseExpr extends BuiltInOperation, @builtinchooseexpr { /** * 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)" } diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Call.qll b/cpp/ql/src/semmle/code/cpp/exprs/Call.qll index 1ee216ca63c..62db9e29949 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Call.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Call.qll @@ -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. */ @@ -387,7 +402,7 @@ class VariableCall extends ExprCall { /** * A call to a constructor. * ``` - * struct S { S(void); } + * struct S { S(void) {} }; * S s; * ``` */ @@ -401,7 +416,7 @@ class ConstructorCall extends FunctionCall { } /** - * A C++ `throw` expression. + * A C++ `throw` expression. * ``` * throw Exc(2); * ``` @@ -437,11 +452,8 @@ class ReThrowExpr extends ThrowExpr { /** * A call to a destructor. * ``` - struct S { ~S(void); }; - void foo() { - S s; - s.~S(); - } + * struct S { ~S(void) {} } *s; + * s->~S(); * ``` */ class DestructorCall extends FunctionCall { @@ -479,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" } @@ -495,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" } @@ -506,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" } @@ -514,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" } @@ -522,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. */ @@ -563,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" } @@ -574,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" } @@ -582,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. */ diff --git a/cpp/ql/src/semmle/code/cpp/exprs/Cast.qll b/cpp/ql/src/semmle/code/cpp/exprs/Cast.qll index df34515bd46..1c16889b23d 100644 --- a/cpp/ql/src/semmle/code/cpp/exprs/Cast.qll +++ b/cpp/ql/src/semmle/code/cpp/exprs/Cast.qll @@ -22,17 +22,20 @@ 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`, + * There are two groups of subtypes of **Cast**. The first group differentiates + * between the different cast syntax forms, e.g. **CStyleCast**, **StaticCast**, * etc. The second group differentiates between the semantic operation being - * performed by the cast, e.g. `IntegralConversion`, `PointerBaseClassConversion`, + * performed by the cast, e.g. **IntegralConversion**, **PointerBaseClassConversion**, * etc. * The two groups are largely orthogonal to one another. For example, a - * 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`. + * 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 { /** @@ -44,7 +47,7 @@ abstract class Cast extends Conversion, @cast { /** * INTERNAL: Do not use. - * Query predicates used to check invariants that should hold for all `Cast` + * Query predicates used to check invariants that should hold for all **Cast** * nodes. To run all sanity queries for the ASTs, including the ones below, * run "semmle/code/cpp/ASTSanity.ql". */ @@ -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(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(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(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,10 +261,16 @@ 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 - * `DerivedClassConversion`. + * casts between base and derived classes, please see see **BaseClassConversion** or + * **DerivedClassConversion**. */ class PointerConversion extends Cast { PointerConversion() { @@ -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(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. */