================
@@ -740,16 +764,182 @@ Interpreter::Visit(const BooleanLiteralNode *node) {
   return ValueObject::CreateValueObjectFromBool(m_target, value, "result");
 }
 
+llvm::Expected<CastKind>
+Interpreter::VerifyCastType(lldb::ValueObjectSP operand, CompilerType op_type,
+                            CompilerType target_type, int location) {
+
+  if (target_type.IsScalarType()) {
+    if (op_type.IsPointerType() || op_type.IsNullPtrType()) {
+      // Cast from pointer to float/double is not allowed.
+      if (target_type.IsFloat()) {
+        std::string errMsg = llvm::formatv(
+            "Cast from {0} to {1} is not allowed", op_type.TypeDescription(),
+            target_type.TypeDescription());
+        return llvm::make_error<DILDiagnosticError>(
+            m_expr, std::move(errMsg), location,
+            op_type.TypeDescription().length());
+      }
+      // Casting pointer to bool is valid. Otherwise check if the result type
+      // is at least as big as the pointer size.
+      uint64_t type_byte_size = 0;
+      uint64_t rhs_type_byte_size = 0;
+      if (auto temp = target_type.GetByteSize(m_exe_ctx_scope.get()))
+        type_byte_size = *temp;
+      if (auto temp = op_type.GetByteSize(m_exe_ctx_scope.get()))
+        rhs_type_byte_size = *temp;
+      if (!target_type.IsBoolean() && type_byte_size < rhs_type_byte_size) {
+        std::string errMsg = llvm::formatv(
+            "cast from pointer to smaller type {0} loses information",
+            target_type.TypeDescription());
+        return llvm::make_error<DILDiagnosticError>(
+            m_expr, std::move(errMsg), location,
+            op_type.TypeDescription().length());
+      }
+    } else if (!op_type.IsScalarType() && !op_type.IsEnumerationType()) {
+      // Otherwise accept only arithmetic types and enums.
+      std::string errMsg = llvm::formatv(
+          "cannot convert {0} to {1} without a conversion operator",
+          op_type.TypeDescription(), target_type.TypeDescription());
+
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, std::move(errMsg), location,
+          op_type.TypeDescription().length());
+    }
+    return CastKind::eArithmetic;
+  }
+
+  if (target_type.IsEnumerationType()) {
+    // Cast to enum type.
+    if (!op_type.IsScalarType() && !op_type.IsEnumerationType()) {
+      std::string errMsg = llvm::formatv("Cast from {0} to {1} is not allowed",
+                                         op_type.TypeDescription(),
+                                         target_type.TypeDescription());
+
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, std::move(errMsg), location,
+          op_type.TypeDescription().length());
+    }
+    return CastKind::eEnumeration;
+  }
+
+  if (target_type.IsPointerType()) {
+    if (!op_type.IsInteger() && !op_type.IsEnumerationType() &&
+        !op_type.IsArrayType() && !op_type.IsPointerType() &&
+        !op_type.IsNullPtrType()) {
+      std::string errMsg = llvm::formatv(
+          "cannot cast from type {0} to pointer type {1}",
+          op_type.TypeDescription(), target_type.TypeDescription());
+
+      return llvm::make_error<DILDiagnosticError>(
+          m_expr, std::move(errMsg), location,
+          op_type.TypeDescription().length());
+    }
+    return CastKind::ePointer;
+  }
+
+  if (target_type.IsNullPtrType()) {
+    // Cast to nullptr type.
+    bool is_signed;
+    if (!target_type.IsNullPtrType() &&
----------------
Michael137 wrote:

This condition can never fire since we already checked 
`target_type.IsNullPtrType()`

What's the intention behind these checks?

https://github.com/llvm/llvm-project/pull/170332
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to