[clang] [Clang] fix generic lambda inside requires-clause of friend function template (PR #99813)

Zhikai Zeng via cfe-commits cfe-commits at lists.llvm.org
Sat Aug 10 20:43:05 PDT 2024


Backl1ght wrote:

> So, friend functions do not increase the template depth? That seems... weird!

This is not the cause, as for template depth friend functions behave just the same as other functions I think. Maybe you are confused by my first comment in https://github.com/llvm/llvm-project/issues/98258 , that is incorrect cause I made a stupid mistake.

As we are allowed to use generic lambda inside requires-clause, a friend function template can reference to a value below the template depth of the friend function. 

For example, the `X` has a template depth of 1 while `f3` has a template depth of 0.

```cpp
struct S {
  template <typename U>
  friend void f3() requires requires { []<int X>(){ return X; }; } {
    return;
  }
};
```

```plain text
`-FriendDecl 0xd461268 <line:2:3, line:5:3> line:3:15
    `-FunctionTemplateDecl 0xd43f638 parent 0xd3ebd28 <line:2:3, line:5:3> line:3:15 friend_undeclared f3
      |-TemplateTypeParmDecl 0xd43ead0 <line:2:13, col:22> col:22 typename depth 0 index 0 U
      `-FunctionDecl 0xd43f548 parent 0xd3ebd28 <line:3:3, line:5:3> line:3:15 friend_undeclared f3 'void ()' implicit-inline
        |-RequiresExpr 0xd43f4b0 <col:29, col:66> 'bool'
        | `-SimpleRequirement 0xd43f480 dependent
        |   `-LambdaExpr 0xd43f458 <col:40, col:63> 'S::(lambda at <source>:3:40)'
        |     |-CXXRecordDecl 0xd43ebf0 <col:40> col:40 implicit class definition
        |     | |-DefinitionData generic lambda empty standard_layout trivially_copyable trivial literal has_constexpr_non_copy_move_ctor can_const_default_init
        |     | | |-DefaultConstructor exists trivial constexpr needs_implicit defaulted_is_constexpr
        |     | | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
        |     | | |-MoveConstructor exists simple trivial needs_implicit
        |     | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
        |     | | |-MoveAssignment exists simple trivial needs_implicit
        |     | | `-Destructor simple irrelevant trivial constexpr needs_implicit
        |     | |-FunctionTemplateDecl 0xd43eea8 <<invalid sloc>, col:63> col:40 operator()
        |     | | |-NonTypeTemplateParmDecl 0xd43ee30 <col:43, col:47> col:47 referenced 'int' depth 1 index 0 X
        |     | | `-CXXMethodDecl 0xd43ed58 <col:50, col:63> col:40 constexpr operator() 'auto () const' inline
        |     | |   `-CompoundStmt 0xd43f0d8 <col:51, col:63>
        |     | |     `-ReturnStmt 0xd43f0c8 <col:53, col:60>
        |     | |       `-DeclRefExpr 0xd43f0a8 <col:60> 'int' NonTypeTemplateParm 0xd43ee30 'X' 'int'
        |     | |-FunctionTemplateDecl 0xd43f2d0 <<invalid sloc>, col:63> col:40 implicit operator auto (*)()
        |     | | |-NonTypeTemplateParmDecl 0xd43ee30 <col:43, col:47> col:47 referenced 'int' depth 1 index 0 X
        |     | | `-CXXConversionDecl 0xd43f218 <col:40, col:63> col:40 implicit constexpr operator auto (*)() 'auto (*() const noexcept)()' inline
        |     | `-FunctionTemplateDecl 0xd43f3e8 <<invalid sloc>, col:63> col:40 implicit __invoke
        |     |   |-NonTypeTemplateParmDecl 0xd43ee30 <col:43, col:47> col:47 referenced 'int' depth 1 index 0 X
        |     |   `-CXXMethodDecl 0xd43f338 <col:40, col:63> col:40 implicit __invoke 'auto ()' static inline
        |     `-CompoundStmt 0xd43f0d8 <col:51, col:63>
        |       `-ReturnStmt 0xd43f0c8 <col:53, col:60>
        |         `-DeclRefExpr 0xd43f0a8 <col:60> 'int' NonTypeTemplateParm 0xd43ee30 'X' 'int'
        `-CompoundStmt 0xd461380 <col:68, line:5:3>
          `-ReturnStmt 0xd461370 <line:4:5>
```

https://godbolt.org/z/6TxrGdM35

We can make this example more complicated, like place a generic lambda inside a generic lambda.
https://godbolt.org/z/E6G5qv7v1

https://github.com/llvm/llvm-project/pull/99813


More information about the cfe-commits mailing list