Skip to content

Commit 120740b

Browse files
authored
[clang][Interp] reinterpret casts aren't always fatal (llvm#101900)
The current interpreter emits the diagnostic and continues, so do the same.
1 parent 5bc99fb commit 120740b

File tree

4 files changed

+26
-7
lines changed

4 files changed

+26
-7
lines changed

clang/lib/AST/Interp/Compiler.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
426426
if (CE->getType()->isAtomicType()) {
427427
if (!this->discard(SubExpr))
428428
return false;
429-
return this->emitInvalidCast(CastKind::Reinterpret, CE);
429+
return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, CE);
430430
}
431431

432432
if (DiscardResult)
@@ -2465,10 +2465,13 @@ bool Compiler<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) {
24652465
template <class Emitter>
24662466
bool Compiler<Emitter>::VisitCXXReinterpretCastExpr(
24672467
const CXXReinterpretCastExpr *E) {
2468-
if (!this->discard(E->getSubExpr()))
2468+
const Expr *SubExpr = E->getSubExpr();
2469+
2470+
bool TypesMatch = classify(E) == classify(SubExpr);
2471+
if (!this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/!TypesMatch, E))
24692472
return false;
24702473

2471-
return this->emitInvalidCast(CastKind::Reinterpret, E);
2474+
return this->delegate(SubExpr);
24722475
}
24732476

24742477
template <class Emitter>

clang/lib/AST/Interp/Interp.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2787,13 +2787,16 @@ inline bool Unsupported(InterpState &S, CodePtr OpPC) {
27872787
inline bool Error(InterpState &S, CodePtr OpPC) { return false; }
27882788

27892789
/// Same here, but only for casts.
2790-
inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind) {
2790+
inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind,
2791+
bool Fatal) {
27912792
const SourceLocation &Loc = S.Current->getLocation(OpPC);
27922793

27932794
// FIXME: Support diagnosing other invalid cast kinds.
2794-
if (Kind == CastKind::Reinterpret)
2795-
S.FFDiag(Loc, diag::note_constexpr_invalid_cast)
2795+
if (Kind == CastKind::Reinterpret) {
2796+
S.CCEDiag(Loc, diag::note_constexpr_invalid_cast)
27962797
<< static_cast<unsigned>(Kind) << S.Current->getRange(OpPC);
2798+
return !Fatal;
2799+
}
27972800
return false;
27982801
}
27992802

clang/lib/AST/Interp/Opcodes.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ def Invalid : Opcode {}
739739
def Unsupported : Opcode {}
740740
def Error : Opcode {}
741741
def InvalidCast : Opcode {
742-
let Args = [ArgCastKind];
742+
let Args = [ArgCastKind, ArgBool];
743743
}
744744

745745
def InvalidDeclRef : Opcode {

clang/test/AST/Interp/codegen.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,16 @@ namespace BaseClassOffsets {
3131
// CHECK: @_ZN16BaseClassOffsets1bE = global ptr getelementptr (i8, ptr @_ZN16BaseClassOffsets1cE, i64 4), align 8
3232
B* b = &c;
3333
}
34+
35+
namespace reinterpretcast {
36+
const unsigned int n = 1234;
37+
extern const int &s = reinterpret_cast<const int&>(n);
38+
// CHECK: @_ZN15reinterpretcastL1nE = internal constant i32 1234, align 4
39+
// CHECK: @_ZN15reinterpretcast1sE = constant ptr @_ZN15reinterpretcastL1nE, align 8
40+
41+
void *f1(unsigned long l) {
42+
return reinterpret_cast<void *>(l);
43+
}
44+
// CHECK: define {{.*}} ptr @_ZN15reinterpretcast2f1Em
45+
// CHECK: inttoptr
46+
}

0 commit comments

Comments
 (0)