diff options
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 23 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 5 |
2 files changed, 17 insertions, 11 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index 3c7115d6836..04dbe9760a2 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -262,19 +262,20 @@ CodeGenFunction::EmitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *E) { "EmitCXXFunctionalCastExpr - called with wrong cast"); CXXMethodDecl *MD = E->getTypeConversionMethod(); + assert(MD && "EmitCXXFunctionalCastExpr - null conversion method"); + assert(isa<CXXConversionDecl>(MD) && "EmitCXXFunctionalCastExpr - not" + " method decl"); const FunctionProtoType *FPT = MD->getType()->getAsFunctionProtoType(); - llvm::Constant *Callee; - if (CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(MD)) - Callee = CGM.GetAddrOfCXXConstructor(CD, Ctor_Complete); - else { - const llvm::Type *Ty = - CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), - FPT->isVariadic()); - Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); - } - llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress(); - return EmitCXXMemberCall(MD, Callee, This, 0, 0); + const llvm::Type *Ty = + CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD), + FPT->isVariadic()); + llvm::Constant *Callee = CGM.GetAddrOfFunction(GlobalDecl(MD), Ty); + llvm::Value *This = EmitLValue(E->getSubExpr()).getAddress(); + RValue RV = EmitCXXMemberCall(MD, Callee, This, 0, 0); + if (RV.isAggregate()) + RV = RValue::get(RV.getAggregateAddr()); + return RV; } llvm::Value *CodeGenFunction::LoadCXXThis() { diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 0d45ce91853..24442c3a733 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1172,6 +1172,11 @@ LValue CodeGenFunction::EmitConditionalOperator(const ConditionalOperator* E) { /// all the reasons that casts are permitted with aggregate result, including /// noop aggregate casts, and cast from scalar to union. LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) { + if (E->getCastKind() == CastExpr::CK_UserDefinedConversion) { + const CXXFunctionalCastExpr *CXXFExpr = cast<CXXFunctionalCastExpr>(E); + return LValue::MakeAddr(EmitCXXFunctionalCastExpr(CXXFExpr).getScalarVal(), 0); + } + // If this is an aggregate-to-aggregate cast, just use the input's address as // the lvalue. if (E->getCastKind() == CastExpr::CK_NoOp) |