Skip to content

Commit bb51313

Browse files
committed
[BoundsSafety][NFC] Simplify the interface of
`BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy` Previously the interface took a std::function<std::string>. The rationale behind this was to prevent callers from always allocating and computing a `std::string`. While trying to upstream this code (rdar://133600117) (llvm#106321) it was pointed out that there might be a simpler way to implement this. This patch instead has callers pass * a `ValueDecl*` pointer. In the cases where this isn't known (currently return values and unnamed parameters) this can be set to nullptr * a boolean flag stating whether or not the `ValueDecl*` should be fully qualified when printed. This avoids needing to pass a `std::function` and also avoids `std::string` unnecessary allocation. rdar://142544708
1 parent aef1dbe commit bb51313

File tree

4 files changed

+55
-48
lines changed

4 files changed

+55
-48
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2228,16 +2228,18 @@ class Sema final : public SemaBase {
22282228
/// \param RHSExpr The expression being assigned from.
22292229
/// \param Action The type assignment being performed
22302230
/// \param Loc The SourceLocation to use for error diagnostics
2231-
/// \param ComputeAssignee If provided this function will be called before
2232-
/// emitting a diagnostic. The function should return the name of
2233-
/// entity being assigned to or an empty string if this cannot be
2234-
/// determined.
2231+
/// \param Assignee The ValueDecl being assigned. This is used to compute
2232+
/// the name of the assignee. If the assignee isn't known this can
2233+
/// be set to nullptr.
2234+
/// \param ShowFullyQualifiedAssigneeName If set to true when using \p
2235+
/// Assignee to compute the name of the assignee use the fully
2236+
/// qualified name, otherwise use the unqualified name.
22352237
///
22362238
/// \returns True iff no diagnostic where emitted, false otherwise.
22372239
bool BoundsSafetyCheckAssignmentToCountAttrPtr(
22382240
QualType LHSTy, Expr *RHSExpr, AssignmentAction Action,
2239-
SourceLocation Loc,
2240-
std::function<std::string()> ComputeAssignee = nullptr);
2241+
SourceLocation Loc, const ValueDecl *Assignee,
2242+
bool ShowFullyQualifiedAssigneeName);
22412243

22422244
/// Perform Checks for assigning to a `__counted_by` or
22432245
/// `__counted_by_or_null` pointer type \param LHSTy where the pointee type
@@ -2248,15 +2250,18 @@ class Sema final : public SemaBase {
22482250
/// \param RHSExpr The expression being assigned from.
22492251
/// \param Action The type assignment being performed
22502252
/// \param Loc The SourceLocation to use for error diagnostics
2251-
/// \param ComputeAssignee If provided this function will be called before
2252-
/// emitting a diagnostic. The function should return the name of
2253-
/// entity being assigned to or an empty string if this cannot be
2254-
/// determined.
2253+
/// \param Assignee The ValueDecl being assigned. This is used to compute
2254+
/// the name of the assignee. If the assignee isn't known this can
2255+
/// be set to nullptr.
2256+
/// \param ShowFullyQualifiedAssigneeName If set to true when using \p
2257+
/// Assignee to compute the name of the assignee use the fully
2258+
/// qualified name, otherwise use the unqualified name.
22552259
///
22562260
/// \returns True iff no diagnostic where emitted, false otherwise.
22572261
bool BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy(
22582262
QualType LHSTy, Expr *RHSExpr, AssignmentAction Action,
2259-
SourceLocation Loc, std::function<std::string()> ComputeAssignee);
2263+
SourceLocation Loc, const ValueDecl *Assignee,
2264+
bool ShowFullyQualifiedAssigneeName);
22602265

22612266
/// Perform Bounds Safety Semantic checks for initializing a Bounds Safety
22622267
/// pointer.

clang/lib/Sema/SemaBoundsSafety.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,8 @@ HasCountedByAttrOnIncompletePointee(QualType Ty, NamedDecl **ND,
463463
}
464464

465465
bool Sema::BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy(
466-
QualType LHSTy, Expr *RHSExpr, AssignmentAction Action,
467-
SourceLocation Loc, std::function<std::string()> ComputeAssignee) {
466+
QualType LHSTy, Expr *RHSExpr, AssignmentAction Action, SourceLocation Loc,
467+
const ValueDecl *Assignee, bool ShowFullyQualifiedAssigneeName) {
468468
NamedDecl *IncompleteTyDecl = nullptr;
469469
const CountAttributedType *CATy = nullptr;
470470
QualType PointeeTy;
@@ -481,13 +481,20 @@ bool Sema::BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy(
481481
Action != AssignmentAction::Casting &&
482482
Action != AssignmentAction::Passing_CFAudited);
483483

484-
// By having users provide a function we only pay the cost of allocation the
485-
// string and computing when a diagnostic is emitted.
486-
std::string Assignee = ComputeAssignee ? ComputeAssignee() : "";
484+
std::string AssigneeStr;
485+
if (Assignee) {
486+
if (ShowFullyQualifiedAssigneeName) {
487+
AssigneeStr = Assignee->getQualifiedNameAsString();
488+
} else {
489+
AssigneeStr = Assignee->getNameAsString();
490+
}
491+
}
487492
{
488493
auto D =
489-
Diag(Loc, diag::err_bounds_safety_counted_by_on_incomplete_type_on_assign)
490-
<< /*0*/ (int)Action << /*1*/ Assignee << /*2*/ (Assignee.size() > 0)
494+
Diag(Loc,
495+
diag::err_bounds_safety_counted_by_on_incomplete_type_on_assign)
496+
<< /*0*/ (int)Action << /*1*/ AssigneeStr
497+
<< /*2*/ (AssigneeStr.size() > 0)
491498
<< /*3*/ isa<ImplicitValueInitExpr>(RHSExpr) << /*4*/ LHSTy
492499
<< /*5*/ CATy->GetAttributeName(/*WithMacroPrefix=*/true)
493500
<< /*6*/ PointeeTy << /*7*/ CATy->isOrNull();
@@ -501,13 +508,13 @@ bool Sema::BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy(
501508
}
502509

503510
bool Sema::BoundsSafetyCheckAssignmentToCountAttrPtr(
504-
QualType LHSTy, Expr *RHSExpr, AssignmentAction Action,
505-
SourceLocation Loc, std::function<std::string()> ComputeAssignee) {
511+
QualType LHSTy, Expr *RHSExpr, AssignmentAction Action, SourceLocation Loc,
512+
const ValueDecl *Assignee, bool ShowFullyQualifiedAssigneeName) {
506513
if (!getLangOpts().hasBoundsSafety())
507514
return true;
508515

509516
return BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy(
510-
LHSTy, RHSExpr, Action, Loc, ComputeAssignee);
517+
LHSTy, RHSExpr, Action, Loc, Assignee, ShowFullyQualifiedAssigneeName);
511518
}
512519

513520
bool Sema::BoundsSafetyCheckInitialization(const InitializedEntity &Entity,
@@ -531,13 +538,10 @@ bool Sema::BoundsSafetyCheckInitialization(const InitializedEntity &Entity,
531538
Entity.getKind() != InitializedEntity::EK_Variable) {
532539

533540
if (!BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy(
534-
LHSType, RHSExpr, Action, SL, [&Entity]() -> std::string {
535-
if (const auto *VD =
536-
dyn_cast_or_null<ValueDecl>(Entity.getDecl())) {
537-
return VD->getQualifiedNameAsString();
538-
}
539-
return "";
540-
})) {
541+
LHSType, RHSExpr, Action, SL,
542+
dyn_cast_or_null<ValueDecl>(Entity.getDecl()),
543+
/*ShowFullQualifiedAssigneeName=*/true)) {
544+
541545
ChecksPassed = false;
542546

543547
// It's not necessarily bad if this assert fails but we should catch
@@ -629,13 +633,12 @@ bool Sema::BoundsSafetyCheckResolvedCall(FunctionDecl *FDecl, CallExpr *Call,
629633

630634
for (size_t ArgIdx = 0; ArgIdx < MinNumArgs; ++ArgIdx) {
631635
Expr *CallArg = Call->getArg(ArgIdx); // FIXME: IgnoreImpCast()?
632-
StringRef ParamName;
636+
const ValueDecl *ParamVarDecl = nullptr;
633637
QualType ParamTy;
634638
if (FDecl) {
635639
// Direct call
636-
auto *ParamVarDecl = FDecl->getParamDecl(ArgIdx);
640+
ParamVarDecl = FDecl->getParamDecl(ArgIdx);
637641
ParamTy = ParamVarDecl->getType();
638-
ParamName = ParamVarDecl->getName();
639642
} else {
640643
// Indirect call. The parameter name isn't known
641644
ParamTy = ProtoType->getParamType(ArgIdx);
@@ -644,7 +647,7 @@ bool Sema::BoundsSafetyCheckResolvedCall(FunctionDecl *FDecl, CallExpr *Call,
644647
// Assigning to the parameter type is treated as a "use" of the type.
645648
if (!BoundsSafetyCheckAssignmentToCountAttrPtr(
646649
ParamTy, CallArg, AssignmentAction::Passing, CallArg->getBeginLoc(),
647-
[&ParamName]() { return ParamName.str(); }))
650+
ParamVarDecl, /*ShowFullQualifiedAssigneeName=*/false))
648651
ChecksPassed = false;
649652
}
650653
return ChecksPassed;

clang/lib/Sema/SemaChecking.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9503,8 +9503,8 @@ Sema::CheckReturnValExpr(Expr *RetValExp, QualType lhsType,
95039503

95049504
/* TO_UPSTREAM(BoundsSafety) ON*/
95059505
BoundsSafetyCheckAssignmentToCountAttrPtr(
9506-
lhsType, RetValExp, AssignmentAction::Returning,
9507-
RetValExp->getBeginLoc());
9506+
lhsType, RetValExp, AssignmentAction::Returning, RetValExp->getBeginLoc(),
9507+
/*Assignee=*/nullptr, /*ShowFullQualifiedAssigneeName=*/false);
95089508

95099509
// For a count-attributed return type, its dependent count variables can be
95109510
// assigned in arbitrary places. Don't try to find the assigned values, just

clang/lib/Sema/SemaExpr.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16730,20 +16730,19 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS,
1673016730
// Even if this check fails don't return early to allow the best
1673116731
// possible error recovery and to allow any subsequent diagnostics to
1673216732
// work.
16733+
const ValueDecl *Assignee = nullptr;
16734+
bool ShowFullyQualifiedAssigneeName = false;
16735+
// In simple cases describe what is being assigned to
16736+
if (auto *DR = dyn_cast<DeclRefExpr>(LHSExpr->IgnoreParenCasts())) {
16737+
Assignee = DR->getDecl();
16738+
} else if (auto *ME = dyn_cast<MemberExpr>(LHSExpr->IgnoreParenCasts())) {
16739+
Assignee = ME->getMemberDecl();
16740+
ShowFullyQualifiedAssigneeName = true;
16741+
}
16742+
1673316743
(void)BoundsSafetyCheckAssignmentToCountAttrPtr(
16734-
LHSType, RHS.get(), AssignmentAction::Assigning, Loc,
16735-
[&LHSExpr]() -> std::string {
16736-
// In simple cases describe what is being assigned to
16737-
if (auto *DR = dyn_cast<DeclRefExpr>(LHSExpr->IgnoreParenCasts())) {
16738-
auto *II = DR->getDecl()->getDeclName().getAsIdentifierInfo();
16739-
if (II)
16740-
return II->getName().str();
16741-
} else if (auto *ME =
16742-
dyn_cast<MemberExpr>(LHSExpr->IgnoreParenCasts())) {
16743-
return ME->getMemberDecl()->getQualifiedNameAsString();
16744-
}
16745-
return "";
16746-
});
16744+
LHSType, RHS.get(), AssignmentAction::Assigning, Loc, Assignee,
16745+
ShowFullyQualifiedAssigneeName);
1674716746
}
1674816747
/* TO_UPSTREAM(BoundsSafety) OFF */
1674916748

@@ -26280,4 +26279,4 @@ ExprResult Sema::ActOnUnsafeTerminatedByFromIndexable(
2628026279
PointerToTerminatorExpr, BuiltinLoc,
2628126280
RParenLoc);
2628226281
}
26283-
/* TO_UPSTREAM(BoundsSafety) OFF*/
26282+
/* TO_UPSTREAM(BoundsSafety) OFF*/

0 commit comments

Comments
 (0)