Re: r288866 - [c++17] P0135R1: Guaranteed copy elision.
> 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.
> On 2016-Dec-08, at 19:29, Richard Smithwrote: > > 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.
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.
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 Prantlwrote: > > 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.
+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 Prantlwrote: > > 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.
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.
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: