Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Correctly handle blacklisted items in the template analysis #623

Conversation

fitzgen
Copy link
Member

@fitzgen fitzgen commented Apr 7, 2017

The template analysis operates on whitelisted items, and uses our tracing
infrastructure to move between them. Usually, that means we can only reach other
whitelisted items by tracing, because the set of whitelisted items is the
transitive closure of all the items explicitly whitelisted. The exception is
when some type is explicitly blacklisted. It could still be reachable via
tracing from a whitelisted item, but is not considered whitelisted due to the
blacklisting.

The easy fix is to run the template analysis on the whole IR graph rather than
just the whitelisted set. This is an approximately one line change in the
analysis, however is not desirable due to performance concerns. The whole point
of whitelisting is that there may be many types in a header, but only a few
the user cares about, or there might be types that aren't explicitly needed and
that are too complicated for bindgen to handle generally (often in
<type_traits>). In these situations, we don't want to waste cycles or even
confuse ourselves by considering such types!

Instead, we keep the whitelisted item set around and check by hand whether any
given item is in it during the template type parameter analysis.

Additionally, we make the decision that blacklisted template definitions use all
of their type parameters. This seems like a reasonable choice because the type
will likely be ported to Rust manually by the bindgen user, and they will be
looking at the C++ definition with all of its type parameters. They can always
insert PhantomDatas manually, so it also gives the most flexibility.

Fixes #584

r? @emilio

@highfive
Copy link

highfive commented Apr 7, 2017

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!

@fitzgen
Copy link
Member Author

fitzgen commented Apr 7, 2017

With the changes in this PR, I can generate bindings for stylo successfully with libclang 3.9.

@emilio
Copy link
Contributor

emilio commented Apr 7, 2017

With the changes in this PR, I can generate bindings for stylo successfully with libclang 3.9.

Nice! What about libclang 4.0/5.0? Does the regression affect that badly our analysis?

@fitzgen
Copy link
Member Author

fitzgen commented Apr 7, 2017

What about libclang 4.0/5.0? Does the regression affect that badly our analysis?

I haven't tested with other libclang versions.

The original test case within bindgen that used default template params looked like it came from gecko though, so if there is any instantiation that relies on the default type, it will fail. Note that this is orthogonal from the template parameter usage analysis. In this scenario, we simply aren't given the data we need, and this happens way before we do any template analysis.

Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome!

Thanks a lot for digging into this.

r=me with that nit addressed

@@ -0,0 +1,13 @@
// bindgen-flags: --blacklist-type '^RefPtr$' --whitelist-function 'Servo_.*' --raw-line 'pub type RefPtr<T> = T;' -- -std=c++14
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no need to ^$, it's added implicitly.

The template analysis operates on whitelisted items, and uses our tracing
infrastructure to move between them. Usually, that means we can only reach other
whitelisted items by tracing, because the set of whitelisted items is the
transitive closure of all the items explicitly whitelisted. The exception is
when some type is explicitly blacklisted. It could still be reachable via
tracing from a whitelisted item, but is not considered whitelisted due to the
blacklisting.

The easy fix is to run the template analysis on the whole IR graph rather than
just the whitelisted set. This is an approximately one line change in the
analysis, however is not desirable due to performance concerns. The whole point
of whitelisting is that there may be *many* types in a header, but only a *few*
the user cares about, or there might be types that aren't explicitly needed and
that are too complicated for bindgen to handle generally (often in
`<type_traits>`). In these situations, we don't want to waste cycles or even
confuse ourselves by considering such types!

Instead, we keep the whitelisted item set around and check by hand whether any
given item is in it during the template type parameter analysis.

Additionally, we make the decision that blacklisted template definitions use all
of their type parameters. This seems like a reasonable choice because the type
will likely be ported to Rust manually by the bindgen user, and they will be
looking at the C++ definition with all of its type parameters. They can always
insert `PhantomData`s manually, so it also gives the most flexibility.

Fixes rust-lang#584
@fitzgen fitzgen force-pushed the issue-584-stylo-blacklisting-in-template-analysis branch from 60ffc31 to c8a206a Compare April 10, 2017 18:09
@fitzgen
Copy link
Member Author

fitzgen commented Apr 10, 2017

@bors-servo r=emilio

Thanks for the review!

@bors-servo
Copy link

📌 Commit c8a206a has been approved by emilio

@bors-servo
Copy link

⌛ Testing commit c8a206a with merge a22ddba...

bors-servo pushed a commit that referenced this pull request Apr 10, 2017
…-analysis, r=emilio

Correctly handle blacklisted items in the template analysis

The template analysis operates on whitelisted items, and uses our tracing
infrastructure to move between them. Usually, that means we can only reach other
whitelisted items by tracing, because the set of whitelisted items is the
transitive closure of all the items explicitly whitelisted. The exception is
when some type is explicitly blacklisted. It could still be reachable via
tracing from a whitelisted item, but is not considered whitelisted due to the
blacklisting.

The easy fix is to run the template analysis on the whole IR graph rather than
just the whitelisted set. This is an approximately one line change in the
analysis, however is not desirable due to performance concerns. The whole point
of whitelisting is that there may be *many* types in a header, but only a *few*
the user cares about, or there might be types that aren't explicitly needed and
that are too complicated for bindgen to handle generally (often in
`<type_traits>`). In these situations, we don't want to waste cycles or even
confuse ourselves by considering such types!

Instead, we keep the whitelisted item set around and check by hand whether any
given item is in it during the template type parameter analysis.

Additionally, we make the decision that blacklisted template definitions use all
of their type parameters. This seems like a reasonable choice because the type
will likely be ported to Rust manually by the bindgen user, and they will be
looking at the C++ definition with all of its type parameters. They can always
insert `PhantomData`s manually, so it also gives the most flexibility.

Fixes #584

r? @emilio
@bors-servo
Copy link

☀️ Test successful - status-travis
Approved by: emilio
Pushing a22ddba to master...

@bors-servo bors-servo merged commit c8a206a into rust-lang:master Apr 10, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bindgen panics in Stylo on master
4 participants