This adds an internal option -wholeprogramdevirt-check which if enabled
will guard each devirtualization with a runtime check against the
expected target, and an invocation of a debug trap if the check fails.
This is useful for debugging WPD failures involving undefined behavior
(e.g. casting to another class type not in the inheritance chain).
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I guess from the perspective of it being used to identify undefined behavior, however, it will only flush that out if we happen to do a single implementation WPD right now. It's also useful for debugging WPD. For now I'd like to get it in as an internal option for debugging, and figure out the appropriate name for a user level option in a follow on patch - wdyt?
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp | ||
---|---|---|
1073 | is versioning necessary here? Can it just be: if (target != direct_target) trap(); direct_target(); |
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp | ||
---|---|---|
1073 | It could, but invoking versionCallSite was very convenient so I didn't need to replicate a bunch of the necessary code. With versionCallSite we currently get: if (target == direct_target) direct_target() else trap() I'm not sure it matters much given that this is for debugging. Wdyt? |
Can you use SplitBlockAndInsertIfThen instead of versionCallSite here? I personally don't find the name versionCallSite very intuitive here.
There's a bunch of handling in versionCallSite for things like must tail calls and invoke instructions that I think I would end up needing to replicate, along with the general case. Calling versionCallSite makes things easy since it handles all of this. Would it help to expand the comment above the call?
You're just adding some code before the call, no? That means that you don't need to touch the call itself.
Yeah actually this is a good reason to go with David's earlier suggestion of changing the if condition. Let me go ahead and do that.
LGTM
llvm/lib/Transforms/IPO/WholeProgramDevirt.cpp | ||
---|---|---|
1070 | No need for an if here, just do the bitcast and it will constant fold away if the types are the same. |
No need for an if here, just do the bitcast and it will constant fold away if the types are the same.