Author: Timm Baeder Date: 2024-08-05T08:17:18+02:00 New Revision: 120740b16c27c12ce989793c2e1a95ac564f25b8
URL: https://github.com/llvm/llvm-project/commit/120740b16c27c12ce989793c2e1a95ac564f25b8 DIFF: https://github.com/llvm/llvm-project/commit/120740b16c27c12ce989793c2e1a95ac564f25b8.diff LOG: [clang][Interp] reinterpret casts aren't always fatal (#101900) The current interpreter emits the diagnostic and continues, so do the same. Added: Modified: clang/lib/AST/Interp/Compiler.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/test/AST/Interp/codegen.cpp Removed: ################################################################################ diff --git a/clang/lib/AST/Interp/Compiler.cpp b/clang/lib/AST/Interp/Compiler.cpp index bd2b0f74b34c5..1295555f4cf22 100644 --- a/clang/lib/AST/Interp/Compiler.cpp +++ b/clang/lib/AST/Interp/Compiler.cpp @@ -426,7 +426,7 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) { if (CE->getType()->isAtomicType()) { if (!this->discard(SubExpr)) return false; - return this->emitInvalidCast(CastKind::Reinterpret, CE); + return this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/true, CE); } if (DiscardResult) @@ -2465,10 +2465,13 @@ bool Compiler<Emitter>::VisitCXXThrowExpr(const CXXThrowExpr *E) { template <class Emitter> bool Compiler<Emitter>::VisitCXXReinterpretCastExpr( const CXXReinterpretCastExpr *E) { - if (!this->discard(E->getSubExpr())) + const Expr *SubExpr = E->getSubExpr(); + + bool TypesMatch = classify(E) == classify(SubExpr); + if (!this->emitInvalidCast(CastKind::Reinterpret, /*Fatal=*/!TypesMatch, E)) return false; - return this->emitInvalidCast(CastKind::Reinterpret, E); + return this->delegate(SubExpr); } template <class Emitter> diff --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h index a3f81e2de466b..04f88efdc0acf 100644 --- a/clang/lib/AST/Interp/Interp.h +++ b/clang/lib/AST/Interp/Interp.h @@ -2787,13 +2787,16 @@ inline bool Unsupported(InterpState &S, CodePtr OpPC) { inline bool Error(InterpState &S, CodePtr OpPC) { return false; } /// Same here, but only for casts. -inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind) { +inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind, + bool Fatal) { const SourceLocation &Loc = S.Current->getLocation(OpPC); // FIXME: Support diagnosing other invalid cast kinds. - if (Kind == CastKind::Reinterpret) - S.FFDiag(Loc, diag::note_constexpr_invalid_cast) + if (Kind == CastKind::Reinterpret) { + S.CCEDiag(Loc, diag::note_constexpr_invalid_cast) << static_cast<unsigned>(Kind) << S.Current->getRange(OpPC); + return !Fatal; + } return false; } diff --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td index 70d06bdfdc21c..220dff0c556b1 100644 --- a/clang/lib/AST/Interp/Opcodes.td +++ b/clang/lib/AST/Interp/Opcodes.td @@ -739,7 +739,7 @@ def Invalid : Opcode {} def Unsupported : Opcode {} def Error : Opcode {} def InvalidCast : Opcode { - let Args = [ArgCastKind]; + let Args = [ArgCastKind, ArgBool]; } def InvalidDeclRef : Opcode { diff --git a/clang/test/AST/Interp/codegen.cpp b/clang/test/AST/Interp/codegen.cpp index a5583d953d234..f1f0a33673a5b 100644 --- a/clang/test/AST/Interp/codegen.cpp +++ b/clang/test/AST/Interp/codegen.cpp @@ -31,3 +31,16 @@ namespace BaseClassOffsets { // CHECK: @_ZN16BaseClassOffsets1bE = global ptr getelementptr (i8, ptr @_ZN16BaseClassOffsets1cE, i64 4), align 8 B* b = &c; } + +namespace reinterpretcast { + const unsigned int n = 1234; + extern const int &s = reinterpret_cast<const int&>(n); + // CHECK: @_ZN15reinterpretcastL1nE = internal constant i32 1234, align 4 + // CHECK: @_ZN15reinterpretcast1sE = constant ptr @_ZN15reinterpretcastL1nE, align 8 + + void *f1(unsigned long l) { + return reinterpret_cast<void *>(l); + } + // CHECK: define {{.*}} ptr @_ZN15reinterpretcast2f1Em + // CHECK: inttoptr +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits