Skip to content

Commit fa6cc7e

Browse files
dougsonosDoug Wyatt
andauthored
[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 <[email protected]>
1 parent 4334b43 commit fa6cc7e

File tree

2 files changed

+27
-0
lines changed

2 files changed

+27
-0
lines changed

clang/lib/Sema/SemaFunctionEffects.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,6 +1302,14 @@ class Analyzer {
13021302
return true;
13031303
}
13041304

1305+
bool TraverseCXXRecordDecl(CXXRecordDecl *D) override {
1306+
// Completely skip local struct/class/union declarations since their
1307+
// methods would otherwise be incorrectly interpreted as part of the
1308+
// function we are currently traversing. The initial Sema pass will have
1309+
// already recorded any nonblocking methods needing analysis.
1310+
return true;
1311+
}
1312+
13051313
bool TraverseConstructorInitializer(CXXCtorInitializer *Init) override {
13061314
ViolationSite PrevVS = VSite;
13071315
if (Init->isAnyMemberInitializer())

clang/test/Sema/attr-nonblocking-constraints.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,25 @@ void nb8c()
104104
};
105105
}
106106

107+
void nb8d() [[clang::nonblocking]]
108+
{
109+
// Blocking methods of a local CXXRecordDecl do not generate diagnostics
110+
// for the outer function.
111+
struct F1 {
112+
void method() { void* ptr = new int; }
113+
};
114+
115+
// Skipping the CXXRecordDecl does not skip a following VarDecl.
116+
struct F2 {
117+
F2() { void* ptr = new int; } // expected-note {{constructor cannot be inferred 'nonblocking' because it allocates or deallocates memory}}
118+
} f2; // expected-warning {{function with 'nonblocking' attribute must not call non-'nonblocking' constructor 'nb8d()::F2::F2'}}
119+
120+
// Nonblocking methods of a local CXXRecordDecl are verified independently.
121+
struct F3 {
122+
void method() [[clang::nonblocking]] { void* ptr = new int; }// expected-warning {{function with 'nonblocking' attribute must not allocate or deallocate memory}}
123+
};
124+
}
125+
107126
// Make sure template expansions are found and verified.
108127
template <typename T>
109128
struct Adder {

0 commit comments

Comments
 (0)