Can anyone spot the deliberate mistake in this code:

llvm::Constant *CodeGenModule::GetAddrOfConstantCString(const  
std::string &str,
                                                         const char  
*GlobalName){
   return GetAddrOfConstantString(str + "\0", GlobalName);
}

This is what clang was using to generate NULL-terminated C strings.   
It is appending a C string containing just the NULL byte to a C++  
string.  Unfortunately, C strings can't contain just the NULL byte -  
"\0" is equivalent to "" with a zero byte after the string.  The  
result is that GetAddrOfConstantCString() did exactly the same as  
GetAddrOfConstantString - return an unterminated string.

Where the input was NULL-terminated, this was fine.  Where it wasn't,  
it was still sometimes fine, because the constant emitted afterwards  
might have started with a 0 byte.

This explains:

- Why modules without a constant string were crashing (the constant  
string contained a NULL, so they had something to terminate the  
string.  They were still doing the wrong thing, but  not crashing.

- Why Eric found some programs crashed in the ObjC load function - the  
class name was unterminated and so when they accessed it they found  
some invalid data.

- Why assignments to ivars didn't always work - the BigInt class  
lookup was failing because BigInteorybh6qw5hutih5 is not a valid class  
name.  The messages sent to construct the BigInt were then sent to  
nil, resulting in the value being 0 (the ivar was being assigned to,  
but with 0).

- Possibly some other weird crashes or unexplained behaviour.


Remember kids - Don't do C strings!

David

_______________________________________________
Etoile-dev mailing list
[email protected]
https://mail.gna.org/listinfo/etoile-dev

Reply via email to