[clang] 529b43c - [clang][Interp] Refine diagnostics for casts from void*

Timm Bäder via cfe-commits cfe-commits at lists.llvm.org
Tue Jun 11 02:19:19 PDT 2024


Author: Timm Bäder
Date: 2024-06-11T11:19:06+02:00
New Revision: 529b43c1fd435e1544bbd581fcf7191c3edfa20e

URL: https://github.com/llvm/llvm-project/commit/529b43c1fd435e1544bbd581fcf7191c3edfa20e
DIFF: https://github.com/llvm/llvm-project/commit/529b43c1fd435e1544bbd581fcf7191c3edfa20e.diff

LOG: [clang][Interp] Refine diagnostics for casts from void*

This is still not perfect, but an improvement in general.

Added: 
    

Modified: 
    clang/lib/AST/Interp/ByteCodeExprGen.cpp
    clang/lib/AST/Interp/Interp.h
    clang/lib/AST/Interp/Opcodes.td

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/Interp/ByteCodeExprGen.cpp b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
index 6654a27c92168..0899a98b3b95a 100644
--- a/clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ b/clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -318,7 +318,8 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
     if (DiscardResult)
       return this->discard(SubExpr);
 
-    std::optional<PrimType> FromT = classify(SubExpr->getType());
+    QualType SubExprTy = SubExpr->getType();
+    std::optional<PrimType> FromT = classify(SubExprTy);
     std::optional<PrimType> ToT = classify(CE->getType());
     if (!FromT || !ToT)
       return false;
@@ -326,9 +327,14 @@ bool ByteCodeExprGen<Emitter>::VisitCastExpr(const CastExpr *CE) {
     assert(isPtrType(*FromT));
     assert(isPtrType(*ToT));
     if (FromT == ToT) {
-      if (SubExpr->getType()->isVoidPointerType())
-        return this->visit(SubExpr) && this->emitVoidPtrCast(CE);
-      return this->delegate(SubExpr);
+      if (CE->getType()->isVoidPointerType())
+        return this->delegate(SubExpr);
+
+      if (!this->visit(SubExpr))
+        return false;
+      if (FromT == PT_Ptr)
+        return this->emitPtrPtrCast(SubExprTy->isVoidPointerType(), CE);
+      return true;
     }
 
     if (!this->visit(SubExpr))

diff  --git a/clang/lib/AST/Interp/Interp.h b/clang/lib/AST/Interp/Interp.h
index 0ad710c5ec1af..784e138e1467d 100644
--- a/clang/lib/AST/Interp/Interp.h
+++ b/clang/lib/AST/Interp/Interp.h
@@ -1980,10 +1980,25 @@ static inline bool CastPointerIntegralAPS(InterpState &S, CodePtr OpPC,
   return true;
 }
 
-static inline bool VoidPtrCast(InterpState &S, CodePtr OpPC) {
-  const SourceInfo &E = S.Current->getSource(OpPC);
-  S.CCEDiag(E, diag::note_constexpr_invalid_cast)
-      << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
+static inline bool PtrPtrCast(InterpState &S, CodePtr OpPC, bool SrcIsVoidPtr) {
+  const auto &Ptr = S.Stk.peek<Pointer>();
+
+  if (SrcIsVoidPtr && S.getLangOpts().CPlusPlus) {
+    bool HasValidResult = !Ptr.isZero();
+
+    if (HasValidResult) {
+      // FIXME: note_constexpr_invalid_void_star_cast
+    } else if (!S.getLangOpts().CPlusPlus26) {
+      const SourceInfo &E = S.Current->getSource(OpPC);
+      S.CCEDiag(E, diag::note_constexpr_invalid_cast)
+          << 3 << "'void *'" << S.Current->getRange(OpPC);
+    }
+  } else {
+    const SourceInfo &E = S.Current->getSource(OpPC);
+    S.CCEDiag(E, diag::note_constexpr_invalid_cast)
+        << 2 << S.getLangOpts().CPlusPlus << S.Current->getRange(OpPC);
+  }
+
   return true;
 }
 

diff  --git a/clang/lib/AST/Interp/Opcodes.td b/clang/lib/AST/Interp/Opcodes.td
index ac5426c87c212..45fc11e564576 100644
--- a/clang/lib/AST/Interp/Opcodes.td
+++ b/clang/lib/AST/Interp/Opcodes.td
@@ -665,7 +665,10 @@ def CastPointerIntegralAPS : Opcode {
   let HasGroup = 0;
   let Args = [ArgUint32];
 }
-def VoidPtrCast : Opcode;
+def PtrPtrCast : Opcode {
+  let Args = [ArgBool];
+
+}
 
 def DecayPtr : Opcode {
   let Types = [PtrTypeClass, PtrTypeClass];


        


More information about the cfe-commits mailing list