Question: Given the following example code:

```
int var;
int mvar;
std::mutex mvar_mutex;

void f(){
    mvar_mutex.lock();
    mvar = var * var;
    mvar_mutex.unlock();
}

```

I want to express that `mvar_mutex` is bound to the variable `mvar` and protects only that variable. `mvar_mutex` should not protect `var` because it is not bound to it. Hence the compiler would be allowed to transform the above code into the below code:

```
int var;
int mvar;
std::mutex mvar_mutex;

void f(){
    int r = var * var; //possible data race created if binding is not known
    mvar_mutex.lock();
    mvar = r;
    mvar_mutex.unlock();
}

```

This might reduce contention on the lock as less work is being done while holding it.

For `int` this can be done using `std::atomic<int> mvar;` and removing `mvar_mutex`, but for other types such as `std::vector<int>` this is not possible.

How do I express the mutex-variable binding in a way that C++ compilers understand it and do the optimization? It should be allowed to reorder any variable up or down across mutex boundaries for any variable that is not bound to that mutex

Since the code is being generated using `clang::ASTConsumer` and `clang::RecursiveASTVisitor` I am willing to use non-standard extensions and AST manipulations as long as clang (ideally clang 4.0) supports them and the resulting code does not need to be elegant or human-readable.

Edit since this seems to be causing confusion: The above transformation is not legal in C++. The described binding of mutex to variable doesn't exist. The question is about how to implement that or achieve the same effect.

Answer: 
If you wish to achieve that the `std::mutex` will only be held until an operation is performed on the protected object, you can write a wrapper `class` as follows:

```
#include <cstdio>
#include <mutex>

template<typename T>
class LockAssignable {
public:
    LockAssignable& operator=(const T& t) {
        std::lock_guard<std::mutex> lk(m_mutex);
        m_protected = t;
        return *this;
    }
    operator T() const {
        std::lock_guard<std::mutex> lk(m_mutex);
        return m_protected;
    }    
    /* other stuff */
private:
    mutable std::mutex m_mutex;
    T m_protected {};
};

inline int factorial(int n) {
    return (n > 1 ? n * factorial(n - 1) : 1);
}

int main() {
    int var = 5;
    LockAssignable<int> mvar;

    mvar = factorial(var);
    printf("Result: %d\n", static_cast<int>(mvar));
    return 0;
}

```

In the example above the `factorial` will be calculated in advance and the `m_mutex` will be acquired only when the assignment or the implicit conversion operator being called on `mvar`.

`[Assembly Output](https://godbolt.org/g/5HW1Qb)`
How about a locked var template ?

```
template<typename Type, typename Mutex = std::mutex>
class Lockable
{
public:
   Lockable(_Type t) : var_(std::move(t));
   Lockable(_Type&&) = default;
   // ...  could need a bit more

   T operator = (const T& x) 
   { 
      std::lock_guard<Lockable> lock(*this);
      var_ = x;
      return x;
   }

   T operator *() const
   { 
      std::lock_guard<Lockable> lock(*this);
      return var_;
   }

   void lock() const   { const_cast<Lockable*>(this)->mutex_.lock(); }
   void unlock() const { const_cast<Lockable*>(this)->mutex_.unlock().; }
private:
  Mutex mutex_;
  Type var_;
};

```

locked by assignment operator

```
Lockable<int>var;
var = mylongComputation();

```

Works great with lock\_guard

```
Lockable<int>var;
std::lock_guard<Lockable<int>> lock(var);
var = 3;

```

Practical on containers

```
Lockable<std::vector<int>> vec;

```

etc...