This is an archive of the discontinued LLVM Phabricator instance.

Handle TemplateArgument in DynTypedNode comparison operations.
AbandonedPublic

Authored by alexfh on Apr 14 2016, 7:40 PM.

Details

Reviewers
bkramer
sbenza
Summary

This patch fixes an assertion failure on some matchers containing
templateArgument() on some code in some configurations. I couldn't come up with a
consistent repro, since the failure depens on the order of elements in a map.
http://reviews.llvm.org/D18136 contains a matcher that causes the issue at least
on some configurations.

The fix turned out to require non-trivial amount of code, very similar to
TemplateArgument::structurallyEquals. I'd prefer to use
TemplateArgument::Profile, if it was possible without ASTContext. Another
alternative would be to add operator< for TemplateArgument, but since it's only
needed in DynTypedNode, I decided to make this code private to DynTypedNode.

Diff Detail

Event Timeline

alexfh updated this revision to Diff 53832.Apr 14 2016, 7:40 PM
alexfh retitled this revision from to Handle TemplateArgument in DynTypedNode comparison operations..
alexfh updated this object.
alexfh added reviewers: sbenza, bkramer.
alexfh added a subscriber: cfe-commits.
sbenza edited edge metadata.Apr 15 2016, 1:06 PM

I think the bug is coming from memoizedMatchesAncestorOfRecursively.
memoizedMatchesRecursively has a special case at the top to skip the cache if the node is not sortable. The other function should do that too.
Although the check is stale also because it is only checking for memoizationData and not whether the node itself works for < and ==.

Note that adding TemplateArgument to the function is ok, but that won't fix the bug because we still have other nodes that are not comparable.

include/clang/AST/ASTTypeTraits.h
269

this comment is stale.

To be more specific, the problem comes from the use of hasAnscestor (done by isInTemplateInstantiation ) while there is a TemplateArgument in the bound nodes.
This tries to put the node into the cache.
To trigger this easily you only need to have a hit in the cache.
I think you can trigger it by adding a second line boost::lexical_cast<std::string>(42); in the string_as_T test. That second hit should get a cache hit and trigger the bug.

I think the bug is coming from memoizedMatchesAncestorOfRecursively.
memoizedMatchesRecursively has a special case at the top to skip the cache if the node is not sortable. The other function should do that too.
Although the check is stale also because it is only checking for memoizationData and not whether the node itself works for < and ==.

Note that adding TemplateArgument to the function is ok, but that won't fix the bug because we still have other nodes that are not comparable.

With this I would be entering "I have no idea what I'm doing" land ;) Might make sense for you to take over the patch, if you know how to fix the issue. WDYT?

Sent http://reviews.llvm.org/D19231 to fix the underlying bug in hasAncestor.
We can proceed with this change if you want, but it is not required anymore. I don't know whether we need the extra complexity of TemplateArgumentLess.

Sent http://reviews.llvm.org/D19231 to fix the underlying bug in hasAncestor.
We can proceed with this change if you want, but it is not required anymore. I don't know whether we need the extra complexity of TemplateArgumentLess.

If this patch is not going to help with performance, I'm happy to abandon it.

We can proceed with this change if you want, but it is not required anymore. I don't know whether we need the extra complexity of TemplateArgumentLess.

If this patch is not going to help with performance, I'm happy to abandon it.

It might help in the cases where you are doing hasAncestor with TemplateArgument bound nodes, but that is a small corner case and I don't think we need to optimize for it.

alexfh abandoned this revision.Apr 19 2016, 3:05 PM

Ok, let's drop this on the floor.