Skip to content

Commit 529b43c

Browse files
committed
[clang][Interp] Refine diagnostics for casts from void*
This is still not perfect, but an improvement in general.
1 parent 35ddc17 commit 529b43c

File tree

3 files changed

+33
-9
lines changed

3 files changed

+33
-9
lines changed

clang/lib/AST/Interp/ByteCodeExprGen.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -318,17 +318,23 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
318318
if (DiscardResult)
319319
return this->discard(SubExpr);
320320

321-
std::optional<PrimType> FromT = classify(SubExpr->getType());
321+
QualType SubExprTy = SubExpr->getType();
322+
std::optional<PrimType> FromT = classify(SubExprTy);
322323
std::optional<PrimType> ToT = classify(CE->getType());
323324
if (!FromT || !ToT)
324325
return false;
325326

326327
assert(isPtrType(*FromT));
327328
assert(isPtrType(*ToT));
328329
if (FromT == ToT) {
329-
if (SubExpr->getType()->isVoidPointerType())
330-
return this->visit(SubExpr) && this->emitVoidPtrCast(CE);
331-
return this->delegate(SubExpr);
330+
if (CE->getType()->isVoidPointerType())
331+
return this->delegate(SubExpr);
332+
333+
if (!this->visit(SubExpr))
334+
return false;
335+
if (FromT == PT_Ptr)
336+
return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(), CE);
337+
return true;
332338
}
333339

334340
if (!this->visit(SubExpr))

clang/lib/AST/Interp/Interp.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,10 +1980,25 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
19801980
return true;
19811981
}
19821982

1983-
static inline bool VoidPtrCast(InterpState &S, CodePtr OpPC) {
1984-
const SourceInfo &E = S.Current->getSource(OpPC);
1985-
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
1986-
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
1983+
static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
1984+
const auto &Ptr = S.Stk.peek<Pointer>();
1985+
1986+
if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) {
1987+
bool HasValidResult = !Ptr.isZero();
1988+
1989+
if (HasValidResult) {
1990+
// FIXME: note_constexpr_invalid_void_star_cast
1991+
} else if (!S.getLangOpts().CPlusPlus26) {
1992+
const SourceInfo &E = S.Current->getSource(OpPC);
1993+
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
1994+
<< 3 << "'void *'" << S.Current->getRange(OpPC);
1995+
}
1996+
} else {
1997+
const SourceInfo &E = S.Current->getSource(OpPC);
1998+
S.CCEDiag(E, diag::note_constexpr_invalid_cast)
1999+
<< 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
2000+
}
2001+
19872002
return true;
19882003
}
19892004

clang/lib/AST/Interp/Opcodes.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -665,7 +665,10 @@ def CastPointerIntegralAPS : Opcode {
665665
let HasGroup = 0;
666666
let Args = [ArgUint32];
667667
}
668-
def VoidPtrCast : Opcode;
668+
def PtrPtrCast : Opcode {
669+
let Args = [ArgBool];
670+
671+
}
669672

670673
def DecayPtr : Opcode {
671674
let Types = [PtrTypeClass, PtrTypeClass];

0 commit comments

Comments
 (0)