[llvm] 0be41ed - [LLVM][Casting.h] Don't create a temporary while casting.
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 12 20:11:07 PDT 2022
Author: bzcheeseman
Date: 2022-05-12T23:11:02-04:00
New Revision: 0be41ed5bb57aded4e8ca1c6a8d22b7830c8f2fc
URL: https://github.com/llvm/llvm-project/commit/0be41ed5bb57aded4e8ca1c6a8d22b7830c8f2fc
DIFF: https://github.com/llvm/llvm-project/commit/0be41ed5bb57aded4e8ca1c6a8d22b7830c8f2fc.diff
LOG: [LLVM][Casting.h] Don't create a temporary while casting.
C-style casting can create a temporary when compiled by a C++ compiler, which was emitting a warning casting a reference to another reference. We can't use C++-style casting directly because it doesn't always work with incomplete types. In order to support the current use-cases, for references we switch to pointer space to perform the cast.
Reviewed By: qiongsiwu1
Differential Revision: https://reviews.llvm.org/D125482
Added:
Modified:
llvm/include/llvm/Support/Casting.h
llvm/unittests/Support/Casting.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/Support/Casting.h b/llvm/include/llvm/Support/Casting.h
index 8c07bf074c6db..5e87495135d1b 100644
--- a/llvm/include/llvm/Support/Casting.h
+++ b/llvm/include/llvm/Support/Casting.h
@@ -209,11 +209,19 @@ template <class To, class From, class SimpleFrom> struct cast_convert_val {
};
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);
}
};
diff --git a/llvm/unittests/Support/Casting.cpp b/llvm/unittests/Support/Casting.cpp
index 56edf155511fb..086548f1e2128 100644
--- a/llvm/unittests/Support/Casting.cpp
+++ b/llvm/unittests/Support/Casting.cpp
@@ -298,11 +298,9 @@ TEST(CastingTest, unique_dyn_cast) {
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 @@ TEST(CastingTest, unique_dyn_cast) {
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);
}
More information about the llvm-commits
mailing list