Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BoundsSafety] Delay processing of bounds attrs in templates #9929

Open
wants to merge 4 commits into
base: stable/20240723
Choose a base branch
from

Conversation

hnrklssn
Copy link

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.

@hnrklssn hnrklssn requested a review from a team as a code owner January 31, 2025 06:45
@hnrklssn
Copy link
Author

@swift-ci please test llvm
@swift-ci please smoke test

@hnrklssn hnrklssn added the clang:bounds-safety Issue relating to the experimental -fbounds-safety feature in Clang label Jan 31, 2025
@@ -3485,6 +3485,9 @@ namespace clang {

void DynamicCountPointerAssignmentAnalysis::run() {
AnalysisDeclContext AC(/* AnalysisDeclContextManager */ nullptr, dcl);
if (isa<TemplateDecl>(dcl)) // delay processing until template has been
// instantiated
return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does it work? Will DynamicCountPointerAssignmentAnalysis::run be called again when dcl is instantiated?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, a new function decl will be created for the instantiated version and all the normal analyses will be run over it

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this sufficient? We could have dependent expressions when the declaration itself is not templated:

  • Non-templated method of a templated struct referencing the template argument
  • Lambda inside a templated function referencing the template argument
  • Method of a non-templated struct nested inside a templated struct referencing the outer struct's template argument

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed to an isTemplated call instead

clang/lib/Sema/SemaDeclAttr.cpp Outdated Show resolved Hide resolved
clang/lib/Sema/SemaDeclAttr.cpp Outdated Show resolved Hide resolved
clang/lib/Sema/SemaExpr.cpp Show resolved Hide resolved
clang/lib/Sema/SemaDeclAttr.cpp Outdated Show resolved Hide resolved
@patrykstefanski
Copy link

CC @ziqingluo-90 since we were discussing templates recently.

@hnrklssn
Copy link
Author

hnrklssn commented Feb 1, 2025

@swift-ci please test

@hnrklssn
Copy link
Author

hnrklssn commented Feb 1, 2025

@swift-ci please test llvm

clang/lib/Sema/SemaDeclAttr.cpp Outdated Show resolved Hide resolved
clang/lib/Sema/SemaDeclAttr.cpp Outdated Show resolved Hide resolved
clang/lib/Sema/SemaDeclAttr.cpp Outdated Show resolved Hide resolved
clang/lib/Sema/SemaTemplateInstantiateDecl.cpp Outdated Show resolved Hide resolved
Copy link

@Xazax-hun Xazax-hun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure non-templated entities nested in templated entities are correctly handled, the very least we should have some tests for that. Added some examples of such cases inline.

@@ -3485,6 +3485,9 @@ namespace clang {

void DynamicCountPointerAssignmentAnalysis::run() {
AnalysisDeclContext AC(/* AnalysisDeclContextManager */ nullptr, dcl);
if (isa<TemplateDecl>(dcl)) // delay processing until template has been
// instantiated
return;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this sufficient? We could have dependent expressions when the declaration itself is not templated:

  • Non-templated method of a templated struct referencing the template argument
  • Lambda inside a templated function referencing the template argument
  • Method of a non-templated struct nested inside a templated struct referencing the outer struct's template argument

static void handlePtrCountedByEndedByAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
unsigned Level;
if (!S.checkUInt32Argument(AL, AL.getArgAsExpr(1), Level))
return;

if (D->getDescribedTemplate() || S.CurContext->isDependentContext()) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question here, wondering if this is sufficient for non-templated entities nested in templates.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also replaced with a call to isTemplated

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.
@hnrklssn hnrklssn force-pushed the bounds-safety-value-dependence branch from 427922f to 9858ef7 Compare February 11, 2025 04:55
@hnrklssn hnrklssn requested a review from a team as a code owner February 11, 2025 04:55
@hnrklssn
Copy link
Author

@swift-ci please test llvm

@hnrklssn
Copy link
Author

@swift-ci please smoke test

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:bounds-safety Issue relating to the experimental -fbounds-safety feature in Clang
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants