https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/108811
We need to be a little more careful here with whether or nor we are able to do the cast at all or not. >From 462cd5016c72728ed120773a0da0aab1895649b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com> Date: Sat, 14 Sep 2024 14:57:18 +0200 Subject: [PATCH] [clang][bytecode] Fix reinterpret_casts from pointer to non-pointers We need to be a little more careful here with whether or nor we are able to do the cast at all or not. --- clang/lib/AST/ByteCode/Compiler.cpp | 38 +++++++++++++++++++++++++---- clang/test/AST/ByteCode/invalid.cpp | 3 +++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 265350e44d95b9..fe9da7801185e3 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -2613,18 +2613,46 @@ bool Compiler<Emitter>::VisitCXXReinterpretCastExpr( const CXXReinterpretCastExpr *E) { const Expr *SubExpr = E->getSubExpr(); - bool Fatal = false; std::optional<PrimType> FromT = classify(SubExpr); std::optional<PrimType> ToT = classify(E); + if (!FromT || !ToT) - Fatal = true; - else - Fatal = (ToT != FromT); + return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, E); + + if (FromT == PT_Ptr || ToT == PT_Ptr) { + // Both types could be PT_Ptr because their expressions are glvalues. + std::optional<PrimType> PointeeFromT; + if (SubExpr->getType()->isPointerOrReferenceType()) + PointeeFromT = classify(SubExpr->getType()->getPointeeType()); + else + PointeeFromT = classify(SubExpr->getType()); + + std::optional<PrimType> PointeeToT; + if (E->getType()->isPointerOrReferenceType()) + PointeeToT = classify(E->getType()->getPointeeType()); + else + PointeeToT = classify(E->getType()); + + bool Fatal = true; + if (PointeeToT && PointeeFromT) { + if (isIntegralType(*PointeeFromT) && isIntegralType(*PointeeToT)) + Fatal = false; + } + + if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E)) + return false; + + if (E->getCastKind() == CK_LValueBitCast) + return this->delegate(SubExpr); + return this->VisitCastExpr(E); + } + // Try to actually do the cast. + bool Fatal = (ToT != FromT); if (!this->emitInvalidCast(CastKind::Reinterpret, Fatal, E)) return false; - return this->delegate(SubExpr); + return this->VisitCastExpr(E); } template <class Emitter> diff --git a/clang/test/AST/ByteCode/invalid.cpp b/clang/test/AST/ByteCode/invalid.cpp index 13ba84bcad1040..2a6c2d13e84673 100644 --- a/clang/test/AST/ByteCode/invalid.cpp +++ b/clang/test/AST/ByteCode/invalid.cpp @@ -54,4 +54,7 @@ namespace Casts { B b; (void)*reinterpret_cast<void*>(&b); // both-error {{indirection not permitted on operand of type 'void *'}} } + + /// Just make sure this doesn't crash. + float PR9558 = reinterpret_cast<const float&>("asd"); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits