Indeed, probably a numerical issue. But can't you just get away with adding a small 'eps' as:
r = interpolate(Expression('1.0-DOLFIN_EPS', degree=1), S)
Which leads to a result numerically zero.
Now, if you want to bound it both from above and from below, you can consider the following approach:
from dolfin import *
import numpy as np
mesh = UnitSquareMesh(1,1)
S = FunctionSpace(mesh, 'CG', 1)
# Construct (conditional) expression
DOLFIN_EPS = 1E-14
v = Expression('cos(2*pi*x[0])',degree = 1)
# Augment with conditionals to restrict solution from above and from below:
c1 = conditional( ge(v, 1-DOLFIN_EPS), 1-DOLFIN_EPS, v )
c2 = conditional( le(v, -1+DOLFIN_EPS), -1+DOLFIN_EPS, c1 )
r = project(c2, S)
# Now you get finite results, both in FEniCS and with numpy!
acos_r = acos(r)
print project(acos_r,S).vector().array()
print np.arccos(r.vector().array())
Note that you actually can skip one projection step, so in the above presented code you can also do it just like this:
acos_r = acos(c2)
print project(acos_r,S).vector().array()
Furthermore, note that it really is a workaround. So no guarantees on robustness ;)