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