Skip to content

Fix Issue 11006 - Subtraction of pointers for void and non-void type compiles#7332

Merged
dlang-bot merged 6 commits intodlang:masterfrom
JinShil:fix_11006
Nov 20, 2017
Merged

Fix Issue 11006 - Subtraction of pointers for void and non-void type compiles#7332
dlang-bot merged 6 commits intodlang:masterfrom
JinShil:fix_11006

Conversation

@JinShil
Copy link
Contributor

@JinShil JinShil commented Nov 18, 2017

Revival of #6440

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @JinShil! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.

Some tips to help speed things up:

  • smaller, focused PRs are easier to review than big ones

  • try not to mix up refactoring or style changes with bug fixes or feature enhancements

  • provide helpful commit messages explaining the rationale behind each change

Bear in mind that large or tricky changes may require multiple rounds of review and revision.

Please see CONTRIBUTING.md for more information.

Bugzilla references

Auto-close Bugzilla Description
11006 Subtraction of pointers for void and non-void types compiles

⚠️⚠️⚠️ Warnings ⚠️⚠️⚠️

@JinShil
Copy link
Contributor Author

JinShil commented Nov 18, 2017

This PR may have revealed the following problem:

Deprecation messages occur in std.experimental.allocator. For example: std/experimental/allocator/building_blocks/bitmapped_block.d(232): Deprecation: Operands point to types of different size; void (1 bytes), ulong (8 bytes).

Perhaps std.experimental.allocator's code should be audited and where there is no problem, intent expressed with explicit casts.

See output of auto-tester for more details.

@JinShil
Copy link
Contributor Author

JinShil commented Nov 18, 2017

@andralex @wilzbach @ZombineDev As code owners of std.experimental.allocator, your thoughts on the error described above?

@andralex
Copy link
Member

@JinShil thanks for pointing that out. The culprit seems to be the snippet:

        auto start = _control.rep.ptr, end = _payload.ptr + _payload.length;
        parent.deallocate(start[0 .. end - start]);

The end - start operation subtracts pointers to different types. The solution is:

        void* start = _control.rep.ptr, end = _payload.ptr + _payload.length;
        parent.deallocate(start[0 .. end - start]);

To my own surprise I managed to create dlang/phobos#5864 just by using the web interface - nice job github.

@andralex
Copy link
Member

As an aside, the code was actually incorrect. It was equivalent to:

        ulong* start = _control.rep.ptr;
        void* end = _payload.ptr + _payload.length;
        parent.deallocate(start[0 .. end - start]);

The computation end - start yields the number of bytes, but the slice passed to deallocate will be 8 times larger. Probably this only worked because the parent allocator tolerated the bug (e.g. Mallocator and GCAllocator don't use the length of the chunk).

@JinShil
Copy link
Contributor Author

JinShil commented Nov 19, 2017

From my perspective, this is ready to go.

Copy link
Member

@PetarKirov PetarKirov left a comment

Choose a reason for hiding this comment

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

LGTM, modulo one question about how strict we want to be.

if (!p1.equivalent(p2))
{
// Types don't match unless the have the same size
if (p1.size() != p2.size())
Copy link
Member

@PetarKirov PetarKirov Nov 19, 2017

Choose a reason for hiding this comment

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

According to spec, subtracting pointers pointing to objects of different types (regardless of size) is an error. In the case where we have pointers to different types, but with equal sizes, the result obviously would be the same if you cast one of the pointers to the same type as the other one, but such code may be actually be a mistake on the user's part. What are your opinions on being more strict, as the spec dictates?

(I just saw that @LemonBoy is also in favor of the more strict approach #6440 (comment).)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, I'm for following the spec. I'll update the PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My understanding is the Type.equivalent() function is all that's needed. I think the size comparison in the previous commit was unnecessary.

Again, I think this is ready to go unless I'm missing something.

@JinShil
Copy link
Contributor Author

JinShil commented Nov 20, 2017

Is jenkins dub just finicky or what?

@WalterBright
Copy link
Member

@andralex it is nice that this PR found a bug.

if (t2.ty == Tpointer)
{
// https://issues.dlang.org/show_bug.cgi?id=11006
Type p1 = t1.nextOf();
Copy link
Member

@WalterBright WalterBright Nov 20, 2017

Choose a reason for hiding this comment

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

Not much point here to linking to the bug report. Instead link to the relevant spec
https://dlang.org/spec/expression.html#add_expressions and add the quote: "If both operands are pointers, and the operator is -, the pointers are subtracted and the result is divided by the size of the type pointed to by the operands. It is an error if the pointers point to different types."

Linking to and quoting from the spec should be a good way to clarify what's going on in the implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done. Thanks!

@dlang-bot dlang-bot merged commit 523301b into dlang:master Nov 20, 2017
@JinShil JinShil deleted the fix_11006 branch November 27, 2017 02:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants