New code may alter assumptions of old code. Things not previously possible, and hence not coded for, suddenly become possible.
There are also the really nasty things like memory overruns, where code writes to memory locations it is not supposed to, corrupting random data, or even code. Sometimes code that has appeared stable, suddenly starts revealing it's true buggy nature. An example would be a memory overrun bug that just writes two bytes out of bounds. Since memory allocations happen in blocks, lets say of 32 bytes, this will not crash if the data structure is only 28 bytes. The erreneous write then happens at byte 30, which is not in unallocated memory, and hence an illegal operation, or in someone else's memory. But if the size of the data structure grows by four bytes, to accomodate a field needed by a new feature, the erreneous write now happens at byte 32, which is outside the allocated block.
This is just a few things I can think of in a hurry. It's complicated stuff this, which is why it breaks so easily. Low level languages like C++ is somewhat more fragile at this point than higher level languages like Java, C# or PHP.