Author: Timm Bäder Date: 2024-04-29T13:02:31+02:00 New Revision: f2452d4b689469b6da63d9e8ffa96eaf4b39ac5d
URL: https://github.com/llvm/llvm-project/commit/f2452d4b689469b6da63d9e8ffa96eaf4b39ac5d DIFF: https://github.com/llvm/llvm-project/commit/f2452d4b689469b6da63d9e8ffa96eaf4b39ac5d.diff LOG: [clang][Interp] Implement zero-init for record types 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 588ffa55c11e61..aebefd716e27cc 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -924,8 +924,31 @@ bool ByteCodeExprGen<Emitter>::VisitImplicitValueInitExpr(const ImplicitValueIni if (std::optional<PrimType> T = classify(QT)) return this->visitZeroInitializer(*T, QT, E); - if (QT->isRecordType()) - return false; + if (QT->isRecordType()) { + const RecordDecl *RD = QT->getAsRecordDecl(); + assert(RD); + if (RD->isInvalidDecl()) + return false; + if (RD->isUnion()) { + // C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the + // object's first non-static named data member is zero-initialized + // FIXME + return false; + } + + if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); + CXXRD && CXXRD->getNumVBases() > 0) { + // TODO: Diagnose. + return false; + } + + const Record *R = getRecord(QT); + if (!R) + return false; + + assert(Initializing); + return this->visitZeroRecordInitializer(R, E); + } if (QT->isIncompleteArrayType()) return true; diff --git a/clang/test/AST/Interp/records.cpp b/clang/test/AST/Interp/records.cpp index 9307b9c090c5dd..ba5c58c96c7bf5 100644 --- a/clang/test/AST/Interp/records.cpp +++ b/clang/test/AST/Interp/records.cpp @@ -90,8 +90,7 @@ struct Ints2 { int a = 10; int b; }; -constexpr Ints2 ints22; // both-error {{without a user-provided default constructor}} \ - // expected-error {{must be initialized by a constant expression}} +constexpr Ints2 ints22; // both-error {{without a user-provided default constructor}} constexpr Ints2 I2 = Ints2{12, 25}; static_assert(I2.a == 12, ""); @@ -1409,3 +1408,15 @@ namespace VirtualBases { static_assert((X*)(Y1*)&z != (X*)(Y2*)&z, ""); } } + +namespace ZeroInit { + struct S3 { + S3() = default; + S3(const S3&) = default; + S3(S3&&) = default; + constexpr S3(int n) : n(n) {} + int n; + }; + 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, ""); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits