const BinaryOperator *Exp = cast<BinaryOperator>(this);
llvm::APSInt LHS, RHS;
+ // Comma operator requires special handling.
+ if (Exp->getOpcode() == BinaryOperator::Comma) {
+ // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
+ // *except* when they are contained within a subexpression that is not
+ // evaluated". Note that Assignment can never happen due to constraints
+ // on the LHS subexpr, so we don't need to check it here.
+ if (isEvaluated) {
+ if (Loc) *Loc = getLocStart();
+ return false;
+ }
+
+ // The result of the constant expr is the RHS.
+ return Exp->getRHS()->isIntegerConstantExpr(Result, Ctx, Loc,
+ isEvaluated);
+ }
+
// Initialize result to have correct signedness and width.
Result = llvm::APSInt(static_cast<uint32_t>(Ctx.getTypeSize(getType())),
- !getType()->isSignedIntegerType());
-
+ !getType()->isSignedIntegerType());
+
// The LHS of a constant expr is always evaluated and needed.
if (!Exp->getLHS()->isIntegerConstantExpr(LHS, Ctx, Loc, isEvaluated))
return false;
case BinaryOperator::LOr:
Result = LHS != 0 || RHS != 0;
break;
-
- case BinaryOperator::Comma:
- // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
- // *except* when they are contained within a subexpression that is not
- // evaluated". Note that Assignment can never happen due to constraints
- // on the LHS subexpr, so we don't need to check it here.
- if (isEvaluated) {
- if (Loc) *Loc = getLocStart();
- return false;
- }
-
- // The result of the constant expr is the RHS.
- Result = RHS;
- return true;
}
assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
}
bool VisitDeclRefExpr(const DeclRefExpr *E);
bool VisitCallExpr(const CallExpr *E);
+ bool VisitBinOpComma(const BinaryOperator *E);
bool VisitBinaryOperator(const BinaryOperator *E);
bool VisitUnaryOperator(const UnaryOperator *E);
}
}
+bool IntExprEvaluator::VisitBinOpComma(const BinaryOperator *E) {
+ llvm::APSInt RHS(32);
+
+ // Require that we be able to evaluate the LHS.
+ if (!E->getLHS()->isEvaluatable(Info.Ctx))
+ return false;
+
+ bool OldEval = Info.isEvaluated;
+ if (!EvaluateInteger(E->getRHS(), RHS, Info))
+ return false;
+ Info.isEvaluated = OldEval;
+
+ // Result of the comma is just the result of the RHS.
+ Result = RHS;
+
+ // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
+ // *except* when they are contained within a subexpression that is not
+ // evaluated". Note that Assignment can never happen due to constraints
+ // on the LHS subexpr, so we don't need to check it here.
+ if (!Info.isEvaluated)
+ return true;
+
+ // If the value is evaluated, we can accept it as an extension.
+ return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr);
+}
+
bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
+ // Comma operator requires special handling.
+ if (E->getOpcode() == BinaryOperator::Comma)
+ return VisitBinOpComma(E);
+
// The LHS of a constant expr is always evaluated and needed.
llvm::APSInt RHS(32);
if (!Visit(E->getLHS())) {
Result = Result != 0 || RHS != 0;
Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
break;
-
-
- case BinaryOperator::Comma:
- // Result of the comma is just the result of the RHS.
- Result = RHS;
-
- // C99 6.6p3: "shall not contain assignment, ..., or comma operators,
- // *except* when they are contained within a subexpression that is not
- // evaluated". Note that Assignment can never happen due to constraints
- // on the LHS subexpr, so we don't need to check it here.
- if (!Info.isEvaluated)
- return true;
-
- // If the value is evaluated, we can accept it as an extension.
- return Extension(E->getOperatorLoc(), diag::ext_comma_in_constant_expr);
- }
+}
Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
return true;