Author: Timm Bäder Date: 2024-05-02T13:20:04+02:00 New Revision: 5d9889a6c6c97c92380c8eee48eaa35067f63766
URL: https://github.com/llvm/llvm-project/commit/5d9889a6c6c97c92380c8eee48eaa35067f63766 DIFF: https://github.com/llvm/llvm-project/commit/5d9889a6c6c97c92380c8eee48eaa35067f63766.diff LOG: [clang][Interp] Fix zero-initializing records with non-trivial ctors We need to do the zero-init and then subsequently call the constructor. 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 f1a51e81a92c2d..2dfa726cc75256 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -2095,10 +2095,16 @@ bool ByteCodeExprGen<Emitter>::VisitCXXConstructExpr( if (T->isRecordType()) { const CXXConstructorDecl *Ctor = E->getConstructor(); - // Trivial zero initialization. - if (E->requiresZeroInitialization() && Ctor->isTrivial()) { + // Zero initialization. + if (E->requiresZeroInitialization()) { const Record *R = getRecord(E->getType()); - return this->visitZeroRecordInitializer(R, E); + + if (!this->visitZeroRecordInitializer(R, E)) + return false; + + // If the constructor is trivial anyway, we're done. + if (Ctor->isTrivial()) + return true; } const Function *Func = getFunction(Ctor); diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 771e5adfca34a4..26efd6896a9f7e 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -999,10 +999,9 @@ namespace TemporaryObjectExpr { F f{12}; }; constexpr int foo(S x) { - return x.a; // expected-note {{read of uninitialized object}} + return x.a; } - static_assert(foo(S()) == 0, ""); // expected-error {{not an integral constant expression}} \ - // expected-note {{in call to}} + static_assert(foo(S()) == 0, ""); }; #endif } @@ -1425,6 +1424,11 @@ namespace ZeroInit { }; constexpr S3 s3d; // both-error {{default initialization of an object of const type 'const S3' without a user-provided default constructor}} static_assert(s3d.n == 0, ""); + + struct P { + int a = 10; + }; + static_assert(P().a == 10, ""); } namespace { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits