Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp (revision 51228) +++ lib/Sema/SemaExpr.cpp (working copy) @@ -1008,6 +1008,22 @@ return Expr; } +QualType Sema::UsualUnaryConversionType(QualType Ty) { + assert(!Ty.isNull() && "UsualUnaryConversions - missing type"); + + if (const ReferenceType *Ref = Ty->getAsReferenceType()) { + Ty = Ref->getPointeeType(); + } + if (Ty->isPromotableIntegerType()) // C99 6.3.1.1p2 + Ty = Context.IntTy; + else if (Ty->isFunctionType()) + Ty = Context.getPointerType(Ty); + else if (Ty->isArrayType()) + Ty = Context.getArrayDecayedType(Ty); + + return Ty; +} + /// UsualArithmeticConversions - Performs various conversions that are common to /// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this /// routine returns the first non-arithmetic type found. The client is @@ -1016,15 +1032,17 @@ /// GCC. QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr, bool isCompAssign) { + QualType lhs = UsualUnaryConversionType(lhsExpr->getType()); + QualType rhs = UsualUnaryConversionType(rhsExpr->getType()); if (!isCompAssign) { - UsualUnaryConversions(lhsExpr); - UsualUnaryConversions(rhsExpr); + ImpCastExprToType(lhsExpr, lhs); + ImpCastExprToType(rhsExpr, rhs); } // For conversion purposes, we ignore any qualifiers. // For example, "const float" and "float" are equivalent. - QualType lhs = lhsExpr->getType().getCanonicalType().getUnqualifiedType(); - QualType rhs = rhsExpr->getType().getCanonicalType().getUnqualifiedType(); - + lhs = lhs.getCanonicalType().getUnqualifiedType(); + rhs = rhs.getCanonicalType().getUnqualifiedType(); + // If both types are identical, no conversion is needed. if (lhs == rhs) return lhs; @@ -1513,12 +1531,17 @@ // Shifts don't perform usual arithmetic conversions, they just do integer // promotions on each operand. C99 6.5.7p3 - if (!isCompAssign) + QualType compTy; + if (!isCompAssign) { UsualUnaryConversions(lex); + compTy = lex->getType(); + } else { + compTy = UsualUnaryConversionType(lex->getType()); + } UsualUnaryConversions(rex); - + // "The type of the result is that of the promoted left operand." - return lex->getType(); + return compTy; } // C99 6.5.8 Index: lib/Sema/Sema.h =================================================================== --- lib/Sema/Sema.h (revision 51228) +++ lib/Sema/Sema.h (working copy) @@ -723,6 +723,10 @@ // UsualUnaryConversions - promotes integers (C99 6.3.1.1p2) and converts // functions and arrays to their respective pointers (C99 6.3.2.1). Expr *UsualUnaryConversions(Expr *&expr); + + // UsualUnaryConversionType - Same as UsualUnaryConversions, but works + // on types instead of expressions + QualType UsualUnaryConversionType(QualType Ty); // DefaultFunctionArrayConversion - converts functions and arrays // to their respective pointers (C99 6.3.2.1).