Skip to content

Commit 8b06b31

Browse files
authored
Merge pull request #668 from ian-semmle/condexpr
C++: Follow changes in how conditional expressions are represented in the database
2 parents 5452000 + 187fdf6 commit 8b06b31

File tree

6 files changed

+310
-129
lines changed

6 files changed

+310
-129
lines changed

cpp/ql/src/semmle/code/cpp/exprs/LogicalOperation.qll

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,28 @@ class LogicalOrExpr extends BinaryLogicalOperation, @orlogicalexpr {
6767
*/
6868
class ConditionalExpr extends Operation, @conditionalexpr {
6969
/** Gets the condition of this conditional expression. */
70-
Expr getCondition() { this.hasChild(result,0) }
70+
Expr getCondition() {
71+
expr_cond_guard(underlyingElement(this), unresolveElement(result))
72+
}
7173

7274
/** Gets the 'then' expression of this conditional expression. */
73-
Expr getThen() { this.hasChild(result,1) }
75+
Expr getThen() {
76+
if this.isTwoOperand()
77+
then result = this.getCondition()
78+
else expr_cond_true(underlyingElement(this), unresolveElement(result))
79+
}
7480

7581
/** Gets the 'else' expression of this conditional expression. */
76-
Expr getElse() { this.hasChild(result,2) }
82+
Expr getElse() {
83+
expr_cond_false(underlyingElement(this), unresolveElement(result))
84+
}
85+
86+
/**
87+
* Holds if this expression used the two operand form `guard ? : false`.
88+
*/
89+
predicate isTwoOperand() {
90+
expr_cond_two_operand(underlyingElement(this))
91+
}
7792

7893
override string getOperator() { result = "?" }
7994

cpp/ql/src/semmlecode.cpp.dbscheme

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1171,6 +1171,41 @@ expr_deallocator(
11711171
int form: int ref
11721172
);
11731173

1174+
/**
1175+
* Holds if the `@conditionalexpr` is of the two operand form
1176+
* `guard ? : false`.
1177+
*/
1178+
expr_cond_two_operand(
1179+
unique int cond: @conditionalexpr ref
1180+
);
1181+
1182+
/**
1183+
* The guard of `@conditionalexpr` `guard ? true : false`
1184+
*/
1185+
expr_cond_guard(
1186+
unique int cond: @conditionalexpr ref,
1187+
int guard: @expr ref
1188+
);
1189+
1190+
/**
1191+
* The expression used when the guard of `@conditionalexpr`
1192+
* `guard ? true : false` holds. For the two operand form
1193+
* `guard ?: false` consider using `expr_cond_guard` instead.
1194+
*/
1195+
expr_cond_true(
1196+
unique int cond: @conditionalexpr ref,
1197+
int true: @expr ref
1198+
);
1199+
1200+
/**
1201+
* The expression used when the guard of `@conditionalexpr`
1202+
* `guard ? true : false` does not hold.
1203+
*/
1204+
expr_cond_false(
1205+
unique int cond: @conditionalexpr ref,
1206+
int false: @expr ref
1207+
);
1208+
11741209
// the second field is a string representation of the value
11751210
// the third field is the actual text in the source or the same as the second field
11761211
values(

0 commit comments

Comments
 (0)