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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits