This is an archive of the discontinued LLVM Phabricator instance.

[ADT] Fix a bug in DenseSet's initializer_list constructor.
ClosedPublic

Authored by lhames on Oct 14 2018, 12:07 PM.

Details

Summary

Without this fix, DenseSet crashes with an assertion if constructed with an
initializer_list whose length is not a power of two.

Diff Detail

Repository
rL LLVM

Event Timeline

lhames created this revision.Oct 14 2018, 12:07 PM
dblaikie added inline comments.Oct 14 2018, 12:17 PM
unittests/ADT/DenseSetTest.cpp
83–87

"Don't crash" tests always look a bit suspect to me (like "test that this does anything other than crash" is not a particularly strong constraint). Maybe test that it contains the desired contents after such construction, and/or that the capacity or buckets or whatever is the expected power of two?

craig.topper added inline comments.
include/llvm/ADT/DenseSet.h
71

Shouldn’t this be PowerOf2Ceil? NextPowerOf2 will change a number that is already a power of 2.

lhames added inline comments.Oct 15 2018, 8:36 AM
include/llvm/ADT/DenseSet.h
71

Yes it should. Thanks!

unittests/ADT/DenseSetTest.cpp
83–87

I only use a "don't crash" test if the other aspects are tested elsewhere. In this case they're covered by the test above, which just happened to have a power-of-two length initializer (or we would have noticed this bug earlier).

I do not suppose there's any harm in doing a sanity check on the content in the non power-of-two case though. I'll add one.

lhames updated this revision to Diff 169717.Oct 15 2018, 9:11 AM

Use PowerOf2Ceil as per Craig's suggestion, and validate set contents in the non power-of-two length initializer list unit test as per Dave's suggestion.

dblaikie accepted this revision.Oct 15 2018, 11:25 AM

Looks good to me (I guess the capacity thing there could be tested too - ensuring that it didn't roll up to a larger capacity than intended?)

This revision is now accepted and ready to land.Oct 15 2018, 11:25 AM
lhames closed this revision.Oct 15 2018, 11:37 AM

Committed as r344542.

Looks good to me (I guess the capacity thing there could be tested too - ensuring that it didn't roll up to a larger capacity than intended?)

Unfortunately DenseSet / DenseMap do not expose a capacity function at the moment. I believe it's just getNumBuckets, so unless there is some reason not to I would be in favor of adding a public 'capacity' function that returns that. Then we could add that check to the unit test.

Committed as r344542.

Looks good to me (I guess the capacity thing there could be tested too - ensuring that it didn't roll up to a larger capacity than intended?)

Unfortunately DenseSet / DenseMap do not expose a capacity function at the moment. I believe it's just getNumBuckets, so unless there is some reason not to I would be in favor of adding a public 'capacity' function that returns that. Then we could add that check to the unit test.

Capacity is the number of elements that can be held without additional allocation, right? So that would be closer to getNumBuckets()/4*3.