diff options
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.cpp')
| -rw-r--r-- | clang/lib/AST/ByteCode/Compiler.cpp | 20 |
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) { |
