https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121292

            Bug ID: 121292
           Summary: GCC incorrectly accepts recursive lambda without error
                    when template function is not instantiated
           Product: gcc
           Version: 14.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: jirehguo at tju dot edu.cn
  Target Milestone: ---

Description:
GCC 14.3.0 incorrectly accepts code containing a recursive lambda expression
within a template function when the template function is not instantiated.
According to the C++17 standard, a lambda cannot recursively reference itself
before its definition is complete because the type of 'auto f' cannot be
determined until the lambda definition is complete.

This is a bug because GCC accepts the code without any errors or warnings when
the template function is not instantiated, but correctly reports an error when
the function is instantiated. Clang correctly reports an error in both cases.

Steps to reproduce:

Save the following code to a file named bug.cpp:
#include<iostream>

template <class T> struct S {
void foo(){
auto f = & {
f();
};
f();
}
};

int main() {
S<float> test;
// test.foo();
}

Compile with: g++ -std=c++17 bug.cpp
Notice that compilation succeeds with no errors or warnings
Expected behavior:
The compiler should report an error indicating the use of 'f' before deduction
of 'auto', as the lambda is trying to reference itself before its type is fully
determined.

Actual behavior:
GCC accepts the code without errors or warnings when the template function is
not instantiated.

Additional information:
When the line "test.foo();" is uncommented, GCC correctly reports the error:

<source>: In instantiation of 'void S<T>::foo() [with T = float]':
<source>:17:11: required from here
17 | test.foo();
| ~~~~~~~~^~
<source>:5:14: error: use of 'f' before deduction of 'auto'
5 | auto f = [&]() {
| ^~~~~~~
6 |
|
7 | f();
| ~~~~
8 | };
| ~
Compiler returned: 1

This demonstrates that GCC is aware of the issue but fails to detect it when
the template function is not instantiated.

GCC version information:
Using built-in specs.
COLLECT_GCC=/home/build/bin/gcc/bin/g++
COLLECT_LTO_WRAPPER=/home/build/bin/gcc/libexec/gcc/x86_64-pc-linux-gnu/14.3.0/lto-wrapper
Target: x86_64-pc-linux-gnu
Configured with: ../gcc-releases/configure --prefix=/home/build/bin/gcc
--enable-languages=c,c++ --disable-multilib --disable-bootstrap
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 14.3.0 (GCC)

System information:
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/ "
SUPPORT_URL="https://help.ubuntu.com/ "
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/ "
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy
"
UBUNTU_CODENAME=jammy

Linux 1a41afa15d2e 5.4.0-144-generic #161-Ubuntu SMP Fri Feb 3 14:49:04 UTC
2023 x86_64 x86_64 x86_64 GNU/Linux

Compilation command:
g++ -std=c++17 bug.cpp

Compiler output (with test.foo() commented out):
[No output - compilation succeeds]

Compiler output (with test.foo() uncommented):

<source>: In instantiation of 'void S<T>::foo() [with T = float]':
<source>:17:11: required from here
17 | test.foo();
| ~~~~~~~~^~
<source>:5:14: error: use of 'f' before deduction of 'auto'
5 | auto f = [&]() {
| ^~~~~~~
6 |
|
7 | f();
| ~~~~
8 | };
| ~
Compiler returned: 1

This bug appears to be related to template instantiation and how GCC handles
error checking for uninstantiated templates. The compiler should detect this
error during the initial parsing/semantic analysis phase, not just when the
template is instantiated.

Reply via email to