Skip to content

Commit f70a6c8

Browse files
committed
[MC/DC] Handle __builtin_expect as if parenthses
Fixes #124565
1 parent a6d4be0 commit f70a6c8

File tree

4 files changed

+26
-9
lines changed

4 files changed

+26
-9
lines changed

clang/include/clang/AST/IgnoreExpr.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,15 @@ inline Expr *IgnoreElidableImplicitConstructorSingleStep(Expr *E) {
134134
return E;
135135
}
136136

137+
inline Expr *IgnoreBuiltinExpectSingleStep(Expr *E) {
138+
if (auto *CE = dyn_cast<CallExpr>(E)) {
139+
if (const FunctionDecl *FD = CE->getDirectCallee())
140+
if (FD->getBuiltinID() == Builtin::BI__builtin_expect)
141+
return CE->getArg(0);
142+
}
143+
return E;
144+
}
145+
137146
inline Expr *IgnoreImplicitAsWrittenSingleStep(Expr *E) {
138147
if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
139148
return ICE->getSubExprAsWritten();

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "clang/AST/Decl.h"
2828
#include "clang/AST/DeclCXX.h"
2929
#include "clang/AST/Expr.h"
30+
#include "clang/AST/IgnoreExpr.h"
3031
#include "clang/AST/StmtCXX.h"
3132
#include "clang/AST/StmtObjC.h"
3233
#include "clang/Basic/Builtins.h"
@@ -1748,12 +1749,14 @@ bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond,
17481749

17491750
/// Strip parentheses and simplistic logical-NOT operators.
17501751
const Expr *CodeGenFunction::stripCond(const Expr *C) {
1751-
while (const UnaryOperator *Op = dyn_cast<UnaryOperator>(C->IgnoreParens())) {
1752-
if (Op->getOpcode() != UO_LNot)
1753-
break;
1754-
C = Op->getSubExpr();
1752+
while (true) {
1753+
const Expr *SC = IgnoreExprNodes(C, IgnoreParensSingleStep,
1754+
IgnoreBuiltinExpectSingleStep,
1755+
IgnoreImplicitCastsSingleStep);
1756+
if (C == SC)
1757+
return SC;
1758+
C = SC;
17551759
}
1756-
return C->IgnoreParens();
17571760
}
17581761

17591762
/// Determine whether the given condition is an instrumentable condition

clang/lib/CodeGen/CodeGenPGO.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,9 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
247247
}
248248

249249
if (const Expr *E = dyn_cast<Expr>(S)) {
250-
const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
251-
if (BinOp && BinOp->isLogicalOp()) {
250+
if (const auto *BinOp =
251+
dyn_cast<BinaryOperator>(CodeGenFunction::stripCond(E));
252+
BinOp && BinOp->isLogicalOp()) {
252253
/// Check for "split-nested" logical operators. This happens when a new
253254
/// boolean expression logical-op nest is encountered within an existing
254255
/// boolean expression, separated by a non-logical operator. For
@@ -280,7 +281,8 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
280281
return true;
281282

282283
if (const Expr *E = dyn_cast<Expr>(S)) {
283-
const BinaryOperator *BinOp = dyn_cast<BinaryOperator>(E->IgnoreParens());
284+
const BinaryOperator *BinOp =
285+
dyn_cast<BinaryOperator>(CodeGenFunction::stripCond(E));
284286
if (BinOp && BinOp->isLogicalOp()) {
285287
assert(LogOpStack.back() == BinOp);
286288
LogOpStack.pop_back();

clang/test/CoverageMapping/mcdc-nested-expr.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,11 @@ bool func_condop(bool a, bool b, bool c) {
2121
// Treated as parentheses.
2222
// CHECK: func_expect{{.*}}:
2323
bool func_expect(bool a, bool b, bool c) {
24-
// WARN: :[[@LINE+1]]:10: warning: unsupported MC/DC boolean expression; contains an operation with a nested boolean expression.
2524
return a || __builtin_expect(b && c, true);
25+
// CHECK: Decision,File 0, [[@LINE-1]]:10 -> [[#L:@LINE-1]]:45 = M:4, C:3
26+
// CHECK: Branch,File 0, [[#L]]:10 -> [[#L]]:11 = (#0 - #1), #1 [1,0,2]
27+
// CHECK: Branch,File 0, [[#L]]:32 -> [[#L]]:33 = #2, (#1 - #2) [2,3,0]
28+
// CHECK: Branch,File 0, [[#L]]:37 -> [[#L]]:38 = #3, (#2 - #3) [3,0,0]
2629
}
2730

2831
// LNot among BinOp(s)

0 commit comments

Comments
 (0)