Kill off the remaining places which generate CK_Unknown casts.
authorJohn McCall <rjmccall@apple.com>
Tue, 16 Nov 2010 02:32:08 +0000 (02:32 +0000)
committerJohn McCall <rjmccall@apple.com>
Tue, 16 Nov 2010 02:32:08 +0000 (02:32 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@119326 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaDeclAttr.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaObjCProperty.cpp

index 6409b992f0bfe1799a8033b3819d8011e2755636..38b4f8b2ab9a6e2d49dabe4f484d520857b0af19 100644 (file)
@@ -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
index a1c07434ecce95cbea80e6e88be42c45ab65e399..3c3e3ae377265b3e7964e7e9610f7233b19a0249 100644 (file)
@@ -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;
index ed4a877a9e6646662b8eb8a13b011942055cb179..0d065145a1f69dbf9373f53f0b39b00d2ac717a3 100644 (file)
@@ -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<ExtVectorType>(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,
index 4c439f90e89008f403b7d668c5640ad352a39a17..fe2de27c6c85a76bf39f65740402acedf3ffb5ae 100644 (file)
@@ -424,11 +424,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
           Context.canAssignObjCInterfaces(
                                   PropType->getAs<ObjCObjectPointerType>(),
                                   IvarType->getAs<ObjCObjectPointerType>());
-      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()