Well, unless you're actually using armor or other stuff that alters the saving throw, it is correct to be 0. The code uses the saving_throws() function to find the _base_ saving throw and the adjusts it by your "personal" changes:
Code:
save = saving_throws(class_sav, type, GET_LEVEL(ch));
save += GET_SAVE(ch, type);
save += modifier;
/* Throwing a 0 is always a failure. */
if (MAX(1, save) < rand_number(0, 99))
So, working as intended.