Index: lib/CodeGen/CGCall.cpp =================================================================== --- lib/CodeGen/CGCall.cpp +++ lib/CodeGen/CGCall.cpp @@ -3102,9 +3102,17 @@ ReturnValueSlot ReturnValue, const CallArgList &CallArgs, const Decl *TargetDecl, - llvm::Instruction **callOrInvoke) { + llvm::Instruction **callOrInvoke, + bool forceCallInstCreation) { // FIXME: We no longer need the types from CallArgs; lift up and simplify. + // It may be nessesary to create a CallInst* even if TargetDecl is not given + // (e. g. when emitting a complex operation call). Without TargetDecl there is + // no way to check the NoUnwind attribute required for CallInst creation. Use + // specific flag then, but take care of possible logical violations. + assert(!(TargetDecl && forceCallInstCreation) && + "Should not force creation of CallInst if TargetDecl is present!"); + // Handle struct-return functions by passing a pointer to the // location that we would like to return into. QualType RetTy = CallInfo.getReturnType(); @@ -3442,7 +3450,7 @@ InvokeDest = getInvokeDest(); llvm::CallSite CS; - if (!InvokeDest) { + if (!InvokeDest || forceCallInstCreation) { CS = Builder.CreateCall(Callee, IRCallArgs); } else { llvm::BasicBlock *Cont = createBasicBlock("invoke.cont"); Index: lib/CodeGen/CGExprComplex.cpp =================================================================== --- lib/CodeGen/CGExprComplex.cpp +++ lib/CodeGen/CGExprComplex.cpp @@ -592,7 +592,7 @@ llvm::Instruction *Call; RValue Res = CGF.EmitCall(FuncInfo, Func, ReturnValueSlot(), Args, - nullptr, &Call); + nullptr, &Call, /*forceCallInstCreation =*/ true); cast(Call)->setCallingConv(CGF.CGM.getBuiltinCC()); cast(Call)->setDoesNotThrow(); Index: lib/CodeGen/CodeGenFunction.h =================================================================== --- lib/CodeGen/CodeGenFunction.h +++ lib/CodeGen/CodeGenFunction.h @@ -2651,7 +2651,8 @@ ReturnValueSlot ReturnValue, const CallArgList &Args, const Decl *TargetDecl = nullptr, - llvm::Instruction **callOrInvoke = nullptr); + llvm::Instruction **callOrInvoke = nullptr, + bool forceCallInstCreation = false); RValue EmitCall(QualType FnType, llvm::Value *Callee, const CallExpr *E, ReturnValueSlot ReturnValue, Index: test/CodeGenCXX/complex_mul_call.cpp =================================================================== --- test/CodeGenCXX/complex_mul_call.cpp +++ test/CodeGenCXX/complex_mul_call.cpp @@ -0,0 +1,24 @@ +// Check that multiplication of complex arguments is performed properly without +// assersion fails when exceptions are enabled. +// +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -emit-llvm %s -o - | FileCheck %s + +struct A { + int x; + A() { x = 10; } + ~A() { x = 20; } +}; + +int main() { + { + A a; + double __complex__ d; + float __complex__ f; + // CHECK-LABEL: main + // CHECK-DAG: call {{.*}} @__muldc3 + double __complex__ d1 = d * d; + // CHECK-DAG: call {{.*}} @__mulsc3 + float __complex__ f1 = f * f; + } + return 0; +}