[clang] [clang][Interp] reinterpret casts aren't always fatal (PR #101900)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Aug 4 11:51:49 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Timm Baeder (tbaederr)
<details>
<summary>Changes</summary>
The current interpreter emits the diagnostic and continues, so do the same.
---
Full diff: https://github.com/llvm/llvm-project/pull/101900.diff
4 Files Affected:
- (modified) clang/lib/AST/Interp/Compiler.cpp (+6-3)
- (modified) clang/lib/AST/Interp/Interp.h (+6-3)
- (modified) clang/lib/AST/Interp/Opcodes.td (+1-1)
- (modified) clang/test/AST/Interp/codegen.cpp (+13)
``````````diff
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
+}
``````````
</details>
https://github.com/llvm/llvm-project/pull/101900
More information about the cfe-commits
mailing list