aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 6c08846..4e63400 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -209,6 +209,19 @@ private:
} // namespace clang
template <class Emitter>
+bool Compiler<Emitter>::isValidBitCast(const CastExpr *E) {
+ QualType FromTy = E->getSubExpr()->getType()->getPointeeType();
+ QualType ToTy = E->getType()->getPointeeType();
+
+ if (classify(FromTy) == classify(ToTy))
+ return true;
+
+ if (FromTy->isVoidType() || ToTy->isVoidType())
+ return true;
+ return false;
+}
+
+template <class Emitter>
bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
const Expr *SubExpr = CE->getSubExpr();
@@ -476,8 +489,9 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
return this->delegate(SubExpr);
case CK_BitCast: {
+ QualType CETy = CE->getType();
// Reject bitcasts to atomic types.
- if (CE->getType()->isAtomicType()) {
+ if (CETy->isAtomicType()) {
if (!this->discard(SubExpr))
return false;
return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, CE);
@@ -492,6 +506,10 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
if (!FromT || !ToT)
return false;
+ if (!this->isValidBitCast(CE) &&
+ !this->emitInvalidCast(CastKind::ReinterpretLike, /*Fatal=*/false, CE))
+ return false;
+
assert(isPtrType(*FromT));
assert(isPtrType(*ToT));
if (FromT == ToT) {