================
@@ -1989,6 +1998,53 @@ bool CheckBitCast(InterpState &S, CodePtr OpPC, const
Type *TargetType,
return true;
}
+bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr,
+ const Type *TargetType) {
+ const auto &Ptr = S.Stk.peek<Pointer>();
+
+ if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) {
+ bool HasValidResult = !Ptr.isZero();
+
+ if (HasValidResult) {
+ if (S.getStdAllocatorCaller("allocate"))
+ return true;
+
+ if (S.getLangOpts().CPlusPlus26 &&
+ S.getASTContext().hasSimilarType(Ptr.getType(),
+ TargetType->getPointeeType()))
+ return true;
+
+ const auto *E = cast<CastExpr>(S.Current->getExpr(OpPC));
+ S.CCEDiag(E, diag::note_constexpr_invalid_void_star_cast)
+ << E->getSubExpr()->getType() << S.getLangOpts().CPlusPlus26
+ << Ptr.getType().getCanonicalType() <<
E->getType()->getPointeeType();
+ } else if (!S.getLangOpts().CPlusPlus26) {
+ const SourceInfo &E = S.Current->getSource(OpPC);
+ S.CCEDiag(E, diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::CastFrom << "'void *'"
+ << S.Current->getRange(OpPC);
+ }
+ } else {
+ const SourceInfo &E = S.Current->getSource(OpPC);
+ S.CCEDiag(E, diag::note_constexpr_invalid_cast)
+ << diag::ConstexprInvalidCastKind::ThisConversionOrReinterpret
+ << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
+ }
+
+ // Retain the casted type for opaque pointers.
+ if (Ptr.isOpaquePointer()) {
+ Pointer P = S.Stk.pop<Pointer>();
+ auto OP = P.asOpaquePointer();
+
+ if (!validType(TargetType->getPointeeType()))
+ return Invalid(S, OpPC);
+
+ S.Stk.push<Pointer>(OP.withFieldType(TargetType), P.getByteOffset());
+ }
+
+ return true;
+}
----------------
ojhunt wrote:
I'd prefer an early return on !isOpaquePointer(), but at this point you know my
preference and that it's not some concrete rule :D
https://github.com/llvm/llvm-project/pull/223607
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits