[cfe-dev] Unexpected TypeLoc match for captured variable in lambda

Manuel Klimek via cfe-dev cfe-dev at lists.llvm.org
Mon Mar 25 01:59:19 PDT 2019


I think there was some work recently that changed how we represented
lambdas, but not sure whether that affected this behavior.
Here, the FieldDecl of the CXXRecordDecl has a const Foo & type and it has
the 'fn' as the TypeLoc - I assume the location is a bug.

I got there through clang-query by adding hasParent() and guessing the
types, iterating between output dump, print and diag.

Note that the output of the class in the second query is a red herring -
the first one shows that we end up there via a FieldDecl (Binding for "3").

clang-query> m
typeLoc(loc(qualType(hasDeclaration(namedDecl(hasName("Foo"))))),
hasParent(typeLoc(hasParent(typeLoc(hasParent(decl(hasParent(decl().bind("4"))).bind("3"))).bind("2"))).bind("1")))

Match #1:

Binding for "1":
Unable to dump values of type TypeLoc

Binding for "2":
Unable to dump values of type TypeLoc

Binding for "3":
FieldDecl 0x7f51ffd91ee0 </tmp/t.cc:7:5> col:5 implicit 'Fn<Foo> &'

Binding for "4":
CXXRecordDecl 0x7f51ffd91c88 </tmp/t.cc:6:3> col:3 implicit class
definition
|-DefinitionData lambda pass_in_registers trivially_copyable
can_const_default_init
| |-DefaultConstructor
| |-CopyConstructor simple trivial has_const_param needs_implicit
implicit_has_const_param
| |-MoveConstructor exists simple trivial needs_implicit
| |-CopyAssignment trivial has_const_param needs_implicit
implicit_has_const_param
| |-MoveAssignment
| `-Destructor simple irrelevant trivial
|-FieldDecl 0x7f51ffd91ee0 <line:7:5> col:5 implicit 'Fn<Foo> &'
|-CXXMethodDecl 0x7f51ffd91dc0 <line:6:21, line:8:3> line:6:3 operator() 'void
(const Foo &) const' inline
| |-ParmVarDecl 0x7f51ffd91ba8 <col:7, col:18> col:18 foo 'const Foo &'
| `-CompoundStmt 0x7f51ffd91f30 <col:23, line:8:3>
|   `-DeclRefExpr 0x7f51ffd91e78 <line:7:5> 'Fn<Foo>':'Fn<Foo>' lvalue
ParmVar 0x7f51ffd91980 'fn' 'Fn<Foo> &'
`-CXXDestructorDecl 0x7f51ffdc3080 <line:6:3> col:3 implicit referenced ~ 'void
() noexcept' inline default trivial

Binding for "root":
Unable to dump values of type TypeLoc

clang-query> set output print

clang-query> m
typeLoc(loc(qualType(hasDeclaration(namedDecl(hasName("Foo"))))),
hasParent(typeLoc(hasParent(typeLoc(hasParent(decl(hasParent(decl().bind("4"))).bind("3"))).bind("2"))).bind("1")))


Match #1:

Binding for "1":
Fn<Foo>
Binding for "2":
Fn<Foo> &
Binding for "3":
Fn<Foo> &
Binding for "4":
class {
   inline void operator()(const Foo &foo) const     {
       fn;
   }
}
Binding for "root":
Foo
1 match.


On Thu, Feb 14, 2019 at 3:13 PM Eric Liu via cfe-dev <cfe-dev at lists.llvm.org>
wrote:

> Hi,
>
> In the following example, the captured variable `fn` is matched as a
> TypeLoc of Foo; `fn` outside of the lambda is not matched.
> ```
> // test.cc
> class Foo {};
>
> template <typename T> struct Fn { T t; };
>
> void f(Fn<Foo> &fn) {
>   [&](const Foo &foo) {
>     fn;  // <--------- *** This is matched as a TypeLoc of Foo ***
>   };
> }
> ```
>
> clang-query> m
> typeLoc(loc(qualType(hasDeclaration(namedDecl(hasName("Foo"))))))
> ...
> Match #2:
> test.cc:7:5: note: "root" binds here
>     fn;
>     ^~
> ...
>
> Is this a bug? If not, is there a way to filter this out?
>
> Thanks,
> Eric
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190325/fd6b76b0/attachment.html>


More information about the cfe-dev mailing list