Skip to content

Commit ee9e2b6

Browse files
committed
Extract check for __builtin_counted_by_ref CallExpr into a helper method.
1 parent 74109c4 commit ee9e2b6

File tree

3 files changed

+22
-10
lines changed

3 files changed

+22
-10
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,6 +2518,11 @@ class Sema final : public SemaBase {
25182518

25192519
bool BuiltinNonDeterministicValue(CallExpr *TheCall);
25202520

2521+
bool IsBuiltinCountedByRef(const Expr *E) {
2522+
const CallExpr *CE = E ? dyn_cast<CallExpr>(E->IgnoreParenImpCasts())
2523+
: nullptr;
2524+
return CE && CE->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref;
2525+
}
25212526
bool BuiltinCountedByRef(CallExpr *TheCall);
25222527

25232528
// Matrix builtin handling.

clang/lib/Sema/SemaExpr.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4896,10 +4896,9 @@ ExprResult Sema::ActOnArraySubscriptExpr(Scope *S, Expr *base,
48964896

48974897
// We cannot use __builtin_counted_by_ref in a binary expression. It's
48984898
// possible to leak the reference and violate bounds security.
4899-
if (auto *CE = dyn_cast<CallExpr>(base->IgnoreParenImpCasts());
4900-
CE && CE->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref)
4901-
Diag(CE->getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
4902-
<< 0 << CE->getSourceRange();
4899+
if (IsBuiltinCountedByRef(base))
4900+
Diag(base->getExprLoc(), diag::err_builtin_counted_by_ref_invalid_use)
4901+
<< 0 << base->getSourceRange();
49034902

49044903
// Handle any non-overload placeholder types in the base and index
49054904
// expressions. We can't handle overloads here because the other
@@ -6493,6 +6492,16 @@ ExprResult Sema::BuildCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
64936492
if (CheckArgsForPlaceholders(ArgExprs))
64946493
return ExprError();
64956494

6495+
// The result of __builtin_counted_by_ref cannot be used as a function
6496+
// argument. It allows leaking and modification of bounds safety information.
6497+
for (const Expr *Arg : ArgExprs)
6498+
if (IsBuiltinCountedByRef(Arg)) {
6499+
Diag(Arg->getExprLoc(),
6500+
diag::err_builtin_counted_by_ref_cannot_leak_reference)
6501+
<< Arg->getSourceRange();
6502+
return ExprError();
6503+
}
6504+
64966505
if (getLangOpts().CPlusPlus) {
64976506
// If this is a pseudo-destructor expression, build the call immediately.
64986507
if (isa<CXXPseudoDestructorExpr>(Fn)) {
@@ -15216,8 +15225,7 @@ ExprResult Sema::ActOnBinOp(Scope *S, SourceLocation TokLoc,
1521615225
// We cannot use __builtin_counted_by_ref in a binary expression. It's
1521715226
// possible to leak the reference and violate bounds security.
1521815227
auto CheckBuiltinCountedByRef = [&](const Expr *E) {
15219-
if (const auto *CE = dyn_cast<CallExpr>(E->IgnoreParenImpCasts());
15220-
CE && CE->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref) {
15228+
if (IsBuiltinCountedByRef(E)) {
1522115229
if (BinaryOperator::isAssignmentOp(Opc))
1522215230
Diag(E->getExprLoc(),
1522315231
diag::err_builtin_counted_by_ref_cannot_leak_reference)

clang/lib/Sema/SemaStmt.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3765,11 +3765,10 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
37653765
<< FSI->getFirstCoroutineStmtKeyword();
37663766
}
37673767

3768-
if (const auto *CE = dyn_cast_if_present<CallExpr>(RetVal.get());
3769-
CE && CE->getBuiltinCallee() == Builtin::BI__builtin_counted_by_ref)
3770-
Diag(CE->getExprLoc(),
3768+
if (IsBuiltinCountedByRef(RetVal.get()))
3769+
Diag(RetVal.get()->getExprLoc(),
37713770
diag::err_builtin_counted_by_ref_cannot_leak_reference)
3772-
<< CE->getSourceRange();
3771+
<< RetVal.get()->getSourceRange();
37733772

37743773
StmtResult R =
37753774
BuildReturnStmt(ReturnLoc, RetVal.get(), /*AllowRecovery=*/true);

0 commit comments

Comments
 (0)