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

bad closure if local variables have larger alignment requirements #17920

Open
dlangBugzillaToGithub opened this issue Aug 23, 2019 · 5 comments
Labels
Arch:x86_64 Issues specific to x86_64 P3 Severity:normal

Comments

@dlangBugzillaToGithub
Copy link

Rainer Schuetze (@rainers) reported this on 2019-08-23T09:35:35Z

Transferred from https://issues.dlang.org/show_bug.cgi?id=20154

CC List

Description

If a local variable has larger alignment requirements, closures that capture function arguments can fail:

struct SpinLock
{
    align(64) int x;
}

void collectReferences(int x) //ref HashTab references)
{
	SpinLock lock; // dmd BUG: alignment causes bad capture!

	void mark() scope nothrow
	{
		assert (x == 7);
	}

	mark();
}

void main()
{
	collectReferences(7);
}


For Win64, RSP is aligned according to alignof(SpinLock) for alignments 32-128. This makes the closure offset for the function argument x non-constant.

Side note: no alignment happens for align(256) or higher.

For Win32, alignment is silently omitted.
@dlangBugzillaToGithub
Copy link
Author

bugzilla (@WalterBright) commented on 2020-08-09T03:35:55Z

The alignment code is emitted for Win64, but not for Win32. But you listed the bug applying to x86_64.

So please clarify:

Is this working for 64 bit platforms?

@dlangBugzillaToGithub
Copy link
Author

bugzilla (@WalterBright) commented on 2020-08-09T03:42:43Z

Currently, stack alignment is enforced only for 64 bit compilations and 32 bit OSX compilations. See the setting of `enforcealign` in codgen() in cgcod.d.

@dlangBugzillaToGithub
Copy link
Author

bugzilla (@WalterBright) commented on 2020-08-09T04:17:41Z

A somewhat more illustrative test:


struct SpinLock
{
    align(64)
	int x;
}

void collectReferences(int x) //ref HashTab references)
{
    SpinLock lock = SpinLock(8); // dmd BUG: alignment causes bad capture!

    void mark() scope nothrow
    {
	assert(lock.x == 8);
	assert(x == 7);
    }

    mark();
}

void main()
{
    collectReferences(7);
}

@dlangBugzillaToGithub
Copy link
Author

r.sagitario commented on 2020-08-09T05:53:25Z

(In reply to Walter Bright from comment #1)
> The alignment code is emitted for Win64, but not for Win32. But you listed
> the bug applying to x86_64.

Win32 passes the assert, but ignores alignments.

> 
> So please clarify:
> 
> Is this working for 64 bit platforms?

No.

@dlangBugzillaToGithub
Copy link
Author

bugzilla (@WalterBright) commented on 2020-08-09T07:09:35Z

Thanks, I think I understand it now. But the solution isn't obvious :-/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Arch:x86_64 Issues specific to x86_64 P3 Severity:normal
Projects
None yet
Development

No branches or pull requests

1 participant