From 29600e160ee58adebe3786422a6b7e71b20311a4 Mon Sep 17 00:00:00 2001 From: John McCall Date: Tue, 16 Nov 2010 02:32:08 +0000 Subject: [PATCH] Kill off the remaining places which generate CK_Unknown casts. llvm-svn: 119326 --- clang/include/clang/Sema/Sema.h | 8 ++++-- clang/lib/Sema/SemaDeclAttr.cpp | 3 +-- clang/lib/Sema/SemaExpr.cpp | 39 +++++++++++++++++++++++------ clang/lib/Sema/SemaObjCProperty.cpp | 12 +++------ 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 6409b992f0bf..38b4f8b2ab9a 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -4108,8 +4108,12 @@ public: /// CheckAssignmentConstraints - Perform type checking for assignment, /// argument passing, variable initialization, and function return values. - /// This routine is only used by the following two methods. C99 6.5.16. - AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs, + /// C99 6.5.16. + AssignConvertType CheckAssignmentConstraints(QualType lhs, QualType rhs); + + /// Check assignment constraints and prepare for a conversion of the + /// RHS to the LHS type. + AssignConvertType CheckAssignmentConstraints(QualType lhs, Expr *&rhs, CastKind &Kind); // CheckSingleAssignmentConstraints - Currently used by diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index a1c07434ecce..3c3e3ae37726 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1375,8 +1375,7 @@ static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { // If this ever proves to be a problem it should be easy to fix. QualType Ty = S.Context.getPointerType(VD->getType()); QualType ParamTy = FD->getParamDecl(0)->getType(); - CastKind K; - if (S.CheckAssignmentConstraints(ParamTy, Ty, K) != Sema::Compatible) { + if (S.CheckAssignmentConstraints(ParamTy, Ty) != Sema::Compatible) { S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_func_arg_incompatible_type) << Attr.getParameterName() << ParamTy << Ty; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ed4a877a9e66..0d065145a1f6 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -5224,6 +5224,19 @@ Sema::CheckObjCPointerTypesForAssignment(QualType lhsType, QualType rhsType) { return IncompatiblePointer; } +Sema::AssignConvertType +Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { + // Fake up an opaque expression. We don't actually care about what + // cast operations are required, so if CheckAssignmentConstraints + // adds casts to this they'll be wasted, but fortunately that doesn't + // usually happen on valid code. + OpaqueValueExpr rhs(rhsType, VK_RValue); + Expr *rhsPtr = &rhs; + CastKind K = CK_Invalid; + + return CheckAssignmentConstraints(lhsType, rhsPtr, K); +} + /// CheckAssignmentConstraints (C99 6.5.16) - This routine currently /// has code to accommodate several GCC extensions when type checking /// pointers. Here are some objectionable examples that GCC considers warnings: @@ -5242,8 +5255,10 @@ Sema::CheckObjCPointerTypesForAssignment(QualType lhsType, QualType rhsType) { /// /// Sets 'Kind' for any result kind except Incompatible. Sema::AssignConvertType -Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType, +Sema::CheckAssignmentConstraints(QualType lhsType, Expr *&rhs, CastKind &Kind) { + QualType rhsType = rhs->getType(); + // Get canonical types. We're not formatting these types, just comparing // them. lhsType = Context.getCanonicalType(lhsType).getUnqualifiedType(); @@ -5282,7 +5297,14 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType, if (rhsType->isExtVectorType()) return Incompatible; if (rhsType->isArithmeticType()) { - Kind = CK_Unknown; // FIXME: vector splat, potentially requires two casts + // CK_VectorSplat does T -> vector T, so first cast to the + // element type. + QualType elType = cast(lhsType)->getElementType(); + if (elType != rhsType) { + Kind = PrepareScalarCast(*this, rhs, elType); + ImpCastExprToType(rhs, elType, Kind); + } + Kind = CK_VectorSplat; return Compatible; } } @@ -5310,7 +5332,7 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType, if (lhsType->isArithmeticType() && rhsType->isArithmeticType() && !(getLangOptions().CPlusPlus && lhsType->isEnumeralType())) { - Kind = CK_Unknown; // FIXME: reuse the cast logic if possible + Kind = PrepareScalarCast(*this, rhs, lhsType); return Compatible; } @@ -5506,10 +5528,12 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType, Expr *&rExpr) { } } + Expr *rhs = rExpr; CastKind Kind = CK_Invalid; - if (CheckAssignmentConstraints(it->getType(), rExpr->getType(), Kind) + if (CheckAssignmentConstraints(it->getType(), rhs, Kind) == Compatible) { - ImpCastExprToType(rExpr, it->getType(), Kind); + ImpCastExprToType(rhs, it->getType(), Kind); + rExpr = rhs; InitField = *it; break; } @@ -5561,7 +5585,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) { CastKind Kind = CK_Invalid; Sema::AssignConvertType result = - CheckAssignmentConstraints(lhsType, rExpr->getType(), Kind); + CheckAssignmentConstraints(lhsType, rExpr, Kind); // C99 6.5.16.1p2: The value of the right operand is converted to the // type of the assignment expression. @@ -6633,8 +6657,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHS, Expr *&RHS, } } else { // Compound assignment "x += y" - CastKind Kind = CK_Invalid; // forgotten? - ConvTy = CheckAssignmentConstraints(LHSType, RHSType, Kind); + ConvTy = CheckAssignmentConstraints(LHSType, RHSType); } if (DiagnoseAssignmentResult(ConvTy, Loc, LHSType, RHSType, diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp index 4c439f90e890..fe2de27c6c85 100644 --- a/clang/lib/Sema/SemaObjCProperty.cpp +++ b/clang/lib/Sema/SemaObjCProperty.cpp @@ -424,11 +424,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, Context.canAssignObjCInterfaces( PropType->getAs(), IvarType->getAs()); - else { - CastKind K = CK_Invalid; - compat = (CheckAssignmentConstraints(PropType, IvarType, K) + else + compat = (CheckAssignmentConstraints(PropType, IvarType) == Compatible); - } if (!compat) { Diag(PropertyLoc, diag::error_property_ivar_type) << property->getDeclName() << PropType @@ -647,11 +645,9 @@ bool Sema::DiagnosePropertyAccessorMismatch(ObjCPropertyDecl *property, if (GetterMethod && GetterMethod->getResultType() != property->getType()) { AssignConvertType result = Incompatible; - if (property->getType()->isObjCObjectPointerType()) { - CastKind Kind = CK_Invalid; + if (property->getType()->isObjCObjectPointerType()) result = CheckAssignmentConstraints(GetterMethod->getResultType(), - property->getType(), Kind); - } + property->getType()); if (result != Compatible) { Diag(Loc, diag::warn_accessor_property_type_mismatch) << property->getDeclName()