Q:

Timer 1 (16 bit): Why is overflow interrupt sometimes missed?

Initialization of timer 1, the 16 bit timer on the ATmega328:
TCCR1A = 0; // normal operation
TCCR1B = bit(CS10); // no prescaling
OCR1A = 0;
OCR1B = 0;
TIMSK1 |= bit(TOIE1); // Timer/Counter 1, Overflow Interrupt Enable

16 bit overflows increment an overflow counter:
ISR(TIMER1_OVF_vect) {
    timer1OverflowCount ++;
}

In a loop it is checked whether the two 16 bit counters increment correctly:
void loop() {
  static uint16_t lastOc = 0, lastC = 0;
  uint16_t oc, c;

  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    oc = timer1OverflowCount;
    c = TCNT1;
  }

  if (c < lastC && oc == lastOc) {
    print(oc, c, lastOc, lastC);
  }

  lastOc = oc;
  lastC = c;
}

Sample output to the serial console:
Bad overflow: oc = 31, c = 49, lastOc = 31, lastC = 65440
Bad overflow: oc = 58, c = 49, lastOc = 58, lastC = 65440
Bad overflow: oc = 66, c = 49, lastOc = 66, lastC = 65440
Bad overflow: oc = 118, c = 49, lastOc = 118, lastC = 65440
Bad overflow: oc = 127, c = 49, lastOc = 127, lastC = 65440

Why does the overflow counter sometimes not get incremented?
I understand that the loop accesses the overflow counter a lot. During an access, interrupts are turned of with ATOMIC_BLOCK(ATOMIC_RESTORESTATE). However, the access is fast, and I expect the overflow interrupt to get queued so that it is never missed.
Full code for the Arduino Pro Mini ATmega328P (5V, 16MHz), compatible with the Arduino IDE 1.8.1:
#include <util/atomic.h>

volatile uint16_t timer1OverflowCount = 0;

ISR(TIMER1_OVF_vect) {
  timer1OverflowCount ++;
}

void setup() {
  TCCR1A = 0; // normal operation
  TCCR1B = bit(CS10); // no prescaling
  OCR1A = 0;
  OCR1B = 0;
  TIMSK1 |= bit(TOIE1); // Timer/Counter 1, Overflow Interrupt Enable

  Serial.begin(9600);
}

void print(uint16_t oc, uint16_t c, uint16_t lastOc, uint16_t lastC) {
  Serial.print("Bad overflow: ");
  Serial.print("oc = ");
  Serial.print(oc);
  Serial.print(", c = ");
  Serial.print(c);
  Serial.print(", lastOc = ");
  Serial.print(lastOc);
  Serial.print(", lastC = ");
  Serial.println(lastC);
}

void loop() {
  static uint16_t lastOc = 0, lastC = 0;
  uint16_t oc, c;

  ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
    oc = timer1OverflowCount;
    c = TCNT1;
  }

  if (c < lastC && oc == lastOc) {
    print(oc, c, lastOc, lastC);
  }

  lastOc = oc;
  lastC = c;
}

A:

The problem is that you are not eliminating the actual issue with the ATOMIC statement- the counter is incrementing in hardware and there will be times when an interrupt is pending but not completed. It's worse because the C int operations take a lot of cycles on an 8-bit processor, but it would show up even in tight asm code. 
If you don't have any other interrupts of much duration going on you don't even have to kill interrupts, you can simply correct the count. 
The general approach is as follows:

read timer1OverflowCount, first timer1OverflowCount sample 
read the hardware counter TCNT1  <-- right here is when you are sampling with high resolution
read timer1OverflowCount again, second timer1OverflowCount sample 

If timer1OverflowCount has changed (incremented), then look at the sample from TCNT1. If it has MSB = 0 then use the later timer1OverflowCount. If it has MSB=1 then use the earlier timer1OverflowCount. 
There is no need to turn interrupts off unless there are other interrupts with slow ISRs going on that could cause the total time for the above to approach the time for the hardware counter to reach 1/2 of full count. It's almost always undesirable to turn off interrupts unless absolutely necessary. 
Edit: In your case you have an int for the overflow so you need to make the read of the variable changed within the ISR atomic, as well as dealing with the issue above. 

A:

The ATOMIC_BLOCK is executed without interruption but the instructions inside are not executed in the same time. 
From "oc = timer1OverflowCount;" to "c = TCNT1;" TCNT1 is incremented and is not the same as when reading oc. 
The error shows when the overflow occurs inside the ATOMIC block and timer1OverflowCount cannot be updated and even the interrupts were disabled TCNT1 will show a later value than timer1OverflowCount.
Switch the two instructions, place each in it's own ATOMIC block and see the result. It is a "false positive". I assumed you just that you just want to check that your TCNT1 overflow interrupt it's working well, It works but the code used is showing errors where they aren't.
At OP request I add the explanation for reading TCNT1 in it's own atomic block. 
Reading the 16 bit TCNT1 register is safe regarding it's incrementation between two 8 bit LSB and MSB register readings, when reading LSB the MSB register is buffered and all further readings will show the same value at the moment when LSB was read. 
But having an interrupt between the two readings that also reads TCNT1 will update the value of the buffered  MSB with the new value that might be different. 
I don't know if applies here but other 16bit register might share the same buffer as TCNT1.
You can watch overflow count for a fixed time to see if has any delay.
The code is fast but also executed without any break between loops. 
In the loop you have more or less five instructions, two transfers in the atomic block, and three outside. Can be added a jump and enable disable interrupts. The chance for this overflow to occur while executing the atomic block and to raise the error is pretty high.
So let's say the processor spend 2us for the ATOMIC block and 4us for the rest of the loop then again 2us in the ATOMIC block and again 4 outside. 
If the overflow occurs while in the ATOMIC block (which is 1/3 chance) while the interrupts are disabled and timer1OverflowCount cannot be incremented you have a pretty good chance to raise a false error. 
The chance is much lower because the compiler adds some code for the loop and also inside the ATOMIC block the overflow must occur before reading TCNT1 LSB.
This is the working code posted by OP in the comment:
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { c = TCNT1; } 
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { oc = timer1OverflowCount; }

I would like to add that this code is working using the conditions from the IF section 
if (c < lastC && oc == lastOc)

But if you check 
if (c >= lastC && oc != lastOc)

meaning changing overflow count without an overflow yo will also have false errors.
In this case, if it isn't just a code check then you should use something like   Spehro's answer reading the TCNT1 again ( also in it's ATOMIC block) and use the lowest value of TCNT1 in case of timer count change.
But if you need to do something when timer count is updating then check only the timer count (thread safe). It's working well.

A:

Looking at the 'bad' printouts we see lastC = 65440 and c = 49, which indicates that 96 counter ticks occurred between each timer read in the main loop. An overflow interrupt should have occurred at 65536, which is about half way through that time. 
But you are also reading timer1OverflowCount about half way through that time, so depending the exact timing of the interrupt it may or may not have occurred when you read the overflow count. When you read the timer the interrupt will have occurred and timer1OverflowCount will have incremented, but you are using the historical overflow count that may be before the timer overflowed.
To get a better idea of what is happening you could do another print out immediately after each 'bad' one, then you should see that timer1OverflowCount has 'mysteriously' incremented before the next interrupt! 
To fix the problem, don't read timer1OverflowCount until c < lastC. Then you will know that an overflow interrupt should have just occurred (and the next one is ~65000 ticks away) so you can reliably test the overflow count.

