Implements in IRgen gnu extensions missing LHS for

complex conditionals. Radar 8453812.

llvm-svn: 114376
This commit is contained in:
Fariborz Jahanian 2010-09-20 23:50:22 +00:00
parent f86e4da7ae
commit 8162d4ad31
4 changed files with 58 additions and 13 deletions

View File

@ -102,6 +102,15 @@ public:
// Visitor Methods
//===--------------------------------------------------------------------===//
ComplexPairTy Visit(Expr *E) {
llvm::DenseMap<const Expr *, ComplexPairTy>::iterator I =
CGF.ConditionalSaveComplexExprs.find(E);
if (I != CGF.ConditionalSaveComplexExprs.end())
return I->second;
return StmtVisitor<ComplexExprEmitter, ComplexPairTy>::Visit(E);
}
ComplexPairTy VisitStmt(Stmt *S) {
S->dump(CGF.getContext().getSourceManager());
assert(0 && "Stmt can't have complex result type!");
@ -622,13 +631,6 @@ ComplexPairTy ComplexExprEmitter::VisitBinComma(const BinaryOperator *E) {
ComplexPairTy ComplexExprEmitter::
VisitConditionalOperator(const ConditionalOperator *E) {
if (!E->getLHS()) {
CGF.ErrorUnsupported(E, "conditional operator with missing LHS");
const llvm::Type *EltTy =
CGF.ConvertType(E->getType()->getAs<ComplexType>()->getElementType());
llvm::Value *U = llvm::UndefValue::get(EltTy);
return ComplexPairTy(U, U);
}
TestAndClearIgnoreReal();
TestAndClearIgnoreImag();
@ -638,14 +640,19 @@ VisitConditionalOperator(const ConditionalOperator *E) {
llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("cond.false");
llvm::BasicBlock *ContBlock = CGF.createBasicBlock("cond.end");
CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
if (E->getLHS())
CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
else {
Expr *save = E->getSAVE();
assert(save && "VisitConditionalOperator - save is null");
// Intentianlly not doing direct assignment to ConditionalSaveExprs[save] !!
ComplexPairTy SaveVal = Visit(save);
CGF.ConditionalSaveComplexExprs[save] = SaveVal;
CGF.EmitBranchOnBoolExpr(E->getCond(), LHSBlock, RHSBlock);
}
CGF.EmitBlock(LHSBlock);
// Handle the GNU extension for missing LHS.
assert(E->getLHS() && "Must have LHS for complex value");
ComplexPairTy LHS = Visit(E->getLHS());
ComplexPairTy LHS = Visit(E->getTrueExpr());
LHSBlock = Builder.GetInsertBlock();
CGF.EmitBranch(ContBlock);

View File

@ -516,6 +516,7 @@ public:
/// to the IR for this expression. Used to implement IR gen. for Gnu
/// extension's missing LHS expression in a conditional operator expression.
llvm::DenseMap<const Expr *, llvm::Value *> ConditionalSaveExprs;
llvm::DenseMap<const Expr *, ComplexPairTy> ConditionalSaveComplexExprs;
EHScopeStack EHStack;

View File

@ -19,3 +19,18 @@ void test1 () {
if (x != y)
abort();
}
// rdar://8453812
_Complex int getComplex(_Complex int val) {
static int count;
if (count++)
abort();
return val;
}
_Complex int complx() {
_Complex int cond;
_Complex int rhs;
return getComplex(1+2i) ? : rhs;
}

View File

@ -22,3 +22,25 @@ int main () {
abort();
}
}
namespace radar8453812 {
extern "C" void abort();
_Complex int getComplex(_Complex int val) {
static int count;
if (count++)
abort();
return val;
}
_Complex int cmplx() {
_Complex int cond;
_Complex int rhs;
return getComplex(1+2i) ? : rhs;
}
int main() {
cmplx();
return 0;
}
}