https://bugs.winehq.org/show_bug.cgi?id=51899
--- Comment #12 from Bruni earns.61@gmail.com --- I've realized my previous comment contains a mistake.
So in if ((x && y) || !z) { body } expression,
it's enough for both x and y to be true or for z to be false to execute if's body.
So z can be split into separate if, which can be placed after original if, copying its body.
Which results in if (x && y) { body } if (!z) { body }
In if (x && y) { body } expression,
it's enough for x to be false to not execute if's body. And one can immediately return in our case, where if's body is the last block before `return`.
So one can decompose it as follows
if (!x) return if (y) { body } if (!z) { body }
Even if `x` is false, execution framework cannot leave the whole test expression until z is testified.
So `x` can be split from `y` only with testifying `z`
So get_dc_attr function body must be as follows.
DC_ATTR *get_dc_attr( HDC hdc ) { DWORD handle_type_bit_mask = 0x1f0000; DWORD type = gdi_handle_type( hdc ); DC_ATTR *dc_attr = get_gdi_client_ptr( hdc, 0 );
if (!type && dc_attr) return dc_attr->disabled ? NULL : dc_attr;
if ((type & handle_type_bit_mask) != NTGDI_OBJ_DC) { SetLastError( ERROR_INVALID_HANDLE ); return NULL; }
if (!dc_attr) { SetLastError( ERROR_INVALID_HANDLE ); return NULL; }
return dc_attr->disabled ? NULL : dc_attr; }
This variant looks correct to me.