mirror of
https://github.com/intel/llvm.git
synced 2026-01-24 00:20:25 +08:00
[clang][Interp] Refine diagnostics for casts from void*
This is still not perfect, but an improvement in general.
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user