Почему из функции возвращается временный объект?
Там будет не временный объект, а тот же самый объект, что вы создали внутри функции. Даже копирования не будет. Хотя, у вас тут объект срезаться может поэтому ещё вопрос. Почитайте про RVO/NRVO.
Я немного поправил ваше решение:Foo get_foo(const char *msg)
{
    return Foo_2(msg);
}
Так будет лучше.
Но! Тут важно понимать, что делать так в реальном коде нельзя, т.к. объект класса Foo_2, при некоторых условиях, срежется до объекта класса Foo. В вашем случае -- это не проблема. Но можно переписать как-то так, например:const Foo &get_foo(const char *msg)
{
    static Foo_2 foo2(msg);
    return foo2;
}
Этот код тоже не для всех случаев подходит, т.к. get_foo будет возвращать всегда один и тот же объект с одним и тем же сообщением.
У тебя тут не внутренняя переменная возвращается, а копия объекта.
*r создается новый объект который инициализируется конструктором копирования из локального, тоже самое было бы если бы вернул temp
Ошибка была бы при функции вида Foo& get_foo(const char *msg)