diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -4331,6 +4331,16 @@ // If the true case is live, we need to track its region. if (CondExprBool) incrementProfileCounter(expr); + // If a throw expression we emit it and return an undefined lvalue + // because it can't be used. + if (auto *ThrowExpr = dyn_cast(live->IgnoreParens())) { + EmitCXXThrowExpr(ThrowExpr); + llvm::Type *Ty = + llvm::PointerType::getUnqual(ConvertType(dead->getType())); + return MakeAddrLValue( + Address(llvm::UndefValue::get(Ty), CharUnits::One()), + dead->getType()); + } return EmitLValue(live); } } diff --git a/clang/test/CodeGenCXX/throw-expressions.cpp b/clang/test/CodeGenCXX/throw-expressions.cpp --- a/clang/test/CodeGenCXX/throw-expressions.cpp +++ b/clang/test/CodeGenCXX/throw-expressions.cpp @@ -79,6 +79,12 @@ // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN6DR15601AD1Ev {{.*}} @_ZGRN6DR15601rE // CHECK-NOT: call {{.*}}@_ZN6DR15601AD1Ev + + // PR28184 + void conditional_throw() { + int a; + (true ? throw 0 : a) = 0; // CHECK: call void @__cxa_throw({{.*}}) + } } // CHECK-LABEL: define void @_Z5test7b(