fix rdar://9780211 - Clang crashes with an assertion failure building WKView.mm from WebKit

This is something of a hack, the problem is as follows:

1. we instantiate both copied of RetainPtr with the two different argument types
   (an id and protocol-qualified id).
2. We refer to the ctor of one of the instantiations when introducing global "x",
   this causes us to emit an llvm::Function for a prototype whose "this" has type
   "RetainPtr<id<bork> >*".
3. We refer to the ctor of the other instantiation when introducing global "y",
   however, because it *mangles to the same name as the other ctor* we just use
   a bitcasted version of the llvm::Function we previously emitted.
4. We emit deferred declarations, causing us to emit the body of the ctor, however
   the body we emit is for RetainPtr<id>, which expects its 'this' to have an IR
   type of "RetainPtr<id>*".

Because of the mangling collision, we don't have this case, and explode.

This is really some sort of weird AST invariant violation or something, but hey
a bitcast makes the pain go away.

llvm-svn: 135572
This commit is contained in:
Chris Lattner 2011-07-20 06:29:00 +00:00
parent 58c62473cd
commit 7369c14b6a
2 changed files with 20 additions and 1 deletions

View File

@ -954,9 +954,13 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
if (Arg->getType().isRestrictQualified())
AI->addAttr(llvm::Attribute::NoAlias);
// Ensure the argument is the correct type.
if (V->getType() != ArgI.getCoerceToType())
V = Builder.CreateBitCast(V, ArgI.getCoerceToType());
if (isPromoted)
V = emitArgumentDemotion(*this, Arg, V);
EmitParmDecl(*Arg, V, ArgNo);
break;
}

View File

@ -24,3 +24,18 @@ namespace test0 {
}
}
// rdar://9780211
@protocol bork
@end
namespace test1 {
template<typename T> struct RetainPtr {
RetainPtr() {}
};
RetainPtr<id<bork> > x;
RetainPtr<id> y;
}