// to depend on a finalizer to flush an in-memory I/O buffer such as a
 // bufio.Writer, because the buffer would not be flushed at program exit.
 //
+// It is not guaranteed that a finalizer will run if the size of *x is
+// zero bytes.
+//
 // A single goroutine runs all finalizers for a program, sequentially.
 // If a finalizer must run for a long time, it should do so by starting
 // a new goroutine.
 
                runtime·printf("runtime.SetFinalizer: first argument is %S, not pointer\n", *obj.type->string);
                goto throw;
        }
+       ot = (PtrType*)obj.type;
+       if(ot->elem != nil && ot->elem->size == 0) {
+               return;
+       }
        if(!runtime·mlookup(obj.data, &base, &size, nil) || obj.data != base) {
                runtime·printf("runtime.SetFinalizer: pointer not at beginning of allocated block\n");
                goto throw;
        }
        nret = 0;
-       ot = (PtrType*)obj.type;
        fint = nil;
        if(finalizer.type != nil) {
                if(finalizer.type->kind != KindFunc)
 
 func fin(v *int) {
 }
 
+// Verify we don't crash at least. golang.org/issue/6857
+func TestFinalizerZeroSizedStruct(t *testing.T) {
+       type Z struct{}
+       z := new(Z)
+       runtime.SetFinalizer(z, func(*Z) {})
+}
+
 func BenchmarkFinalizer(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)