Skip to content

Commit 906c78a

Browse files
author
Liu Yafei
committed
fix bug: conditional expression type and phi node type
1 parent 1caf6cc commit 906c78a

File tree

3 files changed

+52
-64
lines changed

3 files changed

+52
-64
lines changed

includes/sema/ast.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,7 @@ class BinaryOperatorAST : public IBinaryOperationAST {
736736
static std::tuple<Type *, llvm::Value *, llvm::Value *> UsualArithmeticConversions(Value &lhs,
737737
Value &rhs,
738738
const AST *ast);
739+
static bool UsualArithmeticConversions(Type* lhs, Type* rhs, const AST *ast);
739740
protected:
740741
nt<IBinaryOperationAST> mLeft;
741742
Terminal<InfixOp> mOp;

main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ int main() {
2222
testFile.open("test.c");
2323
auto parser = Parser(testFile);
2424
auto tr = parser.parseTranslationUnit();
25-
tr->print(0);
25+
// tr->print(0);
2626
tr->codegen();
2727
AST::getModule()->print(llvm::outs(), nullptr);
2828
// } catch (const SemaException &e) {

src/sema/ast.cpp

Lines changed: 50 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,8 @@ Value ConditionalExpressionAST::codegen() {
634634
auto *falseBlock = llvm::BasicBlock::Create(getContext());
635635
auto *endBlock = llvm::BasicBlock::Create(getContext());
636636

637+
Type *type;
638+
637639
if (auto *ltype = dynamic_cast<IntegerType *> (condValue.getType())) {
638640
auto *const0 = llvm::ConstantInt::get(ltype->getLLVMType(), 0);
639641
cond = sBuilder.CreateICmpNE(condValue.getValue(), const0);
@@ -650,34 +652,41 @@ Value ConditionalExpressionAST::codegen() {
650652
// true block
651653
sBuilder.SetInsertPoint(trueBlock);
652654
auto exp1 = expression->codegen();
653-
if (!sBuilder.GetInsertBlock()->getTerminator())
654-
sBuilder.CreateBr(endBlock);
655+
llvm::Value *trueValue = exp1.getValue();
655656

656657
// false block
657658
currentFunction->getBasicBlockList().push_back(falseBlock);
658659
sBuilder.SetInsertPoint(falseBlock);
659660
auto exp2 = conditional_expression->codegen();
660-
Type *type;
661-
llvm::Value *trueValue = exp1.getValue();
662661
llvm::Value *falseValue = exp2.getValue();
663662

664-
if (dynamic_cast< ArithmeticType *>(exp1.getType())
665-
&& dynamic_cast< ArithmeticType *>(exp2.getType())) {
666-
std::tie(type, trueValue, falseValue) = BinaryOperatorAST::UsualArithmeticConversions(exp1, exp2, this);
667-
} else if ((dynamic_cast< StructType *>(exp1.getType())
668-
|| dynamic_cast< UnionType *>(exp1.getType()))
669-
&& exp1.getType() == exp2.getType()) {
670-
type = exp1.getType();
671-
} else if (exp1.getType() == &VoidType::sVoidType
672-
&& exp2.getType() == &VoidType::sVoidType) {
663+
Type* lType = exp1.getType();
664+
Type* rType = exp2.getType();
665+
if (dynamic_cast< ArithmeticType *>(lType)
666+
&& dynamic_cast< ArithmeticType *>(rType)) {
667+
if (BinaryOperatorAST::UsualArithmeticConversions(lType, rType, this)) {
668+
sBuilder.SetInsertPoint(falseBlock);
669+
falseValue = rType->castTo(lType, falseValue, this);
670+
type = lType;
671+
} else {
672+
sBuilder.SetInsertPoint(trueBlock);
673+
trueValue = lType->castTo(rType, trueValue, this);
674+
type = rType;
675+
}
676+
} else if ((dynamic_cast< StructType *>(lType)
677+
|| dynamic_cast< UnionType *>(lType))
678+
&& lType == rType) {
679+
type = lType;
680+
} else if (lType == &VoidType::sVoidType
681+
&& rType == &VoidType::sVoidType) {
673682
type = &VoidType::sVoidType;
674-
} else if (dynamic_cast< PointerType *>(exp1.getType())
675-
&& dynamic_cast< PointerType *>(exp2.getType())) {
676-
if (exp1.getType()->compatible(exp2.getType())) {
677-
type = exp1.getType();
683+
} else if (dynamic_cast< PointerType *>(lType)
684+
&& dynamic_cast< PointerType *>(rType)) {
685+
if (lType->compatible(rType)) {
686+
type = lType;
678687
} else {
679-
auto *p1 = static_cast<PointerType *>(exp1.getType());
680-
auto *p2 = static_cast<PointerType *>(exp2.getType());
688+
auto *p1 = static_cast<PointerType *>(lType);
689+
auto *p2 = static_cast<PointerType *>(rType);
681690
if (p1->getReferencedQualifiedType().getType() == &VoidType::sVoidType
682691
&& dynamic_cast< ObjectType *> (p2->getReferencedQualifiedType().getType())) {
683692
type = p1;
@@ -693,6 +702,11 @@ Value ConditionalExpressionAST::codegen() {
693702
} else {
694703
throw SemaException("incompatible operand types", involvedTokens());
695704
}
705+
sBuilder.SetInsertPoint(trueBlock);
706+
if (!sBuilder.GetInsertBlock()->getTerminator())
707+
sBuilder.CreateBr(endBlock);
708+
709+
sBuilder.SetInsertPoint(falseBlock);
696710
if (!sBuilder.GetInsertBlock()->getTerminator())
697711
sBuilder.CreateBr(endBlock);
698712

@@ -2396,51 +2410,11 @@ BinaryOperatorAST::UsualArithmeticConversions(Value &lhs, Value &rhs, const AST
23962410
Type *rType = rhs.getType();
23972411
llvm::Value *lValue = lhs.getValue();
23982412
llvm::Value *rValue = rhs.getValue();
2399-
2400-
while (true) {
2401-
if (auto *li = dynamic_cast< IntegerType *>(lType)) {
2402-
if (auto *ri = dynamic_cast< IntegerType *>(rType)) {
2403-
if (li->getSizeInBits() > ri->getSizeInBits()) {
2404-
rValue = ri->castTo(li, rValue, ast);
2405-
rType = lType;
2406-
break;
2407-
} else if (li->getSizeInBits() == ri->getSizeInBits()) {
2408-
if (!li->isSigned() || !ri->isSigned()) {
2409-
lType = !li->isSigned() ? li : ri;
2410-
}
2411-
break;
2412-
} else {
2413-
lValue = li->castTo(ri, lValue, ast);
2414-
lType = rType;
2415-
break;
2416-
}
2417-
} else if (auto *rf = dynamic_cast< FloatingType *>(rType)) {
2418-
lValue = li->castTo(rf, lValue, ast);
2419-
lType = rf;
2420-
break;
2421-
}
2422-
} else if (auto *lf = dynamic_cast< FloatingType *>(lType)) {
2423-
if (auto *ri = dynamic_cast< IntegerType *>(rType)) {
2424-
rValue = ri->castTo(lf, rValue, ast);
2425-
break;
2426-
} else if (auto *rf = dynamic_cast< FloatingType *>(rType)) {
2427-
if (lf->getSizeInBits() > rf->getSizeInBits()) {
2428-
rValue = rf->castTo(lf, rValue, ast);
2429-
rType = lType;
2430-
break;
2431-
} else if (lf->getSizeInBits() == rf->getSizeInBits()) {
2432-
break;
2433-
} else {
2434-
lValue = lf->castTo(rf, lValue, ast);
2435-
lType = rType;
2436-
break;
2437-
}
2438-
}
2439-
}
2440-
throw SemaException("operands must be integer or float type", ast->involvedTokens());
2413+
if (UsualArithmeticConversions(lType, rType, ast)) {
2414+
return {lType, lValue, rType->castTo(lType, rValue, ast)};
2415+
} else {
2416+
return {rType, lType->castTo(rType, lValue, ast), rValue};
24412417
}
2442-
return {lType, lValue, rValue};
2443-
24442418
}
24452419
Value BinaryOperatorAST::codegen(Value &lhs,
24462420
Value &rhs,
@@ -2736,6 +2710,19 @@ Value BinaryOperatorAST::codegen(Value &lhs,
27362710
}
27372711
throw SemaException("invalid operands to binary expression", lAST->involvedTokens());
27382712
}
2713+
bool BinaryOperatorAST::UsualArithmeticConversions(Type *lhs, Type *rhs, const AST *ast) {
2714+
if (dynamic_cast<IntegerType *>(lhs) && dynamic_cast<IntegerType *>(rhs)) {
2715+
return static_cast<IntegerType *>(lhs)->getSizeInBits() > static_cast<IntegerType *>(rhs)->getSizeInBits();
2716+
} else if (dynamic_cast<IntegerType *>(lhs) && dynamic_cast<FloatingType *>(rhs)) {
2717+
return false;
2718+
} else if (dynamic_cast<FloatingType *>(lhs) && dynamic_cast<IntegerType *>(rhs)) {
2719+
return true;
2720+
} else if (dynamic_cast<FloatingType *>(lhs) && dynamic_cast<FloatingType *>(rhs)) {
2721+
return static_cast<FloatingType *>(lhs)->getSizeInBits() > static_cast<FloatingType *>(rhs)->getSizeInBits();
2722+
} else {
2723+
throw SemaException("operands must be integer or float type", ast->involvedTokens());
2724+
}
2725+
}
27392726
Value LogicalBinaryOperatorAST::codegen() {
27402727
auto *currentFunction = sBuilder.GetInsertBlock()->getParent();
27412728
auto *thisBlock = sBuilder.GetInsertBlock();

0 commit comments

Comments
 (0)