Files
codeql/cpp/ql/lib/semmle/code/cpp/exprs/LogicalOperation.qll
Andrew Eisenberg 2c5dd2dfa3 Packaging: Refactor the cpp libraries
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.
2021-08-17 11:22:36 -07:00

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