llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: None (term-est) <details> <summary>Changes</summary> Fixes #<!-- -->163778 (fix might be indirect?) Prevents emitting byte-code for UB casts --- Full diff: https://github.com/llvm/llvm-project/pull/163809.diff 2 Files Affected: - (modified) clang/lib/AST/ByteCode/Compiler.cpp (+44) - (modified) clang/lib/AST/ByteCode/Compiler.h (+2) ``````````diff diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp index 74cae030bb9bb..c30262dd8a323 100644 --- a/clang/lib/AST/ByteCode/Compiler.cpp +++ b/clang/lib/AST/ByteCode/Compiler.cpp @@ -212,6 +212,10 @@ template <class Emitter> bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { const Expr *SubExpr = CE->getSubExpr(); + if (isPunningDereference(SubExpr)) + return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, + CE); + if (DiscardResult) return this->delegate(SubExpr); @@ -5511,6 +5515,46 @@ bool Compiler<Emitter>::maybeEmitDeferredVarInit(const VarDecl *VD) { return true; } +template <class Emitter> +bool Compiler<Emitter>::isPunningDereference(const Expr *E) +{ + E = E->IgnoreParenImpCasts(); + + const auto *UO = dyn_cast<UnaryOperator>(E); + if (!UO || UO->getOpcode() != UO_Deref) + return false; + + const Expr *Base = UO->getSubExpr()->IgnoreParenImpCasts(); + const auto *Cast = dyn_cast<CastExpr>(Base); + if (!Cast) + return false; + + // Only consider reinterpret-ish casts + switch (Cast->getCastKind()) { + case CK_BitCast: + case CK_PointerToIntegral: + case CK_IntegralToPointer: + case CK_AddressSpaceConversion: + break; + default: + return false; // CK_NoOp etc. are fine + } + + QualType DestPtrTy = Cast->getType(); + QualType SrcPtrTy = Cast->getSubExpr()->getType(); + if (!DestPtrTy->isPointerType() || !SrcPtrTy->isPointerType()) + return true; // super fishy, treat it as a pun + + QualType DestPointee = DestPtrTy->getPointeeType(); + QualType SrcPointee = SrcPtrTy->getPointeeType(); + + // If pointee types differ (ignoring qualifiers), its a pun + if (!Ctx.getASTContext().hasSameUnqualifiedType(DestPointee, SrcPointee)) + return true; + + return false; +} + static bool hasTrivialDefaultCtorParent(const FieldDecl *FD) { assert(FD); assert(FD->getParent()->isUnion()); diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h index 5c46f75af4da3..2e814fe3e623b 100644 --- a/clang/lib/AST/ByteCode/Compiler.h +++ b/clang/lib/AST/ByteCode/Compiler.h @@ -423,6 +423,8 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>, bool checkLiteralType(const Expr *E); bool maybeEmitDeferredVarInit(const VarDecl *VD); + bool isPunningDereference(const Expr *E); + bool refersToUnion(const Expr *E); protected: `````````` </details> https://github.com/llvm/llvm-project/pull/163809 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
