Re: r288866 - [c++17] P0135R1: Guaranteed copy elision.

2016-12-09 Thread Adrian Prantl via cfe-commits

> On Dec 8, 2016, at 7:31 PM, Duncan P. N. Exon Smith  
> wrote:
> 
> 
>> On 2016-Dec-08, at 19:29, Richard Smith  wrote:
>> 
>> On 8 Dec 2016 7:17 pm, "Duncan P. N. Exon Smith via cfe-commits" 
>>  wrote:
>> +Eric, Marshall
>> 
>> I haven't looked, but: from the test name, "copy.fail.cpp", I suspect there 
>> is a bug/incompatibility in the test.  It likely relies on the compiler 
>> trying (and failing) to copy something in a context where r288866 guarantees 
>> that there is no copy.
>> 
>> Was this not fixed by "[libcxx] r289033 - Avoid C++17 guaranteed copy 
>> elision when testing for non-copyability"?
> 
> Yes, the bot is green now:
> http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/2728/

That's great! Unfortunately this bot has a latency of more than 6 hours...

thanks,
adrian
> 
>> 
>>> On 2016-Dec-08, at 18:00, Adrian Prantl  wrote:
>>> 
>>> Hi Richard,
>>> 
>>> at this point this is more a heads-up than anything actionable, but I 
>>> wanted to let you know that I bisected this bot failure 
>>> (http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/2721/consoleFull#10584592348254eaf0-7326-4999-85b0-388101f2d404)
>>>  of std/input.output/stream.buffers/streambuf/streambuf.cons/copy.fail.cpp 
>>> down to this commit.
>>> 
>>> I will follow up once I have a better understanding what is going on there.
>>> 
>>> -- adrian
>>> 
 On Dec 6, 2016, at 3:52 PM, Richard Smith via cfe-commits 
  wrote:
 
 Author: rsmith
 Date: Tue Dec  6 17:52:28 2016
 New Revision: 288866
 
 URL: http://llvm.org/viewvc/llvm-project?rev=288866=rev
 Log:
 [c++17] P0135R1: Guaranteed copy elision.
 
 When an object of class type is initialized from a prvalue of the same type
 (ignoring cv qualifications), use the prvalue to initialize the object 
 directly
 instead of inserting a redundant elidable call to a copy constructor.
 
 Added:
  cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
  cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp
 Modified:
  cfe/trunk/include/clang/AST/Expr.h
  cfe/trunk/lib/AST/Expr.cpp
  cfe/trunk/lib/AST/ExprConstant.cpp
  cfe/trunk/lib/CodeGen/CGExpr.cpp
  cfe/trunk/lib/CodeGen/CGExprAgg.cpp
  cfe/trunk/lib/CodeGen/CGExprConstant.cpp
  cfe/trunk/lib/Sema/SemaExprCXX.cpp
  cfe/trunk/lib/Sema/SemaInit.cpp
  cfe/trunk/lib/Sema/SemaOverload.cpp
  cfe/trunk/test/CXX/drs/dr0xx.cpp
  cfe/trunk/test/CXX/drs/dr10xx.cpp
  cfe/trunk/test/CXX/drs/dr1xx.cpp
  cfe/trunk/test/CXX/drs/dr4xx.cpp
  cfe/trunk/test/SemaCXX/aggregate-initialization.cpp
  cfe/trunk/www/cxx_dr_status.html
  cfe/trunk/www/cxx_status.html
 
 Modified: cfe/trunk/include/clang/AST/Expr.h
 URL: 
 http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=288866=288865=288866=diff
 ==
 --- cfe/trunk/include/clang/AST/Expr.h (original)
 +++ cfe/trunk/include/clang/AST/Expr.h Tue Dec  6 17:52:28 2016
 @@ -3786,7 +3786,7 @@ public:
 
 /// \brief Build an empty initializer list.
 explicit InitListExpr(EmptyShell Empty)
 -: Expr(InitListExprClass, Empty) { }
 +: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
 
 unsigned getNumInits() const { return InitExprs.size(); }
 
 @@ -3894,6 +3894,11 @@ public:
 // literal or an @encode?
 bool isStringLiteralInit() const;
 
 +  /// Is this a transparent initializer list (that is, an InitListExpr 
 that is
 +  /// purely syntactic, and whose semantics are that of the sole contained
 +  /// initializer)?
 +  bool isTransparent() const;
 +
 SourceLocation getLBraceLoc() const { return LBraceLoc; }
 void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
 SourceLocation getRBraceLoc() const { return RBraceLoc; }
 
 Modified: cfe/trunk/lib/AST/Expr.cpp
 URL: 
 http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=288866=288865=288866=diff
 ==
 --- cfe/trunk/lib/AST/Expr.cpp (original)
 +++ cfe/trunk/lib/AST/Expr.cpp Tue Dec  6 17:52:28 2016
 @@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit()
 return isa(Init) || isa(Init);
 }
 
 +bool InitListExpr::isTransparent() const {
 +  assert(isSemanticForm() && "syntactic form never semantically 
 transparent");
 +
 +  // A glvalue InitListExpr is always just sugar.
 +  if (isGLValue()) {
 +assert(getNumInits() == 1 && "multiple inits in glvalue init list");
 +return true;
 +  }
 +
 +  // Otherwise, we're sugar if and only if we have exactly one 
 initializer 

Re: r288866 - [c++17] P0135R1: Guaranteed copy elision.

2016-12-08 Thread Duncan P. N. Exon Smith via cfe-commits

> On 2016-Dec-08, at 19:29, Richard Smith  wrote:
> 
> On 8 Dec 2016 7:17 pm, "Duncan P. N. Exon Smith via cfe-commits" 
>  wrote:
> +Eric, Marshall
> 
> I haven't looked, but: from the test name, "copy.fail.cpp", I suspect there 
> is a bug/incompatibility in the test.  It likely relies on the compiler 
> trying (and failing) to copy something in a context where r288866 guarantees 
> that there is no copy.
> 
> Was this not fixed by "[libcxx] r289033 - Avoid C++17 guaranteed copy elision 
> when testing for non-copyability"?

Yes, the bot is green now:
http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/2728/

> 
> > On 2016-Dec-08, at 18:00, Adrian Prantl  wrote:
> >
> > Hi Richard,
> >
> > at this point this is more a heads-up than anything actionable, but I 
> > wanted to let you know that I bisected this bot failure 
> > (http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/2721/consoleFull#10584592348254eaf0-7326-4999-85b0-388101f2d404)
> >  of std/input.output/stream.buffers/streambuf/streambuf.cons/copy.fail.cpp 
> > down to this commit.
> >
> > I will follow up once I have a better understanding what is going on there.
> >
> > -- adrian
> >
> >> On Dec 6, 2016, at 3:52 PM, Richard Smith via cfe-commits 
> >>  wrote:
> >>
> >> Author: rsmith
> >> Date: Tue Dec  6 17:52:28 2016
> >> New Revision: 288866
> >>
> >> URL: http://llvm.org/viewvc/llvm-project?rev=288866=rev
> >> Log:
> >> [c++17] P0135R1: Guaranteed copy elision.
> >>
> >> When an object of class type is initialized from a prvalue of the same type
> >> (ignoring cv qualifications), use the prvalue to initialize the object 
> >> directly
> >> instead of inserting a redundant elidable call to a copy constructor.
> >>
> >> Added:
> >>   cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
> >>   cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp
> >> Modified:
> >>   cfe/trunk/include/clang/AST/Expr.h
> >>   cfe/trunk/lib/AST/Expr.cpp
> >>   cfe/trunk/lib/AST/ExprConstant.cpp
> >>   cfe/trunk/lib/CodeGen/CGExpr.cpp
> >>   cfe/trunk/lib/CodeGen/CGExprAgg.cpp
> >>   cfe/trunk/lib/CodeGen/CGExprConstant.cpp
> >>   cfe/trunk/lib/Sema/SemaExprCXX.cpp
> >>   cfe/trunk/lib/Sema/SemaInit.cpp
> >>   cfe/trunk/lib/Sema/SemaOverload.cpp
> >>   cfe/trunk/test/CXX/drs/dr0xx.cpp
> >>   cfe/trunk/test/CXX/drs/dr10xx.cpp
> >>   cfe/trunk/test/CXX/drs/dr1xx.cpp
> >>   cfe/trunk/test/CXX/drs/dr4xx.cpp
> >>   cfe/trunk/test/SemaCXX/aggregate-initialization.cpp
> >>   cfe/trunk/www/cxx_dr_status.html
> >>   cfe/trunk/www/cxx_status.html
> >>
> >> Modified: cfe/trunk/include/clang/AST/Expr.h
> >> URL: 
> >> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=288866=288865=288866=diff
> >> ==
> >> --- cfe/trunk/include/clang/AST/Expr.h (original)
> >> +++ cfe/trunk/include/clang/AST/Expr.h Tue Dec  6 17:52:28 2016
> >> @@ -3786,7 +3786,7 @@ public:
> >>
> >>  /// \brief Build an empty initializer list.
> >>  explicit InitListExpr(EmptyShell Empty)
> >> -: Expr(InitListExprClass, Empty) { }
> >> +: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
> >>
> >>  unsigned getNumInits() const { return InitExprs.size(); }
> >>
> >> @@ -3894,6 +3894,11 @@ public:
> >>  // literal or an @encode?
> >>  bool isStringLiteralInit() const;
> >>
> >> +  /// Is this a transparent initializer list (that is, an InitListExpr 
> >> that is
> >> +  /// purely syntactic, and whose semantics are that of the sole contained
> >> +  /// initializer)?
> >> +  bool isTransparent() const;
> >> +
> >>  SourceLocation getLBraceLoc() const { return LBraceLoc; }
> >>  void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
> >>  SourceLocation getRBraceLoc() const { return RBraceLoc; }
> >>
> >> Modified: cfe/trunk/lib/AST/Expr.cpp
> >> URL: 
> >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=288866=288865=288866=diff
> >> ==
> >> --- cfe/trunk/lib/AST/Expr.cpp (original)
> >> +++ cfe/trunk/lib/AST/Expr.cpp Tue Dec  6 17:52:28 2016
> >> @@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit()
> >>  return isa(Init) || isa(Init);
> >> }
> >>
> >> +bool InitListExpr::isTransparent() const {
> >> +  assert(isSemanticForm() && "syntactic form never semantically 
> >> transparent");
> >> +
> >> +  // A glvalue InitListExpr is always just sugar.
> >> +  if (isGLValue()) {
> >> +assert(getNumInits() == 1 && "multiple inits in glvalue init list");
> >> +return true;
> >> +  }
> >> +
> >> +  // Otherwise, we're sugar if and only if we have exactly one 
> >> initializer that
> >> +  // is of the same type.
> >> +  if (getNumInits() != 1 || !getInit(0))
> >> +return false;
> >> +
> >> +  return getType().getCanonicalType() ==
> >> + 

Re: r288866 - [c++17] P0135R1: Guaranteed copy elision.

2016-12-08 Thread Duncan P. N. Exon Smith via cfe-commits
Hmm, never mind.  The test seems to preclude copy elision if I'm looking in the 
right place:

std::streambuf ();

int main()
{
std::streambuf sb = get(); // expected-error
}


> On 2016-Dec-08, at 19:17, Duncan P. N. Exon Smith via cfe-commits 
>  wrote:
> 
> +Eric, Marshall
> 
> I haven't looked, but: from the test name, "copy.fail.cpp", I suspect there 
> is a bug/incompatibility in the test.  It likely relies on the compiler 
> trying (and failing) to copy something in a context where r288866 guarantees 
> that there is no copy.
> 
>> On 2016-Dec-08, at 18:00, Adrian Prantl  wrote:
>> 
>> Hi Richard,
>> 
>> at this point this is more a heads-up than anything actionable, but I wanted 
>> to let you know that I bisected this bot failure 
>> (http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/2721/consoleFull#10584592348254eaf0-7326-4999-85b0-388101f2d404)
>>  of std/input.output/stream.buffers/streambuf/streambuf.cons/copy.fail.cpp 
>> down to this commit.
>> 
>> I will follow up once I have a better understanding what is going on there.
>> 
>> -- adrian
>> 
>>> On Dec 6, 2016, at 3:52 PM, Richard Smith via cfe-commits 
>>>  wrote:
>>> 
>>> Author: rsmith
>>> Date: Tue Dec  6 17:52:28 2016
>>> New Revision: 288866
>>> 
>>> URL: http://llvm.org/viewvc/llvm-project?rev=288866=rev
>>> Log:
>>> [c++17] P0135R1: Guaranteed copy elision.
>>> 
>>> When an object of class type is initialized from a prvalue of the same type
>>> (ignoring cv qualifications), use the prvalue to initialize the object 
>>> directly
>>> instead of inserting a redundant elidable call to a copy constructor.
>>> 
>>> Added:
>>>  cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
>>>  cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp
>>> Modified:
>>>  cfe/trunk/include/clang/AST/Expr.h
>>>  cfe/trunk/lib/AST/Expr.cpp
>>>  cfe/trunk/lib/AST/ExprConstant.cpp
>>>  cfe/trunk/lib/CodeGen/CGExpr.cpp
>>>  cfe/trunk/lib/CodeGen/CGExprAgg.cpp
>>>  cfe/trunk/lib/CodeGen/CGExprConstant.cpp
>>>  cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>>  cfe/trunk/lib/Sema/SemaInit.cpp
>>>  cfe/trunk/lib/Sema/SemaOverload.cpp
>>>  cfe/trunk/test/CXX/drs/dr0xx.cpp
>>>  cfe/trunk/test/CXX/drs/dr10xx.cpp
>>>  cfe/trunk/test/CXX/drs/dr1xx.cpp
>>>  cfe/trunk/test/CXX/drs/dr4xx.cpp
>>>  cfe/trunk/test/SemaCXX/aggregate-initialization.cpp
>>>  cfe/trunk/www/cxx_dr_status.html
>>>  cfe/trunk/www/cxx_status.html
>>> 
>>> Modified: cfe/trunk/include/clang/AST/Expr.h
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=288866=288865=288866=diff
>>> ==
>>> --- cfe/trunk/include/clang/AST/Expr.h (original)
>>> +++ cfe/trunk/include/clang/AST/Expr.h Tue Dec  6 17:52:28 2016
>>> @@ -3786,7 +3786,7 @@ public:
>>> 
>>> /// \brief Build an empty initializer list.
>>> explicit InitListExpr(EmptyShell Empty)
>>> -: Expr(InitListExprClass, Empty) { }
>>> +: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
>>> 
>>> unsigned getNumInits() const { return InitExprs.size(); }
>>> 
>>> @@ -3894,6 +3894,11 @@ public:
>>> // literal or an @encode?
>>> bool isStringLiteralInit() const;
>>> 
>>> +  /// Is this a transparent initializer list (that is, an InitListExpr 
>>> that is
>>> +  /// purely syntactic, and whose semantics are that of the sole contained
>>> +  /// initializer)?
>>> +  bool isTransparent() const;
>>> +
>>> SourceLocation getLBraceLoc() const { return LBraceLoc; }
>>> void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
>>> SourceLocation getRBraceLoc() const { return RBraceLoc; }
>>> 
>>> Modified: cfe/trunk/lib/AST/Expr.cpp
>>> URL: 
>>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=288866=288865=288866=diff
>>> ==
>>> --- cfe/trunk/lib/AST/Expr.cpp (original)
>>> +++ cfe/trunk/lib/AST/Expr.cpp Tue Dec  6 17:52:28 2016
>>> @@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit()
>>> return isa(Init) || isa(Init);
>>> }
>>> 
>>> +bool InitListExpr::isTransparent() const {
>>> +  assert(isSemanticForm() && "syntactic form never semantically 
>>> transparent");
>>> +
>>> +  // A glvalue InitListExpr is always just sugar.
>>> +  if (isGLValue()) {
>>> +assert(getNumInits() == 1 && "multiple inits in glvalue init list");
>>> +return true;
>>> +  }
>>> +
>>> +  // Otherwise, we're sugar if and only if we have exactly one initializer 
>>> that
>>> +  // is of the same type.
>>> +  if (getNumInits() != 1 || !getInit(0))
>>> +return false;
>>> +
>>> +  return getType().getCanonicalType() ==
>>> + getInit(0)->getType().getCanonicalType();
>>> +}
>>> +
>>> SourceLocation InitListExpr::getLocStart() const {
>>> if (InitListExpr *SyntacticForm = getSyntacticForm())
>>>   return SyntacticForm->getLocStart();
>>> @@ -2246,12 +2264,15 @@ bool 

Re: r288866 - [c++17] P0135R1: Guaranteed copy elision.

2016-12-08 Thread Richard Smith via cfe-commits
On 8 Dec 2016 7:17 pm, "Duncan P. N. Exon Smith via cfe-commits" <
cfe-commits@lists.llvm.org> wrote:

+Eric, Marshall

I haven't looked, but: from the test name, "copy.fail.cpp", I suspect there
is a bug/incompatibility in the test.  It likely relies on the compiler
trying (and failing) to copy something in a context where r288866
guarantees that there is no copy.


Was this not fixed by "[libcxx] r289033 - Avoid C++17 guaranteed copy
elision when testing for non-copyability"?

> On 2016-Dec-08, at 18:00, Adrian Prantl  wrote:
>
> Hi Richard,
>
> at this point this is more a heads-up than anything actionable, but I
wanted to let you know that I bisected this bot failure (
http://lab.llvm.org:8080/green/job/clang-stage2-cmake-
RgSan_check/2721/consoleFull#10584592348254eaf0-7326-4999-85b0-388101f2d404)
of std/input.output/stream.buffers/streambuf/streambuf.cons/copy.fail.cpp
down to this commit.
>
> I will follow up once I have a better understanding what is going on
there.
>
> -- adrian
>
>> On Dec 6, 2016, at 3:52 PM, Richard Smith via cfe-commits <
cfe-commits@lists.llvm.org> wrote:
>>
>> Author: rsmith
>> Date: Tue Dec  6 17:52:28 2016
>> New Revision: 288866
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=288866=rev
>> Log:
>> [c++17] P0135R1: Guaranteed copy elision.
>>
>> When an object of class type is initialized from a prvalue of the same
type
>> (ignoring cv qualifications), use the prvalue to initialize the object
directly
>> instead of inserting a redundant elidable call to a copy constructor.
>>
>> Added:
>>   cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
>>   cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp
>> Modified:
>>   cfe/trunk/include/clang/AST/Expr.h
>>   cfe/trunk/lib/AST/Expr.cpp
>>   cfe/trunk/lib/AST/ExprConstant.cpp
>>   cfe/trunk/lib/CodeGen/CGExpr.cpp
>>   cfe/trunk/lib/CodeGen/CGExprAgg.cpp
>>   cfe/trunk/lib/CodeGen/CGExprConstant.cpp
>>   cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>   cfe/trunk/lib/Sema/SemaInit.cpp
>>   cfe/trunk/lib/Sema/SemaOverload.cpp
>>   cfe/trunk/test/CXX/drs/dr0xx.cpp
>>   cfe/trunk/test/CXX/drs/dr10xx.cpp
>>   cfe/trunk/test/CXX/drs/dr1xx.cpp
>>   cfe/trunk/test/CXX/drs/dr4xx.cpp
>>   cfe/trunk/test/SemaCXX/aggregate-initialization.cpp
>>   cfe/trunk/www/cxx_dr_status.html
>>   cfe/trunk/www/cxx_status.html
>>
>> Modified: cfe/trunk/include/clang/AST/Expr.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/
clang/AST/Expr.h?rev=288866=288865=288866=diff
>> 
==
>> --- cfe/trunk/include/clang/AST/Expr.h (original)
>> +++ cfe/trunk/include/clang/AST/Expr.h Tue Dec  6 17:52:28 2016
>> @@ -3786,7 +3786,7 @@ public:
>>
>>  /// \brief Build an empty initializer list.
>>  explicit InitListExpr(EmptyShell Empty)
>> -: Expr(InitListExprClass, Empty) { }
>> +: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
>>
>>  unsigned getNumInits() const { return InitExprs.size(); }
>>
>> @@ -3894,6 +3894,11 @@ public:
>>  // literal or an @encode?
>>  bool isStringLiteralInit() const;
>>
>> +  /// Is this a transparent initializer list (that is, an InitListExpr
that is
>> +  /// purely syntactic, and whose semantics are that of the sole
contained
>> +  /// initializer)?
>> +  bool isTransparent() const;
>> +
>>  SourceLocation getLBraceLoc() const { return LBraceLoc; }
>>  void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
>>  SourceLocation getRBraceLoc() const { return RBraceLoc; }
>>
>> Modified: cfe/trunk/lib/AST/Expr.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/
Expr.cpp?rev=288866=288865=288866=diff
>> 
==
>> --- cfe/trunk/lib/AST/Expr.cpp (original)
>> +++ cfe/trunk/lib/AST/Expr.cpp Tue Dec  6 17:52:28 2016
>> @@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit()
>>  return isa(Init) || isa(Init);
>> }
>>
>> +bool InitListExpr::isTransparent() const {
>> +  assert(isSemanticForm() && "syntactic form never semantically
transparent");
>> +
>> +  // A glvalue InitListExpr is always just sugar.
>> +  if (isGLValue()) {
>> +assert(getNumInits() == 1 && "multiple inits in glvalue init list");
>> +return true;
>> +  }
>> +
>> +  // Otherwise, we're sugar if and only if we have exactly one
initializer that
>> +  // is of the same type.
>> +  if (getNumInits() != 1 || !getInit(0))
>> +return false;
>> +
>> +  return getType().getCanonicalType() ==
>> + getInit(0)->getType().getCanonicalType();
>> +}
>> +
>> SourceLocation InitListExpr::getLocStart() const {
>>  if (InitListExpr *SyntacticForm = getSyntacticForm())
>>return SyntacticForm->getLocStart();
>> @@ -2246,12 +2264,15 @@ bool Expr::isUnusedResultAWarning(const
>>// effects (e.g. a placement new with an uninitialized POD).
>>  case CXXDeleteExprClass:
>>return false;
>> +  case MaterializeTemporaryExprClass:
>> +return 

Re: r288866 - [c++17] P0135R1: Guaranteed copy elision.

2016-12-08 Thread Duncan P. N. Exon Smith via cfe-commits
+Eric, Marshall

I haven't looked, but: from the test name, "copy.fail.cpp", I suspect there is 
a bug/incompatibility in the test.  It likely relies on the compiler trying 
(and failing) to copy something in a context where r288866 guarantees that 
there is no copy.

> On 2016-Dec-08, at 18:00, Adrian Prantl  wrote:
> 
> Hi Richard,
> 
> at this point this is more a heads-up than anything actionable, but I wanted 
> to let you know that I bisected this bot failure 
> (http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/2721/consoleFull#10584592348254eaf0-7326-4999-85b0-388101f2d404)
>  of std/input.output/stream.buffers/streambuf/streambuf.cons/copy.fail.cpp 
> down to this commit.
> 
> I will follow up once I have a better understanding what is going on there.
> 
> -- adrian
> 
>> On Dec 6, 2016, at 3:52 PM, Richard Smith via cfe-commits 
>>  wrote:
>> 
>> Author: rsmith
>> Date: Tue Dec  6 17:52:28 2016
>> New Revision: 288866
>> 
>> URL: http://llvm.org/viewvc/llvm-project?rev=288866=rev
>> Log:
>> [c++17] P0135R1: Guaranteed copy elision.
>> 
>> When an object of class type is initialized from a prvalue of the same type
>> (ignoring cv qualifications), use the prvalue to initialize the object 
>> directly
>> instead of inserting a redundant elidable call to a copy constructor.
>> 
>> Added:
>>   cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
>>   cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp
>> Modified:
>>   cfe/trunk/include/clang/AST/Expr.h
>>   cfe/trunk/lib/AST/Expr.cpp
>>   cfe/trunk/lib/AST/ExprConstant.cpp
>>   cfe/trunk/lib/CodeGen/CGExpr.cpp
>>   cfe/trunk/lib/CodeGen/CGExprAgg.cpp
>>   cfe/trunk/lib/CodeGen/CGExprConstant.cpp
>>   cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>   cfe/trunk/lib/Sema/SemaInit.cpp
>>   cfe/trunk/lib/Sema/SemaOverload.cpp
>>   cfe/trunk/test/CXX/drs/dr0xx.cpp
>>   cfe/trunk/test/CXX/drs/dr10xx.cpp
>>   cfe/trunk/test/CXX/drs/dr1xx.cpp
>>   cfe/trunk/test/CXX/drs/dr4xx.cpp
>>   cfe/trunk/test/SemaCXX/aggregate-initialization.cpp
>>   cfe/trunk/www/cxx_dr_status.html
>>   cfe/trunk/www/cxx_status.html
>> 
>> Modified: cfe/trunk/include/clang/AST/Expr.h
>> URL: 
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=288866=288865=288866=diff
>> ==
>> --- cfe/trunk/include/clang/AST/Expr.h (original)
>> +++ cfe/trunk/include/clang/AST/Expr.h Tue Dec  6 17:52:28 2016
>> @@ -3786,7 +3786,7 @@ public:
>> 
>>  /// \brief Build an empty initializer list.
>>  explicit InitListExpr(EmptyShell Empty)
>> -: Expr(InitListExprClass, Empty) { }
>> +: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
>> 
>>  unsigned getNumInits() const { return InitExprs.size(); }
>> 
>> @@ -3894,6 +3894,11 @@ public:
>>  // literal or an @encode?
>>  bool isStringLiteralInit() const;
>> 
>> +  /// Is this a transparent initializer list (that is, an InitListExpr that 
>> is
>> +  /// purely syntactic, and whose semantics are that of the sole contained
>> +  /// initializer)?
>> +  bool isTransparent() const;
>> +
>>  SourceLocation getLBraceLoc() const { return LBraceLoc; }
>>  void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
>>  SourceLocation getRBraceLoc() const { return RBraceLoc; }
>> 
>> Modified: cfe/trunk/lib/AST/Expr.cpp
>> URL: 
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=288866=288865=288866=diff
>> ==
>> --- cfe/trunk/lib/AST/Expr.cpp (original)
>> +++ cfe/trunk/lib/AST/Expr.cpp Tue Dec  6 17:52:28 2016
>> @@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit()
>>  return isa(Init) || isa(Init);
>> }
>> 
>> +bool InitListExpr::isTransparent() const {
>> +  assert(isSemanticForm() && "syntactic form never semantically 
>> transparent");
>> +
>> +  // A glvalue InitListExpr is always just sugar.
>> +  if (isGLValue()) {
>> +assert(getNumInits() == 1 && "multiple inits in glvalue init list");
>> +return true;
>> +  }
>> +
>> +  // Otherwise, we're sugar if and only if we have exactly one initializer 
>> that
>> +  // is of the same type.
>> +  if (getNumInits() != 1 || !getInit(0))
>> +return false;
>> +
>> +  return getType().getCanonicalType() ==
>> + getInit(0)->getType().getCanonicalType();
>> +}
>> +
>> SourceLocation InitListExpr::getLocStart() const {
>>  if (InitListExpr *SyntacticForm = getSyntacticForm())
>>return SyntacticForm->getLocStart();
>> @@ -2246,12 +2264,15 @@ bool Expr::isUnusedResultAWarning(const
>>// effects (e.g. a placement new with an uninitialized POD).
>>  case CXXDeleteExprClass:
>>return false;
>> +  case MaterializeTemporaryExprClass:
>> +return cast(this)->GetTemporaryExpr()
>> +   ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
>>  case CXXBindTemporaryExprClass:
>> -return (cast(this)
>> -

Re: r288866 - [c++17] P0135R1: Guaranteed copy elision.

2016-12-08 Thread Adrian Prantl via cfe-commits
Hi Richard,

at this point this is more a heads-up than anything actionable, but I wanted to 
let you know that I bisected this bot failure 
(http://lab.llvm.org:8080/green/job/clang-stage2-cmake-RgSan_check/2721/consoleFull#10584592348254eaf0-7326-4999-85b0-388101f2d404)
 of std/input.output/stream.buffers/streambuf/streambuf.cons/copy.fail.cpp down 
to this commit.

I will follow up once I have a better understanding what is going on there.

-- adrian

> On Dec 6, 2016, at 3:52 PM, Richard Smith via cfe-commits 
>  wrote:
> 
> Author: rsmith
> Date: Tue Dec  6 17:52:28 2016
> New Revision: 288866
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=288866=rev
> Log:
> [c++17] P0135R1: Guaranteed copy elision.
> 
> When an object of class type is initialized from a prvalue of the same type
> (ignoring cv qualifications), use the prvalue to initialize the object 
> directly
> instead of inserting a redundant elidable call to a copy constructor.
> 
> Added:
>cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
>cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp
> Modified:
>cfe/trunk/include/clang/AST/Expr.h
>cfe/trunk/lib/AST/Expr.cpp
>cfe/trunk/lib/AST/ExprConstant.cpp
>cfe/trunk/lib/CodeGen/CGExpr.cpp
>cfe/trunk/lib/CodeGen/CGExprAgg.cpp
>cfe/trunk/lib/CodeGen/CGExprConstant.cpp
>cfe/trunk/lib/Sema/SemaExprCXX.cpp
>cfe/trunk/lib/Sema/SemaInit.cpp
>cfe/trunk/lib/Sema/SemaOverload.cpp
>cfe/trunk/test/CXX/drs/dr0xx.cpp
>cfe/trunk/test/CXX/drs/dr10xx.cpp
>cfe/trunk/test/CXX/drs/dr1xx.cpp
>cfe/trunk/test/CXX/drs/dr4xx.cpp
>cfe/trunk/test/SemaCXX/aggregate-initialization.cpp
>cfe/trunk/www/cxx_dr_status.html
>cfe/trunk/www/cxx_status.html
> 
> Modified: cfe/trunk/include/clang/AST/Expr.h
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=288866=288865=288866=diff
> ==
> --- cfe/trunk/include/clang/AST/Expr.h (original)
> +++ cfe/trunk/include/clang/AST/Expr.h Tue Dec  6 17:52:28 2016
> @@ -3786,7 +3786,7 @@ public:
> 
>   /// \brief Build an empty initializer list.
>   explicit InitListExpr(EmptyShell Empty)
> -: Expr(InitListExprClass, Empty) { }
> +: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
> 
>   unsigned getNumInits() const { return InitExprs.size(); }
> 
> @@ -3894,6 +3894,11 @@ public:
>   // literal or an @encode?
>   bool isStringLiteralInit() const;
> 
> +  /// Is this a transparent initializer list (that is, an InitListExpr that 
> is
> +  /// purely syntactic, and whose semantics are that of the sole contained
> +  /// initializer)?
> +  bool isTransparent() const;
> +
>   SourceLocation getLBraceLoc() const { return LBraceLoc; }
>   void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
>   SourceLocation getRBraceLoc() const { return RBraceLoc; }
> 
> Modified: cfe/trunk/lib/AST/Expr.cpp
> URL: 
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=288866=288865=288866=diff
> ==
> --- cfe/trunk/lib/AST/Expr.cpp (original)
> +++ cfe/trunk/lib/AST/Expr.cpp Tue Dec  6 17:52:28 2016
> @@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit()
>   return isa(Init) || isa(Init);
> }
> 
> +bool InitListExpr::isTransparent() const {
> +  assert(isSemanticForm() && "syntactic form never semantically 
> transparent");
> +
> +  // A glvalue InitListExpr is always just sugar.
> +  if (isGLValue()) {
> +assert(getNumInits() == 1 && "multiple inits in glvalue init list");
> +return true;
> +  }
> +
> +  // Otherwise, we're sugar if and only if we have exactly one initializer 
> that
> +  // is of the same type.
> +  if (getNumInits() != 1 || !getInit(0))
> +return false;
> +
> +  return getType().getCanonicalType() ==
> + getInit(0)->getType().getCanonicalType();
> +}
> +
> SourceLocation InitListExpr::getLocStart() const {
>   if (InitListExpr *SyntacticForm = getSyntacticForm())
> return SyntacticForm->getLocStart();
> @@ -2246,12 +2264,15 @@ bool Expr::isUnusedResultAWarning(const
> // effects (e.g. a placement new with an uninitialized POD).
>   case CXXDeleteExprClass:
> return false;
> +  case MaterializeTemporaryExprClass:
> +return cast(this)->GetTemporaryExpr()
> +   ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
>   case CXXBindTemporaryExprClass:
> -return (cast(this)
> -->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
> +return cast(this)->getSubExpr()
> +   ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
>   case ExprWithCleanupsClass:
> -return (cast(this)
> -->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
> +return cast(this)->getSubExpr()
> +   ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
>   }
> }
> 
> 
> Modified: 

r288866 - [c++17] P0135R1: Guaranteed copy elision.

2016-12-06 Thread Richard Smith via cfe-commits
Author: rsmith
Date: Tue Dec  6 17:52:28 2016
New Revision: 288866

URL: http://llvm.org/viewvc/llvm-project?rev=288866=rev
Log:
[c++17] P0135R1: Guaranteed copy elision.

When an object of class type is initialized from a prvalue of the same type
(ignoring cv qualifications), use the prvalue to initialize the object directly
instead of inserting a redundant elidable call to a copy constructor.

Added:
cfe/trunk/test/CodeGenCXX/cxx1z-copy-omission.cpp
cfe/trunk/test/SemaCXX/cxx1z-copy-omission.cpp
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprAgg.cpp
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/lib/Sema/SemaOverload.cpp
cfe/trunk/test/CXX/drs/dr0xx.cpp
cfe/trunk/test/CXX/drs/dr10xx.cpp
cfe/trunk/test/CXX/drs/dr1xx.cpp
cfe/trunk/test/CXX/drs/dr4xx.cpp
cfe/trunk/test/SemaCXX/aggregate-initialization.cpp
cfe/trunk/www/cxx_dr_status.html
cfe/trunk/www/cxx_status.html

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=288866=288865=288866=diff
==
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Tue Dec  6 17:52:28 2016
@@ -3786,7 +3786,7 @@ public:
 
   /// \brief Build an empty initializer list.
   explicit InitListExpr(EmptyShell Empty)
-: Expr(InitListExprClass, Empty) { }
+: Expr(InitListExprClass, Empty), AltForm(nullptr, true) { }
 
   unsigned getNumInits() const { return InitExprs.size(); }
 
@@ -3894,6 +3894,11 @@ public:
   // literal or an @encode?
   bool isStringLiteralInit() const;
 
+  /// Is this a transparent initializer list (that is, an InitListExpr that is
+  /// purely syntactic, and whose semantics are that of the sole contained
+  /// initializer)?
+  bool isTransparent() const;
+
   SourceLocation getLBraceLoc() const { return LBraceLoc; }
   void setLBraceLoc(SourceLocation Loc) { LBraceLoc = Loc; }
   SourceLocation getRBraceLoc() const { return RBraceLoc; }

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=288866=288865=288866=diff
==
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Dec  6 17:52:28 2016
@@ -1864,6 +1864,24 @@ bool InitListExpr::isStringLiteralInit()
   return isa(Init) || isa(Init);
 }
 
+bool InitListExpr::isTransparent() const {
+  assert(isSemanticForm() && "syntactic form never semantically transparent");
+
+  // A glvalue InitListExpr is always just sugar.
+  if (isGLValue()) {
+assert(getNumInits() == 1 && "multiple inits in glvalue init list");
+return true;
+  }
+
+  // Otherwise, we're sugar if and only if we have exactly one initializer that
+  // is of the same type.
+  if (getNumInits() != 1 || !getInit(0))
+return false;
+
+  return getType().getCanonicalType() ==
+ getInit(0)->getType().getCanonicalType();
+}
+
 SourceLocation InitListExpr::getLocStart() const {
   if (InitListExpr *SyntacticForm = getSyntacticForm())
 return SyntacticForm->getLocStart();
@@ -2246,12 +2264,15 @@ bool Expr::isUnusedResultAWarning(const
 // effects (e.g. a placement new with an uninitialized POD).
   case CXXDeleteExprClass:
 return false;
+  case MaterializeTemporaryExprClass:
+return cast(this)->GetTemporaryExpr()
+   ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
   case CXXBindTemporaryExprClass:
-return (cast(this)
-->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
+return cast(this)->getSubExpr()
+   ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
   case ExprWithCleanupsClass:
-return (cast(this)
-->getSubExpr()->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx));
+return cast(this)->getSubExpr()
+   ->isUnusedResultAWarning(WarnE, Loc, R1, R2, Ctx);
   }
 }
 

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=288866=288865=288866=diff
==
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Dec  6 17:52:28 2016
@@ -5670,6 +5670,9 @@ bool RecordExprEvaluator::VisitCastExpr(
 }
 
 bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
+  if (E->isTransparent())
+return Visit(E->getInit(0));
+
   const RecordDecl *RD = E->getType()->castAs()->getDecl();
   if (RD->isInvalidDecl()) return false;
   const ASTRecordLayout  = Info.Ctx.getASTRecordLayout(RD);

Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: