As written, it's a bit iffy. Reason being, technically, the function should regain control in order to &&
the result to know what to return. (This is easily optimized away, though, and most compilers will probably do so.)
In order to make sure it's tail-recursive, simply avoid doing anything with the result other than returning it.
int sum_n(int n, int *sum)
{
if (!(n && (*sum += n))) return 0;
return sum_n(n - 1, sum);
}