Skip to content

[clang][Interp] reinterpret casts aren't always fatal #101900

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 5, 2024

Conversation

tbaederr
Copy link
Contributor

@tbaederr tbaederr commented Aug 4, 2024

The current interpreter emits the diagnostic and continues, so do the same.

The current interpreter emits the diagnostic and continues, so do the
same.
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Aug 4, 2024
@llvmbot
Copy link
Member

llvmbot commented Aug 4, 2024

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

Changes

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 --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
+}

@tbaederr tbaederr merged commit 120740b into llvm:main Aug 5, 2024
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants