Anyone familiar with the implementation of `synchronized` in the compiler?

Steven Schveighoffer schveiguy at gmail.com
Mon Mar 7 18:46:20 UTC 2022


On 3/7/22 12:47 PM, Atila Neves wrote:
> I took a cursory look at https://issues.dlang.org/show_bug.cgi?id=22626:
> 
> -----
>      class Oops {
>          synchronized void oops() {}
>      }
> -----
> % dmd -o- -preview=nosharedaccess d.d
> d.d(2): Error: direct access to shared `this` is not allowed, see 
> `core.atomic`
> 
> But I soon got lost in the codebase. The issue is SharedCheckVisitor in 
> expressionsem.d is checking `this`, which is shared, and thinks that 
> access to it is disallowed since it has no idea that the member function 
> is `synchronized`.
> 
> This is stopping me from transitioning nosharedaccess to be on by default.

Looking at the AST output, a synchronized function looks like:

```d
synchronized shared void oops()
	{
		shared shared(Oops) __sync2 = this;
		_d_monitorenter(__sync2);
		_d_monitorexit(__sync2);
	}
```
If we type this all out (except for the synchronized attribute), then it 
fails on any of those calls (the copy of the parameter, or the direct 
calls to monitorenter or monitorexit).

Which brings the question -- how do you call a function with a shared 
`this`? If this isn't possible, then there is something wrong with the 
preview implementation -- you should be able to abstract out your sync 
routines into functions without requiring casts.

This might come down to the fact that the this reference *itself* (as in 
the pointer on the stack) is shared, not just the thing it refers to.

-Steve


More information about the Digitalmars-d mailing list