tbaeder created this revision. tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik. Herald added a project: All. tbaeder requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Add a new `InvalidCast` op for this purpose and emit a diagnostic. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D153276 Files: clang/lib/AST/Interp/ByteCodeExprGen.cpp clang/lib/AST/Interp/ByteCodeExprGen.h clang/lib/AST/Interp/Disasm.cpp clang/lib/AST/Interp/Interp.h clang/lib/AST/Interp/Opcodes.td clang/lib/AST/Interp/PrimType.h clang/test/AST/Interp/unsupported.cpp
Index: clang/test/AST/Interp/unsupported.cpp =================================================================== --- clang/test/AST/Interp/unsupported.cpp +++ clang/test/AST/Interp/unsupported.cpp @@ -47,3 +47,11 @@ return 0; } } + +namespace Casts { + constexpr int a = reinterpret_cast<int>(12); // expected-error {{must be initialized by a constant expression}} \ + // expected-note {{reinterpret_cast is not allowed}} \ + // ref-error {{must be initialized by a constant expression}} \ + // ref-note {{reinterpret_cast is not allowed}} + +} Index: clang/lib/AST/Interp/PrimType.h =================================================================== --- clang/lib/AST/Interp/PrimType.h +++ clang/lib/AST/Interp/PrimType.h @@ -13,6 +13,7 @@ #ifndef LLVM_CLANG_AST_INTERP_TYPE_H #define LLVM_CLANG_AST_INTERP_TYPE_H +#include "llvm/Support/raw_ostream.h" #include <climits> #include <cstddef> #include <cstdint> @@ -42,6 +43,12 @@ PT_FnPtr, }; +enum class CastKind : uint8_t { + Reinterpret, + Dynamic, +}; +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, interp::CastKind CK); + constexpr bool isIntegralType(PrimType T) { return T <= PT_Uint64; } /// Mapping from primitive types to their representation. Index: clang/lib/AST/Interp/Opcodes.td =================================================================== --- clang/lib/AST/Interp/Opcodes.td +++ clang/lib/AST/Interp/Opcodes.td @@ -51,6 +51,7 @@ def ArgFltSemantics : ArgType { let Name = "const llvm::fltSemantics *"; } def ArgRoundingMode : ArgType { let Name = "llvm::RoundingMode"; } def ArgLETD: ArgType { let Name = "const LifetimeExtendedTemporaryDecl *"; } +def ArgCastKind : ArgType { let Name = "CastKind"; } //===----------------------------------------------------------------------===// // Classes of types instructions operate on. @@ -636,3 +637,6 @@ // [] -> [] def Invalid : Opcode {} +def InvalidCast : Opcode { + let Args = [ArgCastKind]; +} Index: clang/lib/AST/Interp/Interp.h =================================================================== --- clang/lib/AST/Interp/Interp.h +++ clang/lib/AST/Interp/Interp.h @@ -1847,6 +1847,14 @@ return false; } +/// Same here, but only for casts. +inline bool InvalidCast(InterpState &S, CodePtr OpPC, CastKind Kind) { + const SourceLocation &Loc = S.Current->getLocation(OpPC); + S.FFDiag(Loc, diag::note_constexpr_invalid_cast) + << static_cast<uint8_t>(Kind) << S.Current->getRange(OpPC); + return false; +} + //===----------------------------------------------------------------------===// // Read opcode arguments //===----------------------------------------------------------------------===// Index: clang/lib/AST/Interp/Disasm.cpp =================================================================== --- clang/lib/AST/Interp/Disasm.cpp +++ clang/lib/AST/Interp/Disasm.cpp @@ -73,3 +73,15 @@ Anon->dump(); } } + +llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, interp::CastKind CK) { + switch (CK) { + case interp::CastKind::Reinterpret: + OS << "reinterpret_cast"; + break; + case interp::CastKind::Dynamic: + OS << "dynamic_cast"; + break; + } + return OS; +} Index: clang/lib/AST/Interp/ByteCodeExprGen.h =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.h +++ clang/lib/AST/Interp/ByteCodeExprGen.h @@ -98,6 +98,7 @@ bool VisitLambdaExpr(const LambdaExpr *E); bool VisitPredefinedExpr(const PredefinedExpr *E); bool VisitCXXThrowExpr(const CXXThrowExpr *E); + bool VisitCXXReinterpretCastExpr(const CXXReinterpretCastExpr *E); protected: bool visitExpr(const Expr *E) override; Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp =================================================================== --- clang/lib/AST/Interp/ByteCodeExprGen.cpp +++ clang/lib/AST/Interp/ByteCodeExprGen.cpp @@ -1115,6 +1115,15 @@ return this->emitInvalid(E); } +template <class Emitter> +bool ByteCodeExprGen<Emitter>::VisitCXXReinterpretCastExpr( + const CXXReinterpretCastExpr *E) { + if (!this->discard(E->getSubExpr())) + return false; + + return this->emitInvalidCast(CastKind::Reinterpret, E); +} + template <class Emitter> bool ByteCodeExprGen<Emitter>::discard(const Expr *E) { if (E->containsErrors()) return false;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits