Submitted by:
Reviewed by:
Start hacking on binary ops...
Important bug fix...was ignoring the return value from ImplicitConversion.
This didn't bother the type checking logic, however the AST was malformed.

llvm-svn: 39410
This commit is contained in:
Steve Naroff 2007-04-20 23:42:24 +00:00
parent 4b7ce03f55
commit 5c10d4bac1
5 changed files with 70 additions and 30 deletions

View File

@ -228,7 +228,9 @@ private:
/// or will return true if the expressions didn't type check properly.
/// type checking binary operators (subroutines of ParseBinOp).
ExprResult CheckMultiplicativeOperands(Expr *op1, Expr *op2); // C99 6.5.5
ExprResult CheckMultiplicativeOperands(Expr *op1, Expr *op2,
SourceLocation OpLoc,
unsigned /*BinaryOperator::Opcode*/OpCode); // C99 6.5.5
ExprResult CheckAdditiveOperands(Expr *op1, Expr *op2); // C99 6.5.6
ExprResult CheckShiftOperands(Expr *op1, Expr *op2); // C99 6.5.7
ExprResult CheckRelationalOperands(Expr *op1, Expr *op2); // C99 6.5.8

View File

@ -182,7 +182,8 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
return CheckIndirectionOperand((Expr *)Input, OpLoc, Opc);
else {
// handle the arithmetic unary operators (C99 6.5.3.3)
QualType opType = ImplicitConversion((Expr *)Input)->getType();
Expr *operand = ImplicitConversion((Expr *)Input);
QualType opType = operand->getType();
assert(!opType.isNull() && "no type for arithmetic unary expression");
QualType resultType = opType;
@ -214,7 +215,7 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
default:
break;
}
return new UnaryOperator((Expr*)Input, Opc, resultType);
return new UnaryOperator(operand, Opc, resultType);
}
}
@ -395,25 +396,25 @@ Action::ExprResult Sema::ParseBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
}
// perform implicit conversions (C99 6.3)
Expr *e1 = ImplicitConversion((Expr*)LHS);
Expr *e2 = ImplicitConversion((Expr*)RHS);
Expr *lhs = ImplicitConversion((Expr*)LHS);
Expr *rhs = ImplicitConversion((Expr*)RHS);
if (BinaryOperator::isMultiplicativeOp(Opc))
CheckMultiplicativeOperands((Expr*)LHS, (Expr*)RHS);
return CheckMultiplicativeOperands(lhs, rhs, TokLoc, Opc);
else if (BinaryOperator::isAdditiveOp(Opc))
CheckAdditiveOperands((Expr*)LHS, (Expr*)RHS);
CheckAdditiveOperands(lhs, rhs);
else if (BinaryOperator::isShiftOp(Opc))
CheckShiftOperands((Expr*)LHS, (Expr*)RHS);
CheckShiftOperands(lhs, rhs);
else if (BinaryOperator::isRelationalOp(Opc))
CheckRelationalOperands((Expr*)LHS, (Expr*)RHS);
CheckRelationalOperands(lhs, rhs);
else if (BinaryOperator::isEqualityOp(Opc))
CheckEqualityOperands((Expr*)LHS, (Expr*)RHS);
CheckEqualityOperands(lhs, rhs);
else if (BinaryOperator::isBitwiseOp(Opc))
CheckBitwiseOperands((Expr*)LHS, (Expr*)RHS);
CheckBitwiseOperands(lhs, rhs);
else if (BinaryOperator::isLogicalOp(Opc))
CheckLogicalOperands((Expr*)LHS, (Expr*)RHS);
CheckLogicalOperands(lhs, rhs);
return new BinaryOperator((Expr*)LHS, (Expr*)RHS, Opc);
return new BinaryOperator(lhs, rhs, Opc);
}
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
@ -443,8 +444,24 @@ Expr *Sema::ImplicitConversion(Expr *E) {
return E;
}
Action::ExprResult Sema::CheckMultiplicativeOperands(Expr *op1, Expr *op2) {
return false;
Action::ExprResult Sema::CheckMultiplicativeOperands(
Expr *lexpr, Expr *rexpr, SourceLocation loc, unsigned code)
{
lexpr = ImplicitConversion((Expr *)lexpr);
rexpr = ImplicitConversion((Expr *)rexpr);
QualType ltype = lexpr->getType();
QualType rtype = rexpr->getType();
assert(!ltype.isNull() && "no left type for CheckMultiplicativeOperands()");
assert(!rtype.isNull() && "no right type for CheckMultiplicativeOperands()");
if ((BinaryOperator::Opcode)code == BinaryOperator::Rem) {
if (!ltype->isIntegralType() || !rtype->isIntegralType())
return Diag(loc, diag::err_typecheck_invalid_operands);
} else {
if (!ltype->isArithmeticType() || !rtype->isArithmeticType())
return Diag(loc, diag::err_typecheck_invalid_operands);
}
return new BinaryOperator(lexpr, rexpr, (BinaryOperator::Opcode)code);
}
Action::ExprResult Sema::CheckAdditiveOperands(Expr *op1, Expr *op2) {

View File

@ -228,7 +228,9 @@ private:
/// or will return true if the expressions didn't type check properly.
/// type checking binary operators (subroutines of ParseBinOp).
ExprResult CheckMultiplicativeOperands(Expr *op1, Expr *op2); // C99 6.5.5
ExprResult CheckMultiplicativeOperands(Expr *op1, Expr *op2,
SourceLocation OpLoc,
unsigned /*BinaryOperator::Opcode*/OpCode); // C99 6.5.5
ExprResult CheckAdditiveOperands(Expr *op1, Expr *op2); // C99 6.5.6
ExprResult CheckShiftOperands(Expr *op1, Expr *op2); // C99 6.5.7
ExprResult CheckRelationalOperands(Expr *op1, Expr *op2); // C99 6.5.8

View File

@ -182,7 +182,8 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
return CheckIndirectionOperand((Expr *)Input, OpLoc, Opc);
else {
// handle the arithmetic unary operators (C99 6.5.3.3)
QualType opType = ImplicitConversion((Expr *)Input)->getType();
Expr *operand = ImplicitConversion((Expr *)Input);
QualType opType = operand->getType();
assert(!opType.isNull() && "no type for arithmetic unary expression");
QualType resultType = opType;
@ -214,7 +215,7 @@ Action::ExprResult Sema::ParseUnaryOp(SourceLocation OpLoc, tok::TokenKind Op,
default:
break;
}
return new UnaryOperator((Expr*)Input, Opc, resultType);
return new UnaryOperator(operand, Opc, resultType);
}
}
@ -395,25 +396,25 @@ Action::ExprResult Sema::ParseBinOp(SourceLocation TokLoc, tok::TokenKind Kind,
}
// perform implicit conversions (C99 6.3)
Expr *e1 = ImplicitConversion((Expr*)LHS);
Expr *e2 = ImplicitConversion((Expr*)RHS);
Expr *lhs = ImplicitConversion((Expr*)LHS);
Expr *rhs = ImplicitConversion((Expr*)RHS);
if (BinaryOperator::isMultiplicativeOp(Opc))
CheckMultiplicativeOperands((Expr*)LHS, (Expr*)RHS);
return CheckMultiplicativeOperands(lhs, rhs, TokLoc, Opc);
else if (BinaryOperator::isAdditiveOp(Opc))
CheckAdditiveOperands((Expr*)LHS, (Expr*)RHS);
CheckAdditiveOperands(lhs, rhs);
else if (BinaryOperator::isShiftOp(Opc))
CheckShiftOperands((Expr*)LHS, (Expr*)RHS);
CheckShiftOperands(lhs, rhs);
else if (BinaryOperator::isRelationalOp(Opc))
CheckRelationalOperands((Expr*)LHS, (Expr*)RHS);
CheckRelationalOperands(lhs, rhs);
else if (BinaryOperator::isEqualityOp(Opc))
CheckEqualityOperands((Expr*)LHS, (Expr*)RHS);
CheckEqualityOperands(lhs, rhs);
else if (BinaryOperator::isBitwiseOp(Opc))
CheckBitwiseOperands((Expr*)LHS, (Expr*)RHS);
CheckBitwiseOperands(lhs, rhs);
else if (BinaryOperator::isLogicalOp(Opc))
CheckLogicalOperands((Expr*)LHS, (Expr*)RHS);
CheckLogicalOperands(lhs, rhs);
return new BinaryOperator((Expr*)LHS, (Expr*)RHS, Opc);
return new BinaryOperator(lhs, rhs, Opc);
}
/// ParseConditionalOp - Parse a ?: operation. Note that 'LHS' may be null
@ -443,8 +444,24 @@ Expr *Sema::ImplicitConversion(Expr *E) {
return E;
}
Action::ExprResult Sema::CheckMultiplicativeOperands(Expr *op1, Expr *op2) {
return false;
Action::ExprResult Sema::CheckMultiplicativeOperands(
Expr *lexpr, Expr *rexpr, SourceLocation loc, unsigned code)
{
lexpr = ImplicitConversion((Expr *)lexpr);
rexpr = ImplicitConversion((Expr *)rexpr);
QualType ltype = lexpr->getType();
QualType rtype = rexpr->getType();
assert(!ltype.isNull() && "no left type for CheckMultiplicativeOperands()");
assert(!rtype.isNull() && "no right type for CheckMultiplicativeOperands()");
if ((BinaryOperator::Opcode)code == BinaryOperator::Rem) {
if (!ltype->isIntegralType() || !rtype->isIntegralType())
return Diag(loc, diag::err_typecheck_invalid_operands);
} else {
if (!ltype->isArithmeticType() || !rtype->isArithmeticType())
return Diag(loc, diag::err_typecheck_invalid_operands);
}
return new BinaryOperator(lexpr, rexpr, (BinaryOperator::Opcode)code);
}
Action::ExprResult Sema::CheckAdditiveOperands(Expr *op1, Expr *op2) {

View File

@ -535,6 +535,8 @@ DIAG(err_typecheck_invalid_lvalue_addrof, ERROR,
"invalid lvalue in address expression")
DIAG(err_typecheck_unary_expr, ERROR,
"invalid argument type to unary expression '%s'")
DIAG(err_typecheck_invalid_operands, ERROR,
"invalid operands to binary expression")
// Statements.
DIAG(err_continue_not_in_loop, ERROR,