[cfe-dev] AST Printing and LValues Written as RValues

Chris Wailes chris.wailes at gmail.com
Tue Oct 29 15:39:46 PDT 2013


Due to the reference collapsing rules of C++ it is possible for a reference
to be written as a RValue reference but have it turn into an LValue
reference.  If you use the -ast-dump flag when this happens the reference
will still be printed out as an RValue reference.  This can be very
confusing when you are trying to figure out why a program is behaving the
way it does or why a call to isRValueRefernce() is returning false when you
would expect otherwise.

Attached are two files: 1) is a C++ program that contains a LValue
reference written as an RValue reference 2) is the relevant section of the
AST as it is printed by -ast-dump.

It seems to me that the fact that a reference is an LValue reference
written as an RValue reference should be evident somewhere in the printed
version of the AST.  The place that seems to make the most sense is in the
DeclRefExpr (0x201bdd0) when it prints out the string representation of the
Function (0x201bcc0).  This appears to be the representation of the
instantiated template which is, if I am understanding the reference
collapsing rules correctly, where the conversion from an RValue reference
to an LValue reference occurs.  If it is printed as an LValue reference
there, and as an RValue reference in the FunctionTemplate (0x1ff3350), that
should make it clear that the reference collapsing rules have been applied.

Before I filed this as a bug I wanted to get the mailing list's feedback.
Should the printing of LValue references written as RValue references be
handled differently, or is the current behavior the desired behavior?

- Chris
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131029/1aa9fffa/attachment.html>
-------------- next part --------------
`-FunctionDecl 0x201aff0 <line:8:1, line:14:1> main 'int (void)'
  `-CompoundStmt 0x201c2f8 <line:8:16, line:14:1>
    |-DeclStmt 0x201b520 <line:9:2, col:10>
    | |-VarDecl 0x201b0d0 <col:2, col:6> a 'class Foo'
    | | `-CXXConstructExpr 0x201b438 <col:6> 'class Foo' 'void (void)'
    | `-VarDecl 0x201b480 <col:2, col:9> b 'class Foo'
    |   `-CXXConstructExpr 0x201b4d8 <col:9> 'class Foo' 'void (void)'
    |-CXXOperatorCallExpr 0x201c270 <line:11:2, col:17> 'void'
    | |-ImplicitCastExpr 0x201c258 <col:4> 'void (*)(class Foo &&)' <FunctionToPointerDecay>
    | | `-DeclRefExpr 0x201c200 <col:4> 'void (class Foo &&)' lvalue CXXMethod 0x201ae80 'operator=' 'void (class Foo &&)'
    | |-DeclRefExpr 0x201b538 <col:2> 'class Foo' lvalue Var 0x201b0d0 'a' 'class Foo'
    | `-CallExpr 0x201c050 <col:6, col:17> 'typename std::remove_reference<class Foo &>::type':'class Foo' xvalue
    |   |-ImplicitCastExpr 0x201c038 <col:6, col:11> 'typename std::remove_reference<class Foo &>::type &&(*)(class Foo &&) noexcept' <FunctionToPointerDecay>
    |   | `-DeclRefExpr 0x201bdd0 <col:6, col:11> 'typename std::remove_reference<class Foo &>::type &&(class Foo &&) noexcept' lvalue Function 0x201bcc0 'move' 'typename std::remove_reference<class Foo &>::type &&(class Foo &&) noexcept' (FunctionTemplate 0x1ff3350 'move')
    |   `-DeclRefExpr 0x201b5d8 <col:16> 'class Foo' lvalue Var 0x201b480 'b' 'class Foo'
    `-ReturnStmt 0x201c2d8 <line:13:2, col:9>
      `-IntegerLiteral 0x201c2b8 <col:9> 'int' 0
-------------- next part --------------
A non-text attachment was scrubbed...
Name: LValueAsRValue.cpp
Type: text/x-c++src
Size: 139 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20131029/1aa9fffa/attachment.cpp>


More information about the cfe-dev mailing list