[clang] 0bc8168 - [clang][bytecode] Fix reinterpret_casts from pointer to non-pointers (#108811)
via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 16 08:35:42 PDT 2024
Author: Timm Baeder
Date: 2024-09-16T17:35:38+02:00
New Revision: 0bc8168070677ef08d58864477d95ebdef917d0c
URL: https://github.com/llvm/llvm-project/commit/0bc8168070677ef08d58864477d95ebdef917d0c
DIFF: https://github.com/llvm/llvm-project/commit/0bc8168070677ef08d58864477d95ebdef917d0c.diff
LOG: [clang][bytecode] Fix reinterpret_casts from pointer to non-pointers (#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.
Added:
Modified:
clang/lib/AST/ByteCode/Compiler.cpp
clang/test/AST/ByteCode/invalid.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 5247b8cadf8d4f..7e0775a51aee61 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2638,18 +2638,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");
}
More information about the cfe-commits
mailing list