When they say "parts are sliced off" they do not mean that these parts somehow "disappear": all they mean that these parts are not copied into the object presented to your function for the corresponding parameter. In this sense, object slicing is not dangerous or poorly defined.
What happens there is rather straightforward: in order to construct the value of the parameter that you are passing by value, the object of the derived class used for the actual parameter is given to the constructor of the base class to make a copy. Once the copy constructor has completed its work, you have an object of the base class.
At this point you have a fully functioning object of the base class. The compiler guards you against accepting a class with pure virtual members by value, so you wouldn't be able to slice your object into an instance with missing pure virtual functions.
A more important question is whether you want the slicing behavior to happen implicitly: there is nothing the compiler does here that you wouldn't be able to do in your code:
void foo(bar b) {
... // Payload logic
}
gives you the same functionality as
void foo(const bar &r) {
bar b(r);
... // Payload logic
}
With the first snippet, it is very easy to miss the fact that an ampersand is missing after the name of a type, leading the readers to think that the polymorphic behavior is retained, while it is, in fact, lost. The second snippet is easier to understand to people who maintain your code, because it makes a copy explicitly.