Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any guarantee about whether code with UB should be reachable?

I have a code snippet from here:

volatile int volatileInt;
int usualInt;

void function (unsigned x, unsigned y, unsigned z)
{
    volatileInt = 0;
    usualInt = (x % y) / z;
}

int main()
{
    function(rand(), rand(), rand());
}

which I compile with Visual C++ 10 with /O2 and get this disassembly:

00403940  push        ebx  
00403941  push        esi  
   276:     function(rand(), rand(), rand());
00403942  mov         esi,dword ptr [__imp__rand (4050C0h)]  
00403948  push        edi  
00403949  call        esi  
0040394B  mov         edi,eax  
0040394D  call        esi  
0040394F  mov         ebx,eax  
00403951  call        esi  
00403953  xor         edx,edx  
00403955  div         eax,ebx  <<<< possible UB
00403957  mov         dword ptr [volatileInt (4074D0h)],0  
00403961  mov         eax,edx  
00403963  xor         edx,edx  
00403965  div         eax,edi  <<<< possible UB
00403967  pop         edi  
00403968  pop         esi  
00403969  pop         ebx  
0040396A  mov         dword ptr [usualInt (4074CCh)],eax  
   277:     return 0;
0040396F  xor         eax,eax
00403971  ret  

Note that there're two operations - "mod" and "div" that could possibly yield UB if their second operand is zero at runtime. In the emitted code both are implemented with div opcodes that will trigger a structured exception and crash the program is the second operand is zero.

The first div is before the volatile int variable is modified, but the second one is after volatile int is modified.

So if x is zero the program crashes without modifying the volatile int but if x is nonzero and y is zero then the program modifies volatile int and then crashes.

So depending on whether x or y are zero the program will exhibit different observable behavior.

Is such interleaving of code with possible UB with code that affects observable behavior allowed?

like image 654
sharptooth Avatar asked Jul 18 '12 09:07

sharptooth


1 Answers

Yes, this implementation is allowed. See 1.9/5:

A conforming implementation executing a well-formed program shall produce the same observable behavior as one of the possible executions of the corresponding instance of the abstract machine with the same program and the same input. However, if any such execution contains an undefined operation, this International Standard places no requirement on the implementation executing that program with that input (not even with regard to operations preceding the first undefined operation).

like image 153
hamstergene Avatar answered Nov 15 '22 00:11

hamstergene