Maps and channels and functions are passed by reference. Slices are passed and returned by value but sometimes share state invisibly, the worst of both worlds. It would make more sense if Go either made this stuff immutable, made defensive copies, or refused and required using explicit pointers for all these cases.
No, it's not the case and this terminology shouldn't be used as it's confusing and unhelpful.
There are reference types in Go even though this is also not a super popular term. They still follow the pass-by-value semantics, it's just that a pointer is copied. A map is effectively a pointer to hmap data structure.
In the early days of Go, there was an explicit pointer, but then it was changed.
Slices are a 3-word structure internally that includes a pointer to a backing array and this is why it's also a "reference type".
That said, everything is still passed by value and there are no references in Go.
foo is receiving a mutable reference and it can't modify the map without those changes leaking out permanently to the caller: https://go.dev/play/p/DXchC5Hq8o8. Passing maps by value would have prevented this by copying the contents.
It's a quirk of C++ that reference args can't be replaced but pointer args can.
The point is that the local variable referencing the map is a different entity than the map itself. Foo gets a copy of that local variable, and the copy references the same map object.
And the fact that C++ references can be used for assignment is essentially their whole point, not "a quirk".