<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/122657>122657</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            `__func__` (, `__PRETTY_FUNCTION__`, `__FUNCSIG__`) does not resolve to directly-containing *function-body* when appearing in lambda's trailing return type
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          jhcarl0814
      </td>
    </tr>
</table>

<pre>
    [Compiler Explorer, x64-64 clang (trunk), -std=c++26 -O2 -Wall -pedantic -pthread](https://godbolt.org/#g:!((g:!((g:!((h:codeEditor,i:(filename:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,selection:(endColumn:50,endLineNumber:17,positionColumn:50,positionLineNumber:17,selectionStartColumn:50,selectionStartLineNumber:17,startColumn:50,startLineNumber:17),source:'%23include%3Carray%3E%0Atemplate%3Cstd::size_t+n%3E%0Astruct+template_str_t:+public+std::array%3Cchar,+n%3E%0A%7B%0A++++consteval+template_str_t(char+const+(%26str)%5Bn+%2B+1%5D)+noexcept%0A++++%7B%0A++++++++std::copy(std::begin(str),+std::begin(str)+%2B+n,+std::begin(*this))%3B%0A++++%7D%0A%7D%3B%0Atemplate%3Cstd::size_t+n%3E%0Atemplate_str_t(char+const+(%26str)%5Bn%5D)+-%3E+template_str_t%3Cn+-+1%3E%3B%0A%0A%23include%3Ciostream%3E%0Atemplate%3Ctemplate_str_t+s%3E%0Astruct+c1_t%0A%7B%0A++++c1_t()+%7B+std::cout+%3C%3C+s.data()+%3C%3C+std::endl%3B+%7D%0A%7D%3B%0A%0Aint+main()%0A%7B%0A++++%5B%5D()+-%3E+c1_t%3C__func__%3E+%7B+return+%7B%7D%3B+%7D()%3B%0A++++%5B%5D%3Ctypename+return_t+%3D+c1_t%3C__func__%3E%3E()+-%3E+return_t+%7B+return+%7B%7D%3B+%7D()%3B%0A%7D%0A'),l:'5',n:'0',o:'C%2B%2B+source+%231',t:'0')),k:50,l:'4',m:65.07009345794393,n:'0',o:'',s:0,t:'0'),(g:!((h:compiler,i:(compiler:clang_trunk,filters:(b:'0',binary:'1',binaryObject:'1',commentOnly:'0',debugCalls:'1',demangle:'0',directives:'0',execute:'1',intel:'0',libraryCode:'0',trim:'1',verboseDemangling:'0'),flagsViewOpen:'1',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-std%3Dc%2B%2B23+-O2+-Wall+-pedantic+-pthread',overrides:!(),selection:(endColumn:1,endLineNumber:1,positionColumn:1,positionLineNumber:1,selectionStartColumn:1,selectionStartLineNumber:1,startColumn:1,startLineNumber:1),source:1),l:'5',n:'0',o:'+x86-64+clang+(trunk)+(Editor+%231)',t:'0'),(h:executor,i:(argsPanelShown:'1',compilationPanelShown:'0',compiler:clang_trunk,compilerName:'',compilerOutShown:'0',execArgs:'',execStdin:'',fontScale:14,fontUsePx:'0',j:1,lang:c%2B%2B,libs:!(),options:'-std%3Dc%2B%2B26+-O2+-Wall+-pedantic+-pthread',overrides:!(),runtimeTools:!(),source:1,stdinPanelShown:'1',tree:'1',wrap:'1'),l:'5',n:'0',o:'Executor+x86-64+clang+(trunk)+(C%2B%2B,+Editor+%231)',t:'0')),header:(),l:'4',m:34.929906542056074,n:'0',o:'',s:1,t:'0')),k:100,l:'3',n:'0',o:'',t:'0')),version:4):
```cpp
#include<array>
template<std::size_t n>
struct template_str_t: public std::array<char, n>
{
    consteval template_str_t(char const (&str)[n + 1]) noexcept
    {
 std::copy(std::begin(str), std::begin(str) + n, std::begin(*this));
 }
};
template<std::size_t n>
template_str_t(char const (&str)[n]) -> template_str_t<n - 1>;

#include<iostream>
template<template_str_t s>
struct c1_t
{
    c1_t() { std::cout << s.data() << std::endl; }
};

int main()
{
    []() -> c1_t<__func__> { return {}; }();
 []<typename return_t = c1_t<__func__>>() -> return_t { return {}; }();
}
```
Program returned: 0
Program stdout
```
operator()
main
```
As shown in above example, a workaround can be to access the correct `__func__`/`__PRETTY_FUNCTION__`/`__FUNCSIG__` when in lambda's template parameter list.
Use scenario (for having the correct value of `__func__`/`__PRETTY_FUNCTION__`/`__FUNCSIG__` in lambda's trailing return type):
1. Write a macro that expands to a stream object that contains `__func__` and flushes its content to `std::cout`/`std::cerr` on destruction (like `qDebug()`). But unlike `qDebug()` which uses `__func__` only for printing and has no knowledge of the following parameters, this stream object also uses expression template to capture all the following parameters, so that when their types (including `__func__`'s type) are available, it knows how much memory should be allocated in advance (or, when records of same size are grouped together, it knows which bucket to send its output to).
2. Write a macro that takes an expression denoting a stream object that is of unknown flavor (e.g. lvalue `std::cout` which outputs ASAP, rvalue `std::osyncstream(std::cout)`/`qDebug().noquote().nospace()` which outputs on destruction), expands to a guard object definitioin that stores the stream object and does something before its construction and after its destruction. The `definition`/`does something` part needs a data_member/variable that is of type `T&` if `stream_expression` is lvalue and `T` otherwise, then at some point the use case `[](decltype((stream_expression)) s)->???<my::remove_rvalue_reference_t<decltype((stream_expression))>>{...}(stream_expression)` which needs correct `__func__` appears.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzEGV1v6jj217gvFig4hI-HPkBoVyOtbq-2vTvaJ2SSA_GtY2dsh5b99atjJyEB2tudHWklRInP9_dxyq0VBwVwT5I1STZ3vHaFNvc_i4wbGS0m07udzk8ITXVZCQmGPrxXUhswhKX0fTYdzaY0k1wdKGELZ2r1StgSYSPrchJvMsLWhK3ZjI6eGB39zqWkowpyrpzI6KhyhQGek2RD2KJwrrIkXhH2SNjjQec7Ld1Ym4M_iA8eNCFsQdji44eCxKtM5_CQC6dRTeGhi72QoHgJ_mk-IWxOWLrXyj1nXOLpZNoc_LDw_T2gRQHtJ4IJS9FQZE9Ygmb5r9SChMwJrYIcUHmqZV3iYxIRloLK_y4UfKvLHRhkhBwrbQXSDFHb02v8Tsiz48YNqYawG7Q3SG5iYuCsrk3WOAktjIXKZJ0DYUmccmP4CX89EJZEKwdlJbkLMB_vFYlXVvwbto6wtTpjWmfqDM9akq11Zuu8mHVV76TAROlYdHLSrOAYwyE3wpL5uvm17j6ZVtbBkctrMWwR-AQcj75A42bWGW92kiD_NqTrCZ5sPGStNLxnULkrebe16H86ezJdnQhbdM87OAjlD4L4tI98Cey0Uh8gErZyhbAeGW2Jb2mVzDed7zZnpK-H8M-5tHPjqOF0FZokTlWAe7d7aZ0F4WuYhEJbZ4CXH-ThJf-1vZGG2WTrPkslD1507p9fRLMOBidx2nyt7TjnjvdperCWEFQuG-s-joj_EgollLyJ7_ITXb2nG0cvLnzdmBmn2-2-Vtl22wJamwy42qheMneatA-Lz3KqE4x-P1Whv7Zct62TNp9o4r8u1R7S_0lFz-5tOpsMTS0JLV0NGrwOT2m_sa-bVhgO4mZiuD5dKLj0tW2rjYhpQC1JvJol42geRct4msyX03gZfyQ6POD4i25ISW9PuTCTzzOuO4lXfihvm4mc7oV0YMJwXewG8ndCcXMaTMVw9LT7CZkbADJdlqDck5KnAY8cdvUh5VLaAXoOJVcHCUNcYXBaHcEOjuEdstoNp7NQDuQAS4qd4eaU6nzI1BlRDkiPYHbawiZoINTh0qF7yQ_2nwLenipQf_lOIMXO9sKFAnWFI7ox2m9HWBo9MhZjDTwx_MY9Cf-2m5L_3exKIWuOYIzI4VLKJ8vI5NYucmsVmXy4iXy8iFyDrimvCW7hDZaQyZdLl7D1-2I2mk2x2fiY-JF0Xknxqd0Ju4pe3i7qtKmwkJT9LZKbg_3OFcjnQr-py-KohOTogEuMqI9xozxbwLduPx0SPNXumhsqtzIH2yfAs2eXC9U__L8l9OwvSGhTKydKeNFaXuV6L0twdxFXfm97toFhY3kzvOoffDHHHrp0-EKuDWYJrgFfTT5UpgCe-zzpjL0eLfF0vGTLZTRLpixKZhHCfjVbJp9MsEnUG2Hxp6X2kdpHMDb0nikexCsSrcgsCp-sqvDxvMy194n4gfR2uKs1lKqAEZY3enWDoOH-QC9uD93doaUn8zWJVpRS2t0ULpmFpTbAqXd9u84ma0UJW9OJv6ouaXcrCBwb3l9f-OkHIC9E3UQYrvmxF0jmG2_ZJjz_2on_jcGNqSMSP1x5PVV0RCfI0wu-DGy3o1_GdsiH2kFo_ZI4CFS3h6OH6WADpyROSZzS_ubdnQ027nh96SfiN2za26_7UsPLkIajt97r0dtd4wevT1hKffA9Zy8m8GvCEzidl2ParraUxJsbbEm7Dge5Z-wvSGtsbMuNRKvvRh8MLxtKQJ_Q_rl1OV5lhkS6AsN9o2oc4700xFlZarHLUqEo3-kjUHjnZSUBE5fTN21eudG1ymnGFd0BdZryLANrqSuAZtrgDkjJLOpsn0WEPfqD7_94eHn51_bxx7f05benbwMYHj7_9jd_Rt8K8BpIXu5yTtjcdmlKK254CQ4MlcK6MYlWPyxQm4HiRmhM9b02tOBHoQ4DnY5c1kD1_n9V7kIvwwVuoW0QMR-6DjkZ09-NcEA5LXlmNHUFdxTeK65y611HQzVR7VfyAM-0clwoe6Eo5Sqne1nbAiwVzno8UA75kFk0vMS2up9PwRhkohXNIVSl0Nj5FlK8AjL4Y4O7fpMcSL8c03XtaK0-wKBvhcgKWlu4UlUreaIYh8oI5dA9qHzBLVWavir9JiE_-GBghPZaSv2GWF1wLeYbNsULB3FpdZAI75UBi0PpnBtO04xXrjZAuZSf8rZNMHyquQKE8aGz6JHQ7ZDmMlUw4CHAlKOQIxeS70J1COcts7TQb7Sss4KWUGpzwoKqZY7FwqXUGXeQ-_LKj1xlgAL9HhpUMZBpk1t0jcW2gk3eyzoYXVeQU6cP4IrwmrYTGSKxq7NX8PlgQeU-R3TtqhqPMJwkWrGbGen4K1jKVd-pOSgdIncrR4XXsFYoXtG95Edt0BIYH8ZUhlK7kZSNokErS1fPq-9oh7km0PaksvZ10OLiDc2yy-9-So6V_qPWDronW_EMLtO1lT0shGZ2D0rzUHOTt1bnsBcKL05CBQ9Ypw2ErneRoiqnuQZLrS7BFejCHey1gbZoz9WHqHyPvQxBPXXG9KXw_ujEqs7kIW80rOLGUQWQW8opzsxtCf7axR6P3AhM0H7UMIOR9wthM9_Q9sHzaMT2nAEeZNtgoqqeBqsb8-9NWAhFCoqiP3QJtNI4fdEntQWacesFdWM3h0yG-lmEvehCol-AKC5CIz8yH9tPWp5C_A2U-gjbkDBbA3swoDLw0_ZL3JtRPF-Px-MwZm8idukS3Hp7rlFeVcCNHd_l93G-jJf8Du4n83g2Z8tkMb0r7pdsPosmHOJ5NJ0vIzaFXTQBlk3y_WKeZ_xO3LOIJdFkEkdREkfTcRLlPIpm8wVn2WS2m5BpBCUXcizlsRxrc7gT1tZwP2FslszvJN-BtP6_PIwpeKMeShgjyebO3CPRaFcfLJlGOC7tmY0TTsL9hUHedSn9ZCA2wP5ExJj5pFTaUQNWy6NvxeF9kDyNmoHmGypboTRM6NFO5yfCVqHvBVciyq_n611t5P3F_5SEK-rdONMlYY9oY_NnVBntX3axR-8ZS9hj47rjPftPAAAA__9_I_1u">