return will exit the method; throw will also exit the method, assuming it is not inside the try. It can only exit once!
So regardless of the order - the first of the  throw / return effectively end the method.
As more general feedback, though: if the intent is to return false upon failure, all you need is:
try
{
    session.Save(obj);
    return true;
}
catch
{
    return false;
}
Personally, I would say that this is bad code - it hides the actual problem from the caller, making it very hard to debug. It tells us nothing of why it failed. I would say that the better approach is simply to let the exception bubble. In that case, there is no point returning true, because we would never return false - and there is no point catching an exception just to re-throw it. So the entire method becomes:
session.Save(obj);
(nothing else required whatsoever)
If your question is "why does only one of these generate a warning": a fair question, but the compiler isn't required to spot either of them for you. Perhaps it should spot it. I suspect that gmcs would spot this and warn about it - the compiler in mono is far more willing to point out stupidity.
Edit: as expected, [g]mcs outputs:
Program.cs(15,13): warning CS0162: Unreachable code detected
Program.cs(28,13): warning CS0162: Unreachable code detected
for the code below - so it does indeed report both uses as warnings:
class Program
{
    static void Main() { }
    static void DoSomething() { }
    bool ReturnFirst()
    {
        try
        {
            DoSomething();
            return true;
        }
        catch
        {
            return false;
            throw; // line 15
        }
    }
    bool ThrowFirst()
    {
        try
        {
            DoSomething();
            return true;
        }
        catch
        {
            throw;
            return false; // line 28
        }
    }
}