December 03, 2023
https://issues.dlang.org/show_bug.cgi?id=24269

          Issue ID: 24269
           Summary: Members inside synchronized method should be only tail
                    shared
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: normal
          Priority: P1
         Component: dmd
          Assignee: nobody@puremagic.com
          Reporter: nick@geany.org

TDPL: https://www.informit.com/articles/article.aspx?p=1609144&seqNum=14

"typing of fields of a synchronized class inside a method goes as follows:

All numeric types are not shared (they have no tail) so they can be manipulated
normally.
Array fields declared with type T[] receive type shared(T)[]; that is, the head
(the slice limits) is not shared and the tail (the contents of the array)
remains shared.
Pointer fields declared with type T* receive type shared(T)*; that is, the head
(the pointer itself) is not shared and the tail (the pointed-to data) remains
shared.
Class fields declared with type T receive type shared(T). Classes are
automatically by-reference, so they're "all tail."
"

And should the same apply to `obj`'s fields inside a `synchronized(obj) statement;` when `obj` is `shared`?

--