@@ -248,12 +248,10 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
248248 if (BitWidth.isZero ())
249249 return true ;
250250
251- if (!P.isInitialized ()) {
252- assert (false && " Implement uninitialized value tracking" );
253- return ReturnOnUninit;
254- }
251+ // Bits will be left uninitialized and diagnosed when reading.
252+ if (!P.isInitialized ())
253+ return true ;
255254
256- assert (P.isInitialized ());
257255 if (T == PT_Ptr) {
258256 assert (P.getType ()->isNullPtrType ());
259257 // Clang treats nullptr_t has having NO bits in its value
@@ -262,6 +260,7 @@ static bool readPointerToBuffer(const Context &Ctx, const Pointer &FromPtr,
262260 return true ;
263261 }
264262
263+ assert (P.isInitialized ());
265264 auto Buff =
266265 std::make_unique<std::byte[]>(ObjectReprChars.getQuantity ());
267266 // Work around floating point types that contain unused padding bytes.
@@ -355,10 +354,11 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
355354 ToPtr, S.getContext (), Buffer.size (),
356355 [&](const Pointer &P, PrimType T, Bits BitOffset,
357356 bool PackedBools) -> bool {
358- CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (P.getType ());
357+ QualType PtrType = P.getType ();
358+ CharUnits ObjectReprChars = ASTCtx.getTypeSizeInChars (PtrType);
359359 Bits FullBitWidth = Bits (ASTCtx.toBits (ObjectReprChars));
360360 if (T == PT_Float) {
361- const auto &Semantics = ASTCtx.getFloatTypeSemantics (P. getType () );
361+ const auto &Semantics = ASTCtx.getFloatTypeSemantics (PtrType );
362362 Bits NumBits = Bits (llvm::APFloatBase::getSizeInBits (Semantics));
363363 assert (NumBits.isFullByte ());
364364 assert (NumBits.getQuantity () <= FullBitWidth.getQuantity ());
@@ -382,6 +382,25 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
382382 else
383383 BitWidth = FullBitWidth;
384384
385+ // If any of the bits are uninitialized, we need to abort unless the
386+ // target type is std::byte or unsigned char.
387+ bool Initialized = Buffer.rangeInitialized (BitOffset, BitWidth);
388+ if (!Initialized) {
389+ if (!PtrType->isStdByteType () &&
390+ !PtrType->isSpecificBuiltinType (BuiltinType::UChar) &&
391+ !PtrType->isSpecificBuiltinType (BuiltinType::Char_U)) {
392+ const Expr *E = S.Current ->getExpr (OpPC);
393+ S.FFDiag (E, diag::note_constexpr_bit_cast_indet_dest)
394+ << PtrType << S.getLangOpts ().CharIsSigned
395+ << E->getSourceRange ();
396+
397+ return false ;
398+ }
399+ llvm::errs () << " Not all initialized\n " ;
400+ return true ;
401+ }
402+ llvm::errs () << " All initialized.\n " ;
403+
385404 auto Memory = Buffer.copyBits (BitOffset, BitWidth, FullBitWidth,
386405 TargetEndianness);
387406 if (llvm::sys::IsBigEndianHost)
0 commit comments