What is the correct usage of llvm::PointerUnion?
I am trying to wrap around it with a custom struct type, but I am getting depreciation warnings:
What is the correct usage of llvm::PointerUnion?
I am trying to wrap around it with a custom struct type, but I am getting depreciation warnings:
what are the warnings you’re seeing?
I’m guessing it’s the is/get functions: llvm-project/llvm/include/llvm/ADT/PointerUnion.h at 0db04963d34be5867379ed47271730d456913e7e · llvm/llvm-project · GitHub . You should switch to llvm::isa and llvm::cast instead.
The diagnostic you get should include the instantiation that leads to the deprecated use
Its warning me that the member functions are depreciated, which makes since if you look at the header like kuhar pointed out. There are depreciation attributes applied to the functions. However, I don’t see how llvm::isa and llvm::cast can be used instead. I want to get a reference to the existing thing, but its creating a copy. For example:
```
cannot bind non-const lvalue reference of type ‘rq::StaticValue&’ to an rvalue of type ‘rq::StaticValue’GCC
```
I solved the problem.
The most confusing part of this to me is the fact that you cannot have const in the template parameter or it results in errors. To prevent this, I think that LLVM should use std::remove_cv_t
Ok, I see what you’re trying to do. You’re trying to return a reference to the field in the union. I am surprised that your solution works - obviously you can cast away the compile times warnings but I’m surprised it doesn’t crash at runtime.
The purpose of PointerUnion is to reduce the space required for a set of pointers. It does this by using free bits in the pointer to indicate the active type of the union. When you try to take the address of these you’re going to be either reading invalid pointers (due to the tag bits) or overwriting with incorrect type information when you write to it.
N.B. deprecated, not depreciated.
I see. It does not seem to have any issues, but if its UB I need to do something different. I am glad I asked people about this. What should I do then?
I think your latest code is correct. That is, given a pointer union PointerUnion<Foo *, Bar *> P, you have to write Foo *F = dyn_cast<Foo *>(P) rather than Foo *F = dyn_cast<Foo>(P).
I understand that this might contradict to the majority of LLVM RAII usages, for instance
Value *V = ...;
Instruction *I = dyn_cast<Instruction>(V);
where you provide the pointee type to dyn_cast’s template argument rather than pointer type.
The reason PointerUnion has this behavior is because its implementation: llvm-project/llvm/include/llvm/ADT/PointerUnion.h at 7513fbd660082b4538fafaae6714edafe8f0e0f8 · llvm/llvm-project · GitHub
Where it simply scans through the list of types it has (which are all pointer types) to check if type To from dyn_cast<To> is in that list. So To in this case has to be pointer type.
This is probably a problem too, right?
![]()