mirror of
https://github.com/github/codeql.git
synced 2025-12-23 12:16:33 +01:00
This PR separates the core cpp packs into `codeql/cpp-queries` and `codeql/cpp-all`. There are very few lines of code changed. Almost all changes are moving files around.
132 lines
3.7 KiB
Plaintext
132 lines
3.7 KiB
Plaintext
/**
|
|
* Provides classes for modeling logical operations such as `!`, `&&`, `||`, and
|
|
* the ternary `? :` expression.
|
|
*/
|
|
|
|
import semmle.code.cpp.exprs.Expr
|
|
|
|
/**
|
|
* A C/C++ unary logical operation.
|
|
*/
|
|
class UnaryLogicalOperation extends UnaryOperation, @un_log_op_expr { }
|
|
|
|
/**
|
|
* A C/C++ logical not expression.
|
|
* ```
|
|
* c = !a;
|
|
* ```
|
|
*/
|
|
class NotExpr extends UnaryLogicalOperation, @notexpr {
|
|
override string getOperator() { result = "!" }
|
|
|
|
override string getAPrimaryQlClass() { result = "NotExpr" }
|
|
|
|
override int getPrecedence() { result = 16 }
|
|
}
|
|
|
|
/**
|
|
* A C/C++ binary logical operation.
|
|
*/
|
|
class BinaryLogicalOperation extends BinaryOperation, @bin_log_op_expr {
|
|
/**
|
|
* Holds if the truth of this binary logical expression having value `wholeIsTrue`
|
|
* implies that the truth of the child expression `part` has truth value `partIsTrue`.
|
|
*
|
|
* For example if the binary operation:
|
|
* ```
|
|
* x && y
|
|
* ```
|
|
* is true, `x` and `y` must also be true, so `impliesValue(x, true, true)` and
|
|
* `impliesValue(y, true, true)` hold.
|
|
*/
|
|
predicate impliesValue(Expr part, boolean partIsTrue, boolean wholeIsTrue) { none() } // overridden in subclasses
|
|
}
|
|
|
|
/**
|
|
* A C/C++ logical AND expression.
|
|
* ```
|
|
* if (a && b) { }
|
|
* ```
|
|
*/
|
|
class LogicalAndExpr extends BinaryLogicalOperation, @andlogicalexpr {
|
|
override string getOperator() { result = "&&" }
|
|
|
|
override string getAPrimaryQlClass() { result = "LogicalAndExpr" }
|
|
|
|
override int getPrecedence() { result = 5 }
|
|
|
|
override predicate impliesValue(Expr part, boolean partIsTrue, boolean wholeIsTrue) {
|
|
wholeIsTrue = true and partIsTrue = true and part = this.getAnOperand()
|
|
or
|
|
wholeIsTrue = true and
|
|
this.getAnOperand().(BinaryLogicalOperation).impliesValue(part, partIsTrue, true)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A C/C++ logical OR expression.
|
|
* ```
|
|
* if (a || b) { }
|
|
* ```
|
|
*/
|
|
class LogicalOrExpr extends BinaryLogicalOperation, @orlogicalexpr {
|
|
override string getOperator() { result = "||" }
|
|
|
|
override string getAPrimaryQlClass() { result = "LogicalOrExpr" }
|
|
|
|
override int getPrecedence() { result = 4 }
|
|
|
|
override predicate impliesValue(Expr part, boolean partIsTrue, boolean wholeIsTrue) {
|
|
wholeIsTrue = false and partIsTrue = false and part = this.getAnOperand()
|
|
or
|
|
wholeIsTrue = false and
|
|
this.getAnOperand().(BinaryLogicalOperation).impliesValue(part, partIsTrue, false)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* A C/C++ conditional ternary expression.
|
|
* ```
|
|
* a = (b > c ? d : e);
|
|
* ```
|
|
*/
|
|
class ConditionalExpr extends Operation, @conditionalexpr {
|
|
/** Gets the condition of this conditional expression. */
|
|
Expr getCondition() { expr_cond_guard(underlyingElement(this), unresolveElement(result)) }
|
|
|
|
override string getAPrimaryQlClass() { result = "ConditionalExpr" }
|
|
|
|
/** Gets the 'then' expression of this conditional expression. */
|
|
Expr getThen() {
|
|
if this.isTwoOperand()
|
|
then result = this.getCondition()
|
|
else expr_cond_true(underlyingElement(this), unresolveElement(result))
|
|
}
|
|
|
|
/** Gets the 'else' expression of this conditional expression. */
|
|
Expr getElse() { expr_cond_false(underlyingElement(this), unresolveElement(result)) }
|
|
|
|
/**
|
|
* Holds if this expression used the two operand form `guard ? : false`.
|
|
*/
|
|
predicate isTwoOperand() { expr_cond_two_operand(underlyingElement(this)) }
|
|
|
|
override string getOperator() { result = "?" }
|
|
|
|
override string toString() { result = "... ? ... : ..." }
|
|
|
|
override int getPrecedence() { result = 3 }
|
|
|
|
override predicate mayBeImpure() {
|
|
this.getCondition().mayBeImpure() or
|
|
this.getThen().mayBeImpure() or
|
|
this.getElse().mayBeImpure()
|
|
}
|
|
|
|
override predicate mayBeGloballyImpure() {
|
|
this.getCondition().mayBeGloballyImpure() or
|
|
this.getThen().mayBeGloballyImpure() or
|
|
this.getElse().mayBeGloballyImpure()
|
|
}
|
|
}
|