@@ -2638,18 +2638,46 @@ bool Compiler<Emitter>::VisitCXXReinterpretCastExpr(
2638
2638
const CXXReinterpretCastExpr *E) {
2639
2639
const Expr *SubExpr = E->getSubExpr ();
2640
2640
2641
- bool Fatal = false ;
2642
2641
std::optional<PrimType> FromT = classify (SubExpr);
2643
2642
std::optional<PrimType> ToT = classify (E);
2643
+
2644
2644
if (!FromT || !ToT)
2645
- Fatal = true ;
2646
- else
2647
- Fatal = (ToT != FromT);
2645
+ return this ->emitInvalidCast (CastKind::Reinterpret, /* Fatal=*/ true , E);
2646
+
2647
+ if (FromT == PT_Ptr || ToT == PT_Ptr) {
2648
+ // Both types could be PT_Ptr because their expressions are glvalues.
2649
+ std::optional<PrimType> PointeeFromT;
2650
+ if (SubExpr->getType ()->isPointerOrReferenceType ())
2651
+ PointeeFromT = classify (SubExpr->getType ()->getPointeeType ());
2652
+ else
2653
+ PointeeFromT = classify (SubExpr->getType ());
2654
+
2655
+ std::optional<PrimType> PointeeToT;
2656
+ if (E->getType ()->isPointerOrReferenceType ())
2657
+ PointeeToT = classify (E->getType ()->getPointeeType ());
2658
+ else
2659
+ PointeeToT = classify (E->getType ());
2660
+
2661
+ bool Fatal = true ;
2662
+ if (PointeeToT && PointeeFromT) {
2663
+ if (isIntegralType (*PointeeFromT) && isIntegralType (*PointeeToT))
2664
+ Fatal = false ;
2665
+ }
2666
+
2667
+ if (!this ->emitInvalidCast (CastKind::Reinterpret, Fatal, E))
2668
+ return false ;
2669
+
2670
+ if (E->getCastKind () == CK_LValueBitCast)
2671
+ return this ->delegate (SubExpr);
2672
+ return this ->VisitCastExpr (E);
2673
+ }
2648
2674
2675
+ // Try to actually do the cast.
2676
+ bool Fatal = (ToT != FromT);
2649
2677
if (!this ->emitInvalidCast (CastKind::Reinterpret, Fatal, E))
2650
2678
return false ;
2651
2679
2652
- return this ->delegate (SubExpr );
2680
+ return this ->VisitCastExpr (E );
2653
2681
}
2654
2682
2655
2683
template <class Emitter >
0 commit comments