Skip to content

Commit c87bc75

Browse files
authored
[BoundsSafety] Delay processing of bounds attrs in templates (#9929)
* [BoundsSafety] Delay processing of bounds attrs in templates Dynamic bounds attributes do not handle value dependent arguments. To enable wider interop with C++ code bases we delay the processing of these attributes inside templated contexts. Instead we apply the new type while instantiating the function. One issue with this approach is that instantiation happens after parsing is finished, and the Scope information we use to prevent attributes from referring to arguments from outer scopes is only available during parsing. These diagnostics were emitted at the end of the type processing. In templated contexts we instead perform that analysis during parsing, and delay the rest of the processing. To avoid churn in unrelated tests the rest of the attributes keep their processing as is, until we've investigated what impact hoisting it would have on the user experience.
1 parent 48f0651 commit c87bc75

11 files changed

+976
-71
lines changed

clang/include/clang/Sema/Sema.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15509,7 +15509,8 @@ class Sema final : public SemaBase {
1550915509
AttributeCommonInfo::Kind Kind,
1551015510
Expr *AttrArg, SourceLocation Loc,
1551115511
SourceRange Range, StringRef DiagName,
15512-
bool OriginatesInAPINotes = false);
15512+
bool OriginatesInAPINotes = false,
15513+
bool InInstantiatedTemplate = false);
1551315514

1551415515
/// Perform Bounds Safety Semantic checks for assigning to a `__counted_by` or
1551515516
/// `__counted_by_or_null` pointer type \param LHSTy.

clang/lib/Sema/BoundsSafetySuggestions.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,6 +1594,10 @@ void UnsafeOperationVisitor::
15941594
Current = PE->getSubExpr();
15951595
continue;
15961596
}
1597+
if (const auto *BCE = dyn_cast<BoundsCheckExpr>(Current)) {
1598+
Current = BCE->getGuardedExpr();
1599+
continue;
1600+
}
15971601
if (const auto *CE = dyn_cast<CastExpr>(Current)) {
15981602
if (CE->getCastKind() == clang::CK_BoundsSafetyPointerCast) {
15991603
// Found a cast we might want to warn about.

clang/lib/Sema/DynamicCountPointerAssignmentAnalysis.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3484,6 +3484,9 @@ namespace clang {
34843484

34853485
void DynamicCountPointerAssignmentAnalysis::run() {
34863486
AnalysisDeclContext AC(/* AnalysisDeclContextManager */ nullptr, dcl);
3487+
if (dcl->isTemplated()) // delay processing until template has been
3488+
// instantiated
3489+
return;
34873490

34883491
CFG *cfg = AC.getCFG();
34893492
if (!cfg)

clang/lib/Sema/SemaDecl.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17302,6 +17302,11 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
1730217302
// the declaration context below. Otherwise, we're unable to transform
1730317303
// 'this' expressions when transforming immediate context functions.
1730417304

17305+
/*TO_UPSTREAM(BoundsSafety) ON*/
17306+
if (LangOpts.BoundsSafety)
17307+
DynamicCountPointerAssignmentAnalysis(*this, dcl).run();
17308+
/*TO_UPSTREAM(BoundsSafety) OFF*/
17309+
1730517310
if (!IsInstantiation)
1730617311
PopDeclContext();
1730717312

@@ -17325,11 +17330,6 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body,
1732517330
if (FD && !FD->isDeleted())
1732617331
checkTypeSupport(FD->getType(), FD->getLocation(), FD);
1732717332

17328-
/*TO_UPSTREAM(BoundsSafety) ON*/
17329-
if (LangOpts.BoundsSafety)
17330-
DynamicCountPointerAssignmentAnalysis(*this, dcl).run();
17331-
/*TO_UPSTREAM(BoundsSafety) OFF*/
17332-
1733317333
return dcl;
1733417334
}
1733517335

0 commit comments

Comments
 (0)