The plain.mp implementation of buildcycle fails to find the correct overlap between two cyclic paths if the beginning (point 0) of one of the paths lies inside the other path. For example:
beginfig(3);
path A, B; picture p[];
A = fullcircle scaled 2.5cm;
B = fullcircle scaled 2cm shifted (1cm,0);
p1 = image(fill buildcycle(A,B) withcolor .8[blue,white]; drawarrow A; drawarrow B;);
A := A rotated 180;
p2 = image(fill buildcycle(A,B) withcolor .8[blue,white]; drawarrow A; drawarrow B;);
B := B rotatedabout(center B,180);
p3 = image(fill buildcycle(A,B) withcolor .8[blue,white]; drawarrow A; drawarrow B;);
A := A rotated 180;
p4 = image(fill buildcycle(A,B) withcolor .8[blue,white]; drawarrow A; drawarrow B;);
for i=1 upto 4: draw p[i] shifted (120i,0); label(decimal i, (7mm+120i,0)); endfor
endfig;
produces

In each subfigure, the arrow head is pointing at the beginning of the path.
You can see that buildcycle only works in situation 2 where neither point 0 lies within the other cyclic path. Note that in situation 4 we get the union of the two paths.
Here's a way to correct this fault. First you need a function to determine whether a given point lies within a cyclic path. Following Sedgewick's Algorirthms in C, you can write:
% is point "p" inside cyclic path "ring" ?
vardef inside(expr p, ring) =
save t, count, test_line;
count := 0;
path test_line;
test_line = p -- (infinity, ypart p);
for i = 1 upto length ring:
t := xpart(subpath(i-1,i) of ring intersectiontimes test_line);
if ((0<=t) and (t<1)): count := count + 1; fi
endfor
odd(count)
enddef;
And here is an overlap function that replaces buildcycle in this special case of two overlapping cyclic paths.
vardef front_half primary p = subpath(0, 1/2 length p) of p enddef;
vardef back_half primary p = subpath(1/2 length p, length p) of p enddef;
% a and b should be cyclic paths...
vardef overlap(expr a, b) =
save p, q;
boolean p, q;
p = inside(point 0 of a, b);
q = inside(point 0 of b, a);
if ((not p) and (not q)):
buildcycle(a,b)
elseif (not p):
buildcycle(front_half b, a, back_half b)
elseif (not q):
buildcycle(front_half a, b, back_half a)
else:
buildcycle(front_half a, back_half b, front_half b, back_half a)
fi
enddef;
The basic idea is that if neither point 0 is inside the other path, then you just call buildcycle, otherwise you split the two cycles up into an appropriate sequence of half cycles. Replacing buildcycle in the above example with overlap gives this:

And replacing buildcycle in the OP example with overlap gives this:

which is probably closer to what was wanted in the first place.
Furthermore, if the two cyclic paths are running in opposite directions the behaviour of buildcycle is different again. Here's an extended version of the first example; in the second row, the larger path is running backwards:

To deal with this possibility you can make overlap more robust by using the useful counterclockwise function (from plain.mp) which returns a copy of a cyclic path running counterclockwise. Here is the improved version of the overlap function.
vardef overlap(expr a, b) =
save p, q, A, B;
boolean p, q;
p = not inside(point 0 of a, b);
q = not inside(point 0 of b, a);
path A, B;
A = counterclockwise a;
B = counterclockwise b;
if (p and q):
buildcycle(A,B)
elseif p:
buildcycle(front_half B, A, back_half B)
elseif q:
buildcycle(front_half A, B, back_half A)
else:
buildcycle(front_half A, back_half B, front_half B, back_half A)
fi
enddef;
which produces this in my extended example.

u:=10pt;– user19832 Jan 22 '14 at 13:34pat4=buildcycle(pat0,pat3)andshow pat4, I get(-77.10028,51.76262)..controls (-77.10014,51.76274) and (-77.10033,51.76294)..(-77.10046,51.76282)..controls (-77.1006,51.7627) and (-77.10042,51.7625)..cycle. I can't say why, but this explains why you don't see the filling. – egreg Jan 22 '14 at 14:17