[PATCH] D125482: [LLVM][Casting.h] Don't create a temporary while casting.

Aman LaChapelle via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu May 12 16:20:14 PDT 2022


bzcheeseman updated this revision to Diff 429096.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125482/new/

https://reviews.llvm.org/D125482

Files:
  llvm/include/llvm/Support/Casting.h
  llvm/unittests/Support/Casting.cpp


Index: llvm/unittests/Support/Casting.cpp
===================================================================
--- llvm/unittests/Support/Casting.cpp
+++ llvm/unittests/Support/Casting.cpp
@@ -298,11 +298,9 @@
   ASSERT_EQ(OrigD, D.get());
   ASSERT_EQ(nullptr, NewB);
 
-  // Converting between unrelated types should fail.  The original value should
-  // remain unchanged and it should return nullptr.
-  //
-  // Note that this is a very contrived test - most of the time we want a cast
-  // like this to emit a compiler error.
+  // This is a very contrived test, casting between completely unrelated types
+  // should generally fail to compile. See the classof shenanigans we have in
+  // the definition of `foo` above.
   auto F = unique_dyn_cast<foo>(D);
   ASSERT_EQ(nullptr, F);
   ASSERT_EQ(OrigD, D.get());
@@ -317,6 +315,9 @@
   auto B3 = unique_dyn_cast<base>(newb());
   EXPECT_NE(nullptr, B3);
 
+  // This is a very contrived test, casting between completely unrelated types
+  // should generally fail to compile. See the classof shenanigans we have in
+  // the definition of `foo` above.
   auto F2 = unique_dyn_cast<foo>(newb());
   EXPECT_EQ(nullptr, F2);
 }
Index: llvm/include/llvm/Support/Casting.h
===================================================================
--- llvm/include/llvm/Support/Casting.h
+++ llvm/include/llvm/Support/Casting.h
@@ -209,11 +209,19 @@
 };
 
 template <class To, class FromTy> struct cast_convert_val<To, FromTy, FromTy> {
-  // This _is_ a simple type, just cast it.
+  // If it's a reference, switch to a pointer to do the cast and then deref it.
   static typename cast_retty<To, FromTy>::ret_type doit(const FromTy &Val) {
-    typename cast_retty<To, FromTy>::ret_type Res2 =
-        (typename cast_retty<To, FromTy>::ret_type) const_cast<FromTy &>(Val);
-    return Res2;
+    return *(std::remove_reference_t<typename cast_retty<To, FromTy>::ret_type>
+                 *)&const_cast<FromTy &>(Val);
+  }
+};
+
+template <class To, class FromTy>
+struct cast_convert_val<To, FromTy *, FromTy *> {
+  // If it's a pointer, we can use c-style casting directly.
+  static typename cast_retty<To, FromTy *>::ret_type doit(const FromTy *Val) {
+    return (typename cast_retty<To, FromTy *>::ret_type) const_cast<FromTy *>(
+        Val);
   }
 };
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D125482.429096.patch
Type: text/x-patch
Size: 2313 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220512/6121ae77/attachment.bin>


More information about the llvm-commits mailing list