From 43f1b86e4f912b4b335e1b438035e6107e3aef43 Mon Sep 17 00:00:00 2001 From: Doug Wyatt Date: Sun, 2 Nov 2025 13:37:18 -0800 Subject: [PATCH 1/3] [Clang] FunctionEffects: properly extract the type of a bound member member function from a CallExpr. --- clang/lib/Sema/SemaFunctionEffects.cpp | 13 +++++++++++-- clang/test/Sema/attr-nonblocking-constraints.cpp | 15 ++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaFunctionEffects.cpp b/clang/lib/Sema/SemaFunctionEffects.cpp index 8590ee831084f..6d7bcbf53fe0f 100644 --- a/clang/lib/Sema/SemaFunctionEffects.cpp +++ b/clang/lib/Sema/SemaFunctionEffects.cpp @@ -1208,8 +1208,17 @@ class Analyzer { return true; } - // No Decl, just an Expr. Just check based on its type. - checkIndirectCall(Call, CalleeExpr->getType()); + // No Decl, just an Expr. Just check based on its type. Bound member + // functions are a special expression type and need to be specially + // unpacked. + QualType CalleeExprQT = CalleeExpr->getType(); + if (CalleeExpr->isBoundMemberFunction(Outer.S.getASTContext())) { + QualType QT = Expr::findBoundMemberType(CalleeExpr); + if (!QT.isNull()) { + CalleeExprQT = QT; + } + } + checkIndirectCall(Call, CalleeExprQT); return true; } diff --git a/clang/test/Sema/attr-nonblocking-constraints.cpp b/clang/test/Sema/attr-nonblocking-constraints.cpp index b26a945843696..22f7e23f81cf9 100644 --- a/clang/test/Sema/attr-nonblocking-constraints.cpp +++ b/clang/test/Sema/attr-nonblocking-constraints.cpp @@ -236,9 +236,22 @@ void nb13() [[clang::nonblocking]] { nb12(); } struct PTMFTester { typedef void (PTMFTester::*ConvertFunction)() [[clang::nonblocking]]; + ConvertFunction mConvertFunc; + void convert() [[clang::nonblocking]]; - ConvertFunction mConvertFunc; + template + struct Holder { + T value; + + T& operator*() { return value; } + }; + + + void ptmfInExpr(Holder& holder) [[clang::nonblocking]] + { + (this->*(*holder))(); // This should not generate a warning. + } }; void PTMFTester::convert() [[clang::nonblocking]] From 99061e9f7086aa49d6888e689ba972d0aa1fd86b Mon Sep 17 00:00:00 2001 From: Doug Wyatt Date: Mon, 3 Nov 2025 07:42:02 -0800 Subject: [PATCH 2/3] Update clang/lib/Sema/SemaFunctionEffects.cpp Co-authored-by: Sirraide --- clang/lib/Sema/SemaFunctionEffects.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Sema/SemaFunctionEffects.cpp b/clang/lib/Sema/SemaFunctionEffects.cpp index 6d7bcbf53fe0f..5459861ec349d 100644 --- a/clang/lib/Sema/SemaFunctionEffects.cpp +++ b/clang/lib/Sema/SemaFunctionEffects.cpp @@ -1214,9 +1214,8 @@ class Analyzer { QualType CalleeExprQT = CalleeExpr->getType(); if (CalleeExpr->isBoundMemberFunction(Outer.S.getASTContext())) { QualType QT = Expr::findBoundMemberType(CalleeExpr); - if (!QT.isNull()) { + if (!QT.isNull()) CalleeExprQT = QT; - } } checkIndirectCall(Call, CalleeExprQT); From 537900aac9bc56ae4bb869129ebd1ad718653834 Mon Sep 17 00:00:00 2001 From: Doug Wyatt Date: Mon, 3 Nov 2025 07:50:54 -0800 Subject: [PATCH 3/3] more tests --- .../Sema/attr-nonblocking-constraints.cpp | 20 ++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/clang/test/Sema/attr-nonblocking-constraints.cpp b/clang/test/Sema/attr-nonblocking-constraints.cpp index 22f7e23f81cf9..0d2dbb4947dc8 100644 --- a/clang/test/Sema/attr-nonblocking-constraints.cpp +++ b/clang/test/Sema/attr-nonblocking-constraints.cpp @@ -235,10 +235,14 @@ void nb13() [[clang::nonblocking]] { nb12(); } // C++ member function pointers struct PTMFTester { typedef void (PTMFTester::*ConvertFunction)() [[clang::nonblocking]]; + typedef void (PTMFTester::*BlockingFunction)(); ConvertFunction mConvertFunc; - void convert() [[clang::nonblocking]]; + void convert() [[clang::nonblocking]] + { + (this->*mConvertFunc)(); // This should not generate a warning. + } template struct Holder { @@ -250,14 +254,16 @@ struct PTMFTester { void ptmfInExpr(Holder& holder) [[clang::nonblocking]] { - (this->*(*holder))(); // This should not generate a warning. + (this->*(*holder))(); // Should not generate a warning. + ((*this).*(*holder))(); // Should not generate a warning. } -}; -void PTMFTester::convert() [[clang::nonblocking]] -{ - (this->*mConvertFunc)(); -} + void ptmfInExpr(Holder& holder) [[clang::nonblocking]] + { + (this->*(*holder))(); // expected-warning {{function with 'nonblocking' attribute must not call non-'nonblocking' expression}} + ((*this).*(*holder))(); // expected-warning {{function with 'nonblocking' attribute must not call non-'nonblocking' expression}} + } +}; // Allow implicit conversion from array to pointer. void nb14(unsigned idx) [[clang::nonblocking]]