Author: Timm Bäder Date: 2024-05-21T12:51:30+02:00 New Revision: d9c27cafdb1c16fff837a3eb0ec0fb2ad912bc50
URL: https://github.com/llvm/llvm-project/commit/d9c27cafdb1c16fff837a3eb0ec0fb2ad912bc50 DIFF: https://github.com/llvm/llvm-project/commit/d9c27cafdb1c16fff837a3eb0ec0fb2ad912bc50.diff LOG: [clang][Interp] Fix discarding construct exprs with zero initializers We need to create the temporary earlier so the visitZeroRecordInitializer() call has access to it. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/test/AST/Interp/records.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 640311e1444bf..a61270c77ea8f 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2088,6 +2088,21 @@ bool ByteCodeExprGen<Emitter>::VisitCXXConstructExpr( if (T->isRecordType()) { const CXXConstructorDecl *Ctor = E->getConstructor(); + // If we're discarding a construct expression, we still need + // to allocate a variable and call the constructor and destructor. + if (DiscardResult) { + if (Ctor->isTrivial()) + return true; + assert(!Initializing); + std::optional<unsigned> LocalIndex = allocateLocal(E); + + if (!LocalIndex) + return false; + + if (!this->emitGetPtrLocal(*LocalIndex, E)) + return false; + } + // Zero initialization. if (E->requiresZeroInitialization()) { const Record *R = getRecord(E->getType()); @@ -2108,19 +2123,6 @@ bool ByteCodeExprGen<Emitter>::VisitCXXConstructExpr( assert(Func->hasThisPointer()); assert(!Func->hasRVO()); - // If we're discarding a construct expression, we still need - // to allocate a variable and call the constructor and destructor. - if (DiscardResult) { - assert(!Initializing); - std::optional<unsigned> LocalIndex = allocateLocal(E); - - if (!LocalIndex) - return false; - - if (!this->emitGetPtrLocal(*LocalIndex, E)) - return false; - } - // The This pointer is already on the stack because this is an initializer, // but we need to dup() so the call() below has its own copy. if (!this->emitDupPtr(E)) diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 41be9b71a27f9..3a5ecd291a568 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -1459,3 +1459,13 @@ namespace TemporaryWithInvalidDestructor { // both-note {{in call to}} #endif } + +namespace IgnoredCtorWithZeroInit { + struct S { + int a; + }; + + bool get_status() { + return (S(), true); + } +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits