I build the clang 3.8 branch on my linux machine (4.2.0-30-generic #36-Ubuntu SMP x86_64) using cmake from scratch. llvm and clang build fine.
But I get a stack clobber, when I execute the following code in "CodeGenFunction::generateObjCSetterBody". The same code has no problems on OS X.
ImplicitCastExpr argLoad(ImplicitCastExpr::OnStack,
argType.getUnqualifiedType(), CK_LValueToRValue,
expr, VK_RValue);
CastKind argCK = CK_NoOp;
===> if (ivarRef.getType()->isObjCObjectPointerType()) {
You can see in the following lldb session, why I suspect, that the compiler miscalculated some stack offsets. First I look at `argLoad` which is fine. Then I step over `ivarRef.getType()`, and `argLoad` is still fine. Then the result of `ivarRef.getType()` is stored in a temporary variable and *boom*, `argLoad` is now broken.
(lldb) p argLoad.dump()
ImplicitCastExpr 0x7fffffff9600 'id':'id' <LValueToRValue>
`-DeclRefExpr 0x7fffffff9660 'id':'id' lvalue ParmVar 0x9271378 'other' 'id':'id'
(lldb) nexti
Process 4075 stopped
* thread #1: tid = 4075, 0x00000000033d0173 clang-3.8`clang::CodeGen::CodeGenFunction::generateObjCSetterBody(this=0x00007fffffffa490, classImpl=0x00000000092713e0, propImpl=0x0000000009271468, AtomicHelperFn=0x0000000000000000) + 4009 at CGObjC.cpp:1617, name = 'clang-3.8', stop reason = instruction step over
frame #0: 0x00000000033d0173 clang-3.8`clang::CodeGen::CodeGenFunction::generateObjCSetterBody(this=0x00007fffffffa490, classImpl=0x00000000092713e0, propImpl=0x0000000009271468, AtomicHelperFn=0x0000000000000000) + 4009 at CGObjC.cpp:1617
1614 // Objective-C pointer types, we can always bit cast the RHS in these cases.
1615 // The following absurdity is just to ensure well-formed IR.
1616 CastKind argCK = CK_NoOp;
-> 1617 if (ivarRef.getType()->isObjCObjectPointerType()) {
1618 if (argLoad.getType()->isObjCObjectPointerType())
1619 argCK = CK_BitCast;
1620 else if (argLoad.getType()->isBlockPointerType())
-> 0x33d0173 <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4009>: callq 0x30fe538 ; clang::Expr::getType at Expr.h:125
0x33d0178 <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4014>: movq %rax, -0x370(%rbp)
0x33d017f <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4021>: leaq -0x370(%rbp), %rax
0x33d0186 <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4028>: movq %rax, %rdi
(lldb) nexti
Process 4075 stopped
* thread #1: tid = 4075, 0x00000000033d0178 clang-3.8`clang::CodeGen::CodeGenFunction::generateObjCSetterBody(this=0x00007fffffffa490, classImpl=0x00000000092713e0, propImpl=0x0000000009271468, AtomicHelperFn=0x0000000000000000) + 4014 at CGObjC.cpp:1617, name = 'clang-3.8', stop reason = instruction step over
frame #0: 0x00000000033d0178 clang-3.8`clang::CodeGen::CodeGenFunction::generateObjCSetterBody(this=0x00007fffffffa490, classImpl=0x00000000092713e0, propImpl=0x0000000009271468, AtomicHelperFn=0x0000000000000000) + 4014 at CGObjC.cpp:1617
1614 // Objective-C pointer types, we can always bit cast the RHS in these cases.
1615 // The following absurdity is just to ensure well-formed IR.
1616 CastKind argCK = CK_NoOp;
-> 1617 if (ivarRef.getType()->isObjCObjectPointerType()) {
1618 if (argLoad.getType()->isObjCObjectPointerType())
1619 argCK = CK_BitCast;
1620 else if (argLoad.getType()->isBlockPointerType())
-> 0x33d0178 <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4014>: movq %rax, -0x370(%rbp)
0x33d017f <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4021>: leaq -0x370(%rbp), %rax
0x33d0186 <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4028>: movq %rax, %rdi
0x33d0189 <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4031>: callq 0x30a6308 ; clang::QualType::operator-> at Type.h:634
(lldb) p ((ImplicitCastExpr *) 0x7fffffff9600)->dump()
ImplicitCastExpr 0x7fffffff9600 'id':'id' <LValueToRValue>
`-DeclRefExpr 0x7fffffff9660 'id':'id' lvalue ParmVar 0x9271378 'other' 'id':'id'
(lldb) p/x $rbp
(unsigned long) $74 = 0x00007fffffff99d0
(lldb) nexti
Process 4075 stopped
* thread #1: tid = 4075, 0x00000000033d017f clang-3.8`clang::CodeGen::CodeGenFunction::generateObjCSetterBody(this=0x00007fffffffa490, classImpl=0x00000000092713e0, propImpl=0x0000000009271468, AtomicHelperFn=0x0000000000000000) + 4021 at CGObjC.cpp:1617, name = 'clang-3.8', stop reason = instruction step over
frame #0: 0x00000000033d017f clang-3.8`clang::CodeGen::CodeGenFunction::generateObjCSetterBody(this=0x00007fffffffa490, classImpl=0x00000000092713e0, propImpl=0x0000000009271468, AtomicHelperFn=0x0000000000000000) + 4021 at CGObjC.cpp:1617
1614 // Objective-C pointer types, we can always bit cast the RHS in these cases.
1615 // The following absurdity is just to ensure well-formed IR.
1616 CastKind argCK = CK_NoOp;
-> 1617 if (ivarRef.getType()->isObjCObjectPointerType()) {
1618 if (argLoad.getType()->isObjCObjectPointerType())
1619 argCK = CK_BitCast;
1620 else if (argLoad.getType()->isBlockPointerType())
-> 0x33d017f <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4021>: leaq -0x370(%rbp), %rax
0x33d0186 <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4028>: movq %rax, %rdi
0x33d0189 <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4031>: callq 0x30a6308 ; clang::QualType::operator-> at Type.h:634
0x33d018e <clang::CodeGen::CodeGenFunction::generateObjCSetterBody+4036>: movq %rax, %rdi
(lldb) p ((ImplicitCastExpr *) 0x7fffffff9600)->dump()
ImplicitCastExpr 0x7fffffff9600clang-3.8: /home/nat/srcO/mulle-clang-install/src/llvm/include/llvm/Support/Casting.h:237: typename llvm::cast_retty<X, Y*>::ret_type llvm::cast(Y*) [with X = clang::Expr; Y = clang::Stmt; typename llvm::cast_retty<X, Y*>::ret_type = clang::Expr*]: Assertion `isa<X>(Val) && "cast<Ty>() argument of incompatible type!"' failed.
error: Execution was interrupted, reason: signal SIGABRT.
The process has been returned to the state before expression evaluation.
So OK, lets run clang tests and see if it the test suite catches this and maybe some other errors:
$ make clang-test
...
[ 80%] Built target libclang
Linking CXX executable libclangTests
/home/nat/srcO/mulle-clang-install/build/llvm.d/lib/libgtest.a(gtest-all.cc.o): In function `llvm::raw_os_ostream::raw_os_ostream(std::ostream&)':
/home/nat/srcO/mulle-clang-install/src/llvm/include/llvm/Support/raw_os_ostream.h:36: undefined reference to `vtable for llvm::raw_os_ostream'
/home/nat/srcO/mulle-clang-install/build/llvm.d/lib/libgtest.a(gtest-all.cc.o): In function `llvm::convertible_fwd_ostream::~convertible_fwd_ostream()':
/home/nat/srcO/mulle-clang-install/src/llvm/utils/unittest/googletest/include/gtest/internal/gtest-internal.h:107: undefined reference to `llvm::raw_os_ostream::~raw_os_ostream()'
collect2: error: ld returned 1 exit status
unittests/libclang/CMakeFiles/libclangTests.dir/build.make:87: recipe for target 'unittests/libclang/libclangTests' failed
make[3]: *** [unittests/libclang/libclangTests] Error 1
CMakeFiles/Makefile2:6456: recipe for target 'unittests/libclang/CMakeFiles/libclangTests.dir/all' failed
make[2]: *** [unittests/libclang/CMakeFiles/libclangTests.dir/all] Error 2
CMakeFiles/Makefile2:6551: recipe for target 'test/CMakeFiles/clang-test.dir/rule' failed
make[1]: *** [test/CMakeFiles/clang-test.dir/rule] Error 2
Makefile:1463: recipe for target 'clang-test' failed
make: *** [clang-test] Error 2
That's where I need some humoring, because I am seemingly stuck.
Ciao
Nat!