[Clang] FunctionEffects: ignore (methods of) local CXXRecordDecls. (#166078)
In the following example, `Functor::method()` inappropriately triggers a
diagnostic that `outer()` is blocking by allocating memory.
```
void outer() [[clang::nonblocking]]
{
struct Functor {
int* ptr;
void method() { ptr = new int; }
};
}
```
---------
Co-authored-by: Doug Wyatt <dwyatt@apple.com>
This commit is contained in:
parent
4334b43c65
commit
fa6cc7eade
@ -1302,6 +1302,14 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TraverseCXXRecordDecl(CXXRecordDecl *D) override {
|
||||
// Completely skip local struct/class/union declarations since their
|
||||
// methods would otherwise be incorrectly interpreted as part of the
|
||||
// function we are currently traversing. The initial Sema pass will have
|
||||
// already recorded any nonblocking methods needing analysis.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
|
||||
ViolationSite PrevVS = VSite;
|
||||
if (Init->isAnyMemberInitializer())
|
||||
|
||||
@ -104,6 +104,25 @@ void nb8c()
|
||||
};
|
||||
}
|
||||
|
||||
void nb8d() [[clang::nonblocking]]
|
||||
{
|
||||
// Blocking methods of a local CXXRecordDecl do not generate diagnostics
|
||||
// for the outer function.
|
||||
struct F1 {
|
||||
void method() { void* ptr = new int; }
|
||||
};
|
||||
|
||||
// Skipping the CXXRecordDecl does not skip a following VarDecl.
|
||||
struct F2 {
|
||||
F2() { void* ptr = new int; } // expected-note {{constructor cannot be inferred 'nonblocking' because it allocates or deallocates memory}}
|
||||
} f2; // expected-warning {{function with 'nonblocking' attribute must not call non-'nonblocking' constructor 'nb8d()::F2::F2'}}
|
||||
|
||||
// Nonblocking methods of a local CXXRecordDecl are verified independently.
|
||||
struct F3 {
|
||||
void method() [[clang::nonblocking]] { void* ptr = new int; }// expected-warning {{function with 'nonblocking' attribute must not allocate or deallocate memory}}
|
||||
};
|
||||
}
|
||||
|
||||
// Make sure template expansions are found and verified.
|
||||
template <typename T>
|
||||
struct Adder {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user