Skip to content

[clang] Compiler fails to detect infinite recursion in A<T, T>-style nested templates #148610

@GitSparTV

Description

@GitSparTV
template <typename T, typename U = T>
class A {};

template <typename T>
void RecursiveFunction(T t) {
    RecursiveFunction(A<T>());
}

int main() { RecursiveFunction(42); }

Demo: https://godbolt.org/z/jbTWh1Kej

Compiler is able to detect recursion in cases like $\text{A&lt;...A&lt;T&gt;...&gt;}$, but not in $\text{A&lt;...A&lt;T&gt;..., ...A&lt;T&gt;...&gt;}$.
In other words this is what happens in the example: $T_0 = \texttt{B}, \quad T_{n+1} = \texttt{A&lt;}T_n,\ T_n\texttt{&gt;}$

All major compilers don't generate any information, just eating RAM and stack space.

Another example where the generated template can be examined: https://godbolt.org/z/MKdcqbqjW

Here you can see Add function is instantiated with:
unique_ptr<D, D> -> unique_ptr<unique_ptr<D, D>, unique_ptr<D, D>> -> unique_ptr<unique_ptr<unique_ptr<D, D>, unique_ptr<D, D>>, unique_ptr<unique_ptr<D, D>, unique_ptr<D, D>>> -> and so on

This bug was found when using real std::unique_ptr, since it has 2 parameters both of which are dependent on T, current recursion detection doesn't work.

Real example: https://godbolt.org/z/6TK94576j

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:diagnosticsNew/improved warning or error message in Clang, but not in clang-tidy or static analyzerfalse-negative

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions