[cfe-dev] clang unable to build example C file

Török Edvin edwintorok at gmail.com
Fri Oct 12 04:50:23 PDT 2007


On 10/12/07, Chris Lattner <clattner at apple.com> wrote:
>
> It is somewhat convoluted, but len is set when the identifier is
> lexed.  The codepath is through the
> StringMap<IdentifierInfo>::GetOrCreateValue method, which calls
> StringMapEntry<IdentifierInfo>::Create, which sets the size on line
> 155 of llvm/include/llvm/ADT/StringMap.h.
>
> I don't see how there could be a problem here, everything looks
> reasonable.
>

Ok, it is something wrong with StringMap.h, but the testcases don't catch it.
See patch at end of this mail.

Look:
StringMapEntry on creation is:
(llvm::StringMapEntry<clang::IdentifierInfo> *) 0xaf5490

and IdentifierInfo is at 8 bytes distance:
print &II
$29 = (clang::IdentifierInfo *) 0xaf5498

but sizeof(StringMapEntryBase) is 4.

However offsetof(StringMapEntry, Val) == 8.

See below for a patch that changes -sizeof(StringMapEntryBase) to
offsetof(..), which should be safer, should such a change occur again
in the future, and also offsetof better expresses what the code does
IMHO.
Make check gives same results as before (3 ocaml bindings failure, 1
CodeGen failure).

When I apply this patch clang can successfully compile t.c!!

The CodeGen failure (both w/, and w/o my patch) is this one:
 FAIL: /home/edwin/llvm-svn/llvm/test/CodeGen/X86/2007-09-17-ObjcFrameEH.ll
Failed with exit(1) at line 1
while running: llvm-as <
/home/edwin/llvm-svn/llvm/test/CodeGen/X86/2007-09-17-ObjcFrameEH.ll |
llc -march=x86 -enable-eh | grep {isNullOrNil].eh"} | wc -l | grep 2
child process exited abnormally

Maybe a testsuite for StringMap would be useful?

--Edwin

Index: include/llvm/ADT/StringMap.h
===================================================================
--- include/llvm/ADT/StringMap.h        (revision 42869)
+++ include/llvm/ADT/StringMap.h        (working copy)
@@ -172,7 +172,7 @@
   /// into a StringMapEntry, return the StringMapEntry itself.
   static StringMapEntry &GetStringMapEntryFromValue(ValueTy &V) {
     return *reinterpret_cast<StringMapEntry*>(reinterpret_cast<char*>(&V) -
-                                              sizeof(StringMapEntryBase));
+                                              offsetof(StringMapEntry, Val) );
   }
   static const StringMapEntry &GetStringMapEntryFromValue(const ValueTy &V) {
     return GetStringMapEntryFromValue(const_cast<ValueTy&>(V));



More information about the cfe-dev mailing list