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

Suppress the "read-modify-write" error if type is a struct or a class #10281

Merged
merged 1 commit into from Aug 8, 2019
Merged

Suppress the "read-modify-write" error if type is a struct or a class #10281

merged 1 commit into from Aug 8, 2019

Conversation

ErnyTech
Copy link
Contributor

@ErnyTech ErnyTech commented Aug 6, 2019

If a struct or class with shared type implements the opUnary or opOpAssign
operator then it is possible to perform "read-modify-write" operations
because the operator's implementation is supposed to perform atomic operations.

The purpose of this modification is to allow the creation of wrappers
(with structs or classes) to run atomic operations silently, for example:

shared struct Atomic {
    int a;

    int opUnary(string s)() if (s == "++")
    {
        import core.atomic : atomicOp;
        return atomicOp!"+="(a, 1);
    }
}

Atomic atomicvar;
atomicvar++; // Safe! Atomic struct implements opUnary

@dlang-bot
Copy link
Contributor

Thanks for your pull request and interest in making D better, @ErnyTech! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub fetch digger
dub run digger -- build "master + dmd#10281"

Geod24
Geod24 previously requested changes Aug 6, 2019
Copy link
Member

@Geod24 Geod24 left a comment

Choose a reason for hiding this comment

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

No test

@@ -1353,7 +1353,7 @@ extern (C++) abstract class Expression : ASTNode
extern (D) final bool checkReadModifyWrite(TOK rmwOp, Expression ex = null)
{
//printf("Expression::checkReadModifyWrite() %s %s", toChars(), ex ? ex.toChars() : "");
if (!type || !type.isShared())
if (!type || !type.isShared() || type.isTypeStruct() || type.isTypeClass())
Copy link
Member

Choose a reason for hiding this comment

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

That doesn't look right. It's blindly allowing struct / class

Copy link
Contributor Author

@ErnyTech ErnyTech Aug 6, 2019

Choose a reason for hiding this comment

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

If the class/struct does not implement the operator the compiler will give the error "is not a scalar"

if (exp.e1.checkScalar() ||

So I don't think further checks are necessary

@ErnyTech
Copy link
Contributor Author

ErnyTech commented Aug 6, 2019

Added compilable test

@thewilsonator thewilsonator dismissed Geod24’s stale review August 7, 2019 01:16

Compilable test added.

@thewilsonator
Copy link
Contributor

Searching for tabs
./changelog/pending.dd:321:	int opUnary(string s)() if (s == "++")
./changelog/pending.dd:322:	{
./changelog/pending.dd:323:		import core.atomic : atomicOp;
./changelog/pending.dd:324:		return atomicOp!"+="(a, 1);
./changelog/pending.dd:325:	}

{
S s;
s++;
shared(C) c = new C();
Copy link
Member

Choose a reason for hiding this comment

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

Why does this need to be shared if C is a shared class ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Using shared in the class declaration does not seem to make the class type "implicitly" shared unlike what it does in a struct

Copy link
Contributor Author

@ErnyTech ErnyTech left a comment

Choose a reason for hiding this comment

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

I realized that the formatting has problems (badly converted tabs), I have to solve it

If a struct or class with shared type implements the opUnary or opOpAssign
operator then it is possible to perform "read-modify-write" operations
because the operator's implementation is supposed to perform atomic operations.

Signed-off-by: Ernesto Castellotti <erny.castell@gmail.com>
@ErnyTech
Copy link
Contributor Author

ErnyTech commented Aug 7, 2019

I realized that the formatting has problems (badly converted tabs), I have to solve it

Fixed

@dlang-bot dlang-bot merged commit cb5997b into dlang:master Aug 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants