[Clang] FunctionEffects: properly extract the type of a bound member member function from a CallExpr. by dougsonos · Pull Request #166101 · llvm/llvm-project (original) (raw)

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 andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Conversation4 Commits4 Checks13 Files changed

Conversation

This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters

[ Show hidden characters]({{ revealButtonHref }})

@dougsonos

There's a bug illustrated by this example:

template <typename T>
struct Holder {
    T value;
    
    T& operator*() { return value; }
};

struct X {
    using Dispatch = float (X::*)() [[clang::nonblocking]];
    
    void fails(Holder<Dispatch>& holder) [[clang::nonblocking]]
    {
        (this->*(*holder))();   <<< the expression is incorrectly determined not to be nonblocking
    }

    void succeeds(Holder<Dispatch>& holder) [[clang::nonblocking]]
    {
        auto func = *holder;
        (this->*func)();
    }
};

In both cases we have a CXXMemberCallExpr. In succeeds, the expression refers to a Decl (func) and gets a useful PTMF type. In fails, the expression does not refer to a Decl and its type is special, printed as bound member function. Expr provides a method for extracting the true type so we can use that in this situation.

…member function from a CallExpr.

@llvmbot llvmbot added clang

Clang issues not falling into any other category

clang:frontend

Language frontend issues, e.g. anything involving "Sema"

labels

Nov 2, 2025

@llvmbot

@llvm/pr-subscribers-clang

Author: Doug Wyatt (dougsonos)

Changes

There's a bug illustrated by this example:

template &lt;typename T&gt;
struct Holder {
    T value;
    
    T&amp; operator*() { return value; }
};

struct X {
    using Dispatch = float (X::*)() [[clang::nonblocking]];
    
    void fails(Holder&lt;Dispatch&gt;&amp; holder) [[clang::nonblocking]]
    {
        (this-&gt;*(*holder))();   &lt;&lt;&lt; the expression is incorrectly determined not to be nonblocking
    }

    void succeeds(Holder&lt;Dispatch&gt;&amp; holder) [[clang::nonblocking]]
    {
        auto func = *holder;
        (this-&gt;*func)();
    }
};

In both cases we have a CXXMemberCallExpr. In succeeds, the expression refers to a Decl (func) and gets a useful PTMF type. In fails, the expression does not refer to a Decl and its type is special, printed as bound member function. Expr provides a method for extracting the true type so we can use that in this situation.


Full diff: https://github.com/llvm/llvm-project/pull/166101.diff

2 Files Affected:

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; }

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]];

Sirraide

Choose a reason for hiding this comment

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

Some minor comments; lgtm otherwise

void ptmfInExpr(Holder& holder) [[clang::nonblocking]]
{
(this->*(*holder))(); // This should not generate a warning.

Choose a reason for hiding this comment

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

Can you also add

as well as a test case that shows that we do issue a warning if the member function is not nonblocking.

@dougsonos @Sirraide

Co-authored-by: Sirraide aeternalmail@gmail.com

Labels

clang:frontend

Language frontend issues, e.g. anything involving "Sema"

clang

Clang issues not falling into any other category