Author: Timm Bäder Date: 2024-06-11T11:19:06+02:00 New Revision: 529b43c1fd435e1544bbd581fcf7191c3edfa20e
URL: https://github.com/llvm/llvm-project/commit/529b43c1fd435e1544bbd581fcf7191c3edfa20e DIFF: https://github.com/llvm/llvm-project/commit/529b43c1fd435e1544bbd581fcf7191c3edfa20e.diff LOG: [clang][Interp] Refine diagnostics for casts from void* This is still not perfect, but an improvement in general. Added: Modified: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp index 6654a27c92168..0899a98b3b95a 100644 --- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -318,7 +318,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) { if (DiscardResult) return this->discard(SubExpr); - std::optional<PrimType> FromT = classify(SubExpr->getType()); + QualType SubExprTy = SubExpr->getType(); + std::optional<PrimType> FromT = classify(SubExprTy); std::optional<PrimType> ToT = classify(CE->getType()); if (!FromT || !ToT) return false; @@ -326,9 +327,14 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) { assert(isPtrType(*FromT)); assert(isPtrType(*ToT)); if (FromT == ToT) { - if (SubExpr->getType()->isVoidPointerType()) - return this->visit(SubExpr) && this->emitVoidPtrCast(CE); - return this->delegate(SubExpr); + if (CE->getType()->isVoidPointerType()) + return this->delegate(SubExpr); + + if (!this->visit(SubExpr)) + return false; + if (FromT == PT_Ptr) + return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(), CE); + return true; } if (!this->visit(SubExpr)) diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index 0ad710c5ec1af..784e138e1467d 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -1980,10 +1980,25 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC, return true; } -static inline bool VoidPtrCast(InterpState &S, CodePtr OpPC) { - const SourceInfo &E = S.Current->getSource(OpPC); - S.CCEDiag(E, diag::note_constexpr_invalid_cast) - << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC); +static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) { + const auto &Ptr = S.Stk.peek<Pointer>(); + + if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) { + bool HasValidResult = !Ptr.isZero(); + + if (HasValidResult) { + // FIXME: note_constexpr_invalid_void_star_cast + } else if (!S.getLangOpts().CPlusPlus26) { + const SourceInfo &E = S.Current->getSource(OpPC); + S.CCEDiag(E, diag::note_constexpr_invalid_cast) + << 3 << "'void *'" << S.Current->getRange(OpPC); + } + } else { + const SourceInfo &E = S.Current->getSource(OpPC); + S.CCEDiag(E, diag::note_constexpr_invalid_cast) + << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC); + } + return true; } diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index ac5426c87c212..45fc11e564576 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -665,7 +665,10 @@ def CastPointerIntegralAPS : Opcode { let HasGroup = 0; let Args = [ArgUint32]; } -def VoidPtrCast : Opcode; +def PtrPtrCast : Opcode { + let Args = [ArgBool]; + +} def DecayPtr : Opcode { let Types = [PtrTypeClass, PtrTypeClass]; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits