]> granicus.if.org Git - clang/commitdiff
Merge all the 'assignment' diagnostic code into one routine, decloning
authorChris Lattner <sabre@nondot.org>
Fri, 4 Jan 2008 18:04:52 +0000 (18:04 +0000)
committerChris Lattner <sabre@nondot.org>
Fri, 4 Jan 2008 18:04:52 +0000 (18:04 +0000)
it from several places.  This merges the diagnostics, making them more
uniform and fewer in number. This also simplifies and cleans up the code.

Some highlights:
1. This removes a bunch of very-similar diagnostics.
2. This renames AssignmentCheckResult -> AssignConvertType
3. This merges PointerFromInt + IntFromPointer which were always treated the same.
4. This updates a bunch of test cases that have minor changes to the produced diagnostics.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45589 91177308-0d34-0410-b5e6-96231b3b80d8

21 files changed:
Sema/Sema.h
Sema/SemaDecl.cpp
Sema/SemaExpr.cpp
Sema/SemaStmt.cpp
include/clang/Basic/DiagnosticKinds.def
test/Parser/builtin_types_compatible.c
test/Parser/implicit-casts.c
test/Parser/typeof.c
test/Sema/argument-checking.m
test/Sema/array-constraint.c
test/Sema/array-init.c
test/Sema/builtins.c
test/Sema/incompatible-protocol-qualified-types.m
test/Sema/objc-comptypes-1.m
test/Sema/objc-comptypes-3.m
test/Sema/objc-comptypes-5.m
test/Sema/objc-comptypes-6.m
test/Sema/objc-comptypes-7.m
test/Sema/protocol-id-test-3.m
test/Sema/typedef-retain.c
test/Sema/vector-assign.c

index 6f546514dbb076200e4bd3469a5637b5d72d33b4..e790a74251cc61a93ab84e35c43874cbaac386da 100644 (file)
@@ -613,34 +613,42 @@ private:
   // responsible for emitting appropriate error diagnostics.
   QualType UsualArithmeticConversions(Expr *&lExpr, Expr *&rExpr,
                                       bool isCompAssign = false);
-  enum AssignmentCheckResult {
+  enum AssignConvertType {
     Compatible,
     Incompatible,
-    PointerFromInt, 
-    IntFromPointer,
+    PointerInt, 
     FunctionVoidPointer,
     IncompatiblePointer,
     CompatiblePointerDiscardsQualifiers
   };
-  // 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.
-  AssignmentCheckResult CheckAssignmentConstraints(QualType lhs, QualType rhs);
+  
+  /// DiagnoseAssignmentResult - Emit a diagnostic, if required, for the
+  /// assignment conversion type specified by ConvTy.  This returns true if the
+  /// conversion was invalid or false if the conversion was accepted.
+  bool DiagnoseAssignmentResult(AssignConvertType ConvTy,
+                                SourceLocation Loc,
+                                QualType DstType, QualType SrcType,
+                                Expr *SrcExpr, const char *Flavor);
+  
+  /// 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);
   
   // CheckSingleAssignmentConstraints - Currently used by ActOnCallExpr,
   // CheckAssignmentOperands, and ActOnReturnStmt. Prior to type checking, 
   // this routine performs the default function/array converions.
-  AssignmentCheckResult CheckSingleAssignmentConstraints(QualType lhs, 
-                                                         Expr *&rExpr);
+  AssignConvertType CheckSingleAssignmentConstraints(QualType lhs, 
+                                                     Expr *&rExpr);
   // CheckCompoundAssignmentConstraints - Type check without performing any 
   // conversions. For compound assignments, the "Check...Operands" methods 
   // perform the necessary conversions. 
-  AssignmentCheckResult CheckCompoundAssignmentConstraints(QualType lhs, 
-                                                           QualType rhs);
+  AssignConvertType CheckCompoundAssignmentConstraints(QualType lhs, 
+                                                       QualType rhs);
   
   // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
-  AssignmentCheckResult CheckPointerTypesForAssignment(QualType lhsType, 
-                                                       QualType rhsType);
+  AssignConvertType CheckPointerTypesForAssignment(QualType lhsType, 
+                                                   QualType rhsType);
   
   /// the following "Check" methods will return a valid/converted QualType
   /// or a null QualType (indicating an error diagnostic was issued).
index 1165e526d8de942a78befeb3e1e91e557988b95c..07b3d713681681e307969c6bf5d9f6d92b130fb0 100644 (file)
@@ -364,53 +364,13 @@ bool Sema::CheckSingleInitializer(Expr *&Init, bool isStatic,
     return true;
   }
   
-  AssignmentCheckResult result;
   // Get the type before calling CheckSingleAssignmentConstraints(), since
   // it can promote the expression.
-  QualType rhsType = Init->getType(); 
+  QualType InitType = Init->getType(); 
   
-  result = CheckSingleAssignmentConstraints(DeclType, Init);
-  
-  // decode the result (notice that extensions still return a type).
-  switch (result) {
-  case Compatible:
-    break;
-  case Incompatible:
-    // FIXME: tighten up this check which should allow:
-    // char s[] = "abc", which is identical to char s[] = { 'a', 'b', 'c' };
-    if (rhsType == Context.getPointerType(Context.CharTy))
-      break;
-    Diag(Init->getLocStart(), diag::err_typecheck_assign_incompatible, 
-         DeclType.getAsString(), rhsType.getAsString(), 
-         Init->getSourceRange());
-    return true;
-  case PointerFromInt:
-    Diag(Init->getLocStart(), diag::ext_typecheck_assign_pointer_int,
-         DeclType.getAsString(), rhsType.getAsString(), 
-         Init->getSourceRange());
-    break;
-  case IntFromPointer: 
-    Diag(Init->getLocStart(), diag::ext_typecheck_assign_pointer_int, 
-         DeclType.getAsString(), rhsType.getAsString(), 
-         Init->getSourceRange());
-    break;
-  case FunctionVoidPointer:
-    Diag(Init->getLocStart(), diag::ext_typecheck_assign_pointer_void_func, 
-         DeclType.getAsString(), rhsType.getAsString(), 
-         Init->getSourceRange());
-    break;
-  case IncompatiblePointer:
-    Diag(Init->getLocStart(), diag::ext_typecheck_assign_incompatible_pointer,
-         DeclType.getAsString(), rhsType.getAsString(), 
-         Init->getSourceRange());
-    break;
-  case CompatiblePointerDiscardsQualifiers:
-    Diag(Init->getLocStart(), diag::ext_typecheck_assign_discards_qualifiers,
-         DeclType.getAsString(), rhsType.getAsString(), 
-         Init->getSourceRange());
-    break;
-  }
-  return false;
+  AssignConvertType ConvTy = CheckSingleAssignmentConstraints(DeclType, Init);
+  return DiagnoseAssignmentResult(ConvTy, Init->getLocStart(), DeclType,
+                                  InitType, Init, "initializing");
 }
 
 bool Sema::CheckInitExpr(Expr *expr, InitListExpr *IList, unsigned slot,
index 3a3cfc18bc08a618b1d2c9ce6bb6f7bd2764ca5f..7ed0bf102a6da37f4e60a57ddd8bdfed88fbaacf 100644 (file)
@@ -615,55 +615,17 @@ ActOnCallExpr(ExprTy *fn, SourceLocation LParenLoc,
     // Continue to check argument types (even if we have too few/many args).
     for (unsigned i = 0; i != NumArgsToCheck; i++) {
       Expr *Arg = Args[i];
-      QualType LHSType = Proto->getArgType(i);
-      QualType RHSType = Arg->getType();
-
-      // If necessary, apply function/array conversion. C99 6.7.5.3p[7,8]. 
-      if (const ArrayType *AT = LHSType->getAsArrayType())
-        LHSType = Context.getPointerType(AT->getElementType());
-      else if (LHSType->isFunctionType())
-        LHSType = Context.getPointerType(LHSType);
+      QualType ProtoArgType = Proto->getArgType(i);
+      QualType ArgType = Arg->getType();
 
       // Compute implicit casts from the operand to the formal argument type.
-      AssignmentCheckResult Result =
-        CheckSingleAssignmentConstraints(LHSType, Arg);
+      AssignConvertType ConvTy =
+        CheckSingleAssignmentConstraints(ProtoArgType, Arg);
       TheCall->setArg(i, Arg);
       
-      // Decode the result (notice that AST's are still created for extensions).
-      SourceLocation Loc = Arg->getLocStart();
-      switch (Result) {
-      case Compatible:
-        break;
-      case PointerFromInt:
-        Diag(Loc, diag::ext_typecheck_passing_pointer_int, 
-             LHSType.getAsString(), RHSType.getAsString(),
-             Fn->getSourceRange(), Arg->getSourceRange());
-        break;
-      case IntFromPointer:
-        Diag(Loc, diag::ext_typecheck_passing_pointer_int, 
-             LHSType.getAsString(), RHSType.getAsString(),
-             Fn->getSourceRange(), Arg->getSourceRange());
-        break;
-      case FunctionVoidPointer:
-        Diag(Loc, diag::ext_typecheck_passing_pointer_void_func, 
-             LHSType.getAsString(), RHSType.getAsString(),
-             Fn->getSourceRange(), Arg->getSourceRange());
-        break;
-      case IncompatiblePointer:
-        Diag(Loc, diag::ext_typecheck_passing_incompatible_pointer, 
-             RHSType.getAsString(), LHSType.getAsString(),
-             Fn->getSourceRange(), Arg->getSourceRange());
-        break;
-      case CompatiblePointerDiscardsQualifiers:
-        Diag(Loc, diag::ext_typecheck_passing_discards_qualifiers,
-             RHSType.getAsString(), LHSType.getAsString(),
-             Fn->getSourceRange(), Arg->getSourceRange());
-        break;
-      case Incompatible:
-        return Diag(Loc, diag::err_typecheck_passing_incompatible,
-                    RHSType.getAsString(), LHSType.getAsString(),
-                    Fn->getSourceRange(), Arg->getSourceRange());
-      }
+      if (DiagnoseAssignmentResult(ConvTy, Arg->getLocStart(), ProtoArgType,
+                                   ArgType, Arg, "passing"))
+        return true;
     }
     
     // If this is a variadic call, handle args passed through "...".
@@ -1056,7 +1018,7 @@ QualType Sema::UsualArithmeticConversions(Expr *&lhsExpr, Expr *&rhsExpr,
 // routine is it effectively iqnores the qualifiers on the top level pointee.
 // This circumvents the usual type rules specified in 6.2.7p1 & 6.7.5.[1-3].
 // FIXME: add a couple examples in this comment.
-Sema::AssignmentCheckResult 
+Sema::AssignConvertType 
 Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
   QualType lhptee, rhptee;
   
@@ -1068,21 +1030,21 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
   lhptee = lhptee.getCanonicalType();
   rhptee = rhptee.getCanonicalType();
 
-  AssignmentCheckResult r = Compatible;
+  AssignConvertType ConvTy = Compatible;
   
   // C99 6.5.16.1p1: This following citation is common to constraints 
   // 3 & 4 (below). ...and the type *pointed to* by the left has all the 
   // qualifiers of the type *pointed to* by the right; 
   if ((lhptee.getQualifiers() & rhptee.getQualifiers()) != 
        rhptee.getQualifiers())
-    r = CompatiblePointerDiscardsQualifiers;
+    ConvTy = CompatiblePointerDiscardsQualifiers;
 
   // C99 6.5.16.1p1 (constraint 4): If one operand is a pointer to an object or 
   // incomplete type and the other is a pointer to a qualified or unqualified 
   // version of void...
   if (lhptee->isVoidType()) {
     if (rhptee->isObjectType() || rhptee->isIncompleteType())
-      return r;
+      return ConvTy;
     
     // As an extension, we allow cast to/from void* to function pointer.
     if (rhptee->isFunctionType())
@@ -1091,7 +1053,7 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
   
   if (rhptee->isVoidType()) {
     if (lhptee->isObjectType() || lhptee->isIncompleteType())
-      return r;
+      return ConvTy;
 
     // As an extension, we allow cast to/from void* to function pointer.
     if (lhptee->isFunctionType())
@@ -1103,7 +1065,7 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
   if (!Context.typesAreCompatible(lhptee.getUnqualifiedType(), 
                                   rhptee.getUnqualifiedType()))
     return IncompatiblePointer; // this "trumps" PointerAssignDiscardsQualifiers
-  return r;
+  return ConvTy;
 }
 
 /// CheckAssignmentConstraints (C99 6.5.16) - This routine currently 
@@ -1123,7 +1085,7 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
 /// C99 spec dictates. 
 /// Note: the warning above turn into errors when -pedantic-errors is enabled. 
 ///
-Sema::AssignmentCheckResult
+Sema::AssignConvertType
 Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
 
   
@@ -1169,14 +1131,14 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
     return Compatible;
   } else if (lhsType->isPointerType()) {
     if (rhsType->isIntegerType())
-      return PointerFromInt;
+      return PointerInt;
       
     if (rhsType->isPointerType())
       return CheckPointerTypesForAssignment(lhsType, rhsType);
   } else if (rhsType->isPointerType()) {
     // C99 6.5.16.1p1: the left operand is _Bool and the right is a pointer.
     if ((lhsType->isIntegerType()) && (lhsType != Context.BoolTy))
-      return IntFromPointer;
+      return PointerInt;
 
     if (lhsType->isPointerType()) 
       return CheckPointerTypesForAssignment(lhsType, rhsType);
@@ -1187,7 +1149,7 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
   return Incompatible;
 }
 
-Sema::AssignmentCheckResult
+Sema::AssignConvertType
 Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
   // C99 6.5.16.1p1: the left operand is a pointer and the right is
   // a null pointer constant.
@@ -1206,9 +1168,8 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
   if (!lhsType->isReferenceType())
     DefaultFunctionArrayConversion(rExpr);
 
-  Sema::AssignmentCheckResult result;
-  
-  result = CheckAssignmentConstraints(lhsType, rExpr->getType());
+  Sema::AssignConvertType result =
+    CheckAssignmentConstraints(lhsType, rExpr->getType());
   
   // C99 6.5.16.1p2: The value of the right operand is converted to the
   // type of the assignment expression.
@@ -1217,7 +1178,7 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
   return result;
 }
 
-Sema::AssignmentCheckResult
+Sema::AssignConvertType
 Sema::CheckCompoundAssignmentConstraints(QualType lhsType, QualType rhsType) {
   return CheckAssignmentConstraints(lhsType, rhsType);
 }
@@ -1501,81 +1462,47 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1
 {
   QualType lhsType = lex->getType();
   QualType rhsType = compoundType.isNull() ? rex->getType() : compoundType;
-  bool hadError = false;
   Expr::isModifiableLvalueResult mlval = lex->isModifiableLvalue(); 
 
   switch (mlval) { // C99 6.5.16p2
-    case Expr::MLV_Valid: 
-      break;
-    case Expr::MLV_ConstQualified:
-      Diag(loc, diag::err_typecheck_assign_const, lex->getSourceRange());
-      hadError = true;
-      break;
-    case Expr::MLV_ArrayType: 
-      Diag(loc, diag::err_typecheck_array_not_modifiable_lvalue,
-           lhsType.getAsString(), lex->getSourceRange());
-      return QualType(); 
-    case Expr::MLV_NotObjectType: 
-      Diag(loc, diag::err_typecheck_non_object_not_modifiable_lvalue,
-           lhsType.getAsString(), lex->getSourceRange());
-      return QualType();
-    case Expr::MLV_InvalidExpression:
-      Diag(loc, diag::err_typecheck_expression_not_modifiable_lvalue,
-           lex->getSourceRange());
-      return QualType();
-    case Expr::MLV_IncompleteType:
-    case Expr::MLV_IncompleteVoidType:
-      Diag(loc, diag::err_typecheck_incomplete_type_not_modifiable_lvalue,
-           lhsType.getAsString(), lex->getSourceRange());
-      return QualType();
-    case Expr::MLV_DuplicateVectorComponents:
-      Diag(loc, diag::err_typecheck_duplicate_vector_components_not_mlvalue,
-           lex->getSourceRange());
-      return QualType();
+  case Expr::MLV_Valid: 
+    break;
+  case Expr::MLV_ConstQualified:
+    Diag(loc, diag::err_typecheck_assign_const, lex->getSourceRange());
+    return QualType();
+  case Expr::MLV_ArrayType: 
+    Diag(loc, diag::err_typecheck_array_not_modifiable_lvalue,
+         lhsType.getAsString(), lex->getSourceRange());
+    return QualType(); 
+  case Expr::MLV_NotObjectType: 
+    Diag(loc, diag::err_typecheck_non_object_not_modifiable_lvalue,
+         lhsType.getAsString(), lex->getSourceRange());
+    return QualType();
+  case Expr::MLV_InvalidExpression:
+    Diag(loc, diag::err_typecheck_expression_not_modifiable_lvalue,
+         lex->getSourceRange());
+    return QualType();
+  case Expr::MLV_IncompleteType:
+  case Expr::MLV_IncompleteVoidType:
+    Diag(loc, diag::err_typecheck_incomplete_type_not_modifiable_lvalue,
+         lhsType.getAsString(), lex->getSourceRange());
+    return QualType();
+  case Expr::MLV_DuplicateVectorComponents:
+    Diag(loc, diag::err_typecheck_duplicate_vector_components_not_mlvalue,
+         lex->getSourceRange());
+    return QualType();
   }
-  AssignmentCheckResult result;
-  
+
+  AssignConvertType ConvTy;
   if (compoundType.isNull())
-    result = CheckSingleAssignmentConstraints(lhsType, rex);
+    ConvTy = CheckSingleAssignmentConstraints(lhsType, rex);
   else
-    result = CheckCompoundAssignmentConstraints(lhsType, rhsType);
+    ConvTy = CheckCompoundAssignmentConstraints(lhsType, rhsType);
 
-  // decode the result (notice that extensions still return a type).
-  switch (result) {
-  case Compatible:
-    break;
-  case Incompatible:
-    Diag(loc, diag::err_typecheck_assign_incompatible, 
-         lhsType.getAsString(), rhsType.getAsString(),
-         lex->getSourceRange(), rex->getSourceRange());
-    hadError = true;
-    break;
-  case PointerFromInt:
-    Diag(loc, diag::ext_typecheck_assign_pointer_int,
-         lhsType.getAsString(), rhsType.getAsString(),
-         lex->getSourceRange(), rex->getSourceRange());
-    break;
-  case IntFromPointer: 
-    Diag(loc, diag::ext_typecheck_assign_pointer_int, 
-         lhsType.getAsString(), rhsType.getAsString(),
-         lex->getSourceRange(), rex->getSourceRange());
-    break;
-  case FunctionVoidPointer:
-    Diag(loc, diag::ext_typecheck_assign_pointer_void_func, 
-         lhsType.getAsString(), rhsType.getAsString(),
-         lex->getSourceRange(), rex->getSourceRange());
-    break;
-  case IncompatiblePointer:
-    Diag(loc, diag::ext_typecheck_assign_incompatible_pointer,
-         lhsType.getAsString(), rhsType.getAsString(),
-         lex->getSourceRange(), rex->getSourceRange());
-    break;
-  case CompatiblePointerDiscardsQualifiers:
-    Diag(loc, diag::ext_typecheck_assign_discards_qualifiers,
-         lhsType.getAsString(), rhsType.getAsString(),
-         lex->getSourceRange(), rex->getSourceRange());
-    break;
-  }
+  if (DiagnoseAssignmentResult(ConvTy, loc, lhsType, rhsType,
+                               rex, "assigning"))
+    return QualType();
+  
   // C99 6.5.16p3: The type of an assignment expression is the type of the
   // left operand unless the left operand has qualified type, in which case
   // it is the unqualified version of the type of the left operand. 
@@ -1583,7 +1510,7 @@ inline QualType Sema::CheckAssignmentOperands( // C99 6.5.16.1
   // is converted to the type of the assignment expression (above).
   // C++ 5.17p1: the type of the assignment expression is that of its left
   // oprdu.
-  return hadError ? QualType() : lhsType.getUnqualifiedType();
+  return lhsType.getUnqualifiedType();
 }
 
 inline QualType Sema::CheckCommaOperands( // C99 6.5.17
@@ -2097,18 +2024,14 @@ Sema::ExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, ExprTy *cond,
 
 Sema::ExprResult Sema::ActOnVAArg(SourceLocation BuiltinLoc,
                                   ExprTy *expr, TypeTy *type,
-                                  SourceLocation RPLoc)
-{
+                                  SourceLocation RPLoc) {
   Expr *E = static_cast<Expr*>(expr);
   QualType T = QualType::getFromOpaquePtr(type);
 
   InitBuiltinVaListType();
   
-  Sema::AssignmentCheckResult result;
-
-  result = CheckAssignmentConstraints(Context.getBuiltinVaListType(), 
-                                      E->getType());
-  if (result != Compatible)
+  if (CheckAssignmentConstraints(Context.getBuiltinVaListType(), E->getType())
+      != Compatible)
     return Diag(E->getLocStart(),
                 diag::err_first_argument_to_va_arg_not_of_type_va_list,
                 E->getType().getAsString(),
@@ -2206,6 +2129,39 @@ Sema::ExprResult Sema::ParseObjCProtocolExpression(IdentifierInfo *ProtocolId,
   return new ObjCProtocolExpr(t, PDecl, AtLoc, RParenLoc);
 }
 
+bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
+                                    SourceLocation Loc,
+                                    QualType DstType, QualType SrcType,
+                                    Expr *SrcExpr, const char *Flavor) {
+  // Decode the result (notice that AST's are still created for extensions).
+  bool isInvalid = false;
+  unsigned DiagKind;
+  switch (ConvTy) {
+  default: assert(0 && "Unknown conversion type");
+  case Compatible: return false;
+  case PointerInt:
+    DiagKind = diag::ext_typecheck_convert_pointer_int;
+    break;
+  case IncompatiblePointer:
+    DiagKind = diag::ext_typecheck_convert_incompatible_pointer;
+    break;
+  case FunctionVoidPointer:
+    DiagKind = diag::ext_typecheck_convert_pointer_void_func;
+    break;
+  case CompatiblePointerDiscardsQualifiers:
+    DiagKind = diag::ext_typecheck_convert_discards_qualifiers;
+    break;
+  case Incompatible:
+    DiagKind = diag::err_typecheck_convert_incompatible;
+    isInvalid = true;
+    break;
+  }
+  
+  Diag(Loc, DiagKind, DstType.getAsString(), SrcType.getAsString(), Flavor,
+       SrcExpr->getSourceRange());
+  return isInvalid;
+}
+
 bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
                                      ObjcMethodDecl *Method) {
   bool anyIncompatibleArgs = false;
@@ -2223,44 +2179,14 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
     else if (lhsType->isFunctionType())
       lhsType = Context.getPointerType(lhsType);
 
-    AssignmentCheckResult result = CheckSingleAssignmentConstraints(lhsType,
-                                                                    argExpr);
+    AssignConvertType Result = CheckSingleAssignmentConstraints(lhsType,
+                                                                argExpr);
     if (Args[i] != argExpr) // The expression was converted.
       Args[i] = argExpr; // Make sure we store the converted expression.
-    SourceLocation l = argExpr->getLocStart();
-
-    // Decode the result (notice that AST's are still created for extensions).
-    const char *Kind = "sending";
-    switch (result) {
-    case Compatible:
-      break;
-    case PointerFromInt:
-    case IntFromPointer:
-      Diag(l, diag::ext_typecheck_convert_pointer_int, 
-           lhsType.getAsString(), rhsType.getAsString(), Kind,
-           argExpr->getSourceRange());
-      break;
-    case IncompatiblePointer:
-      Diag(l, diag::ext_typecheck_convert_incompatible_pointer, 
-           lhsType.getAsString(), rhsType.getAsString(), Kind,
-           argExpr->getSourceRange());
-      break;
-    case FunctionVoidPointer:
-      Diag(l, diag::ext_typecheck_convert_pointer_void_func, 
-           lhsType.getAsString(), rhsType.getAsString(), Kind,
-           argExpr->getSourceRange());
-      break;
-    case CompatiblePointerDiscardsQualifiers:
-      Diag(l, diag::ext_typecheck_convert_discards_qualifiers,
-           lhsType.getAsString(), rhsType.getAsString(), Kind,
-           argExpr->getSourceRange());
-      break;
-    case Incompatible:
-      Diag(l, diag::err_typecheck_convert_incompatible,
-           lhsType.getAsString(), rhsType.getAsString(), Kind,
-           argExpr->getSourceRange());
-      anyIncompatibleArgs = true;
-    }
+    
+    anyIncompatibleArgs |= 
+      DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
+                               argExpr, "sending");
   }
   return anyIncompatibleArgs;
 }
index 6b60bd02744218d50c36eedfeff2737f64604f2a..a983036b9933bfbdf368dd0a837159c68c1f3fe4 100644 (file)
@@ -616,10 +616,10 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
 Action::StmtResult
 Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) {
   Expr *RetValExp = static_cast<Expr *>(rex);
-  QualType lhsType = CurFunctionDecl ? CurFunctionDecl->getResultType() : 
-                                       CurMethodDecl->getResultType();
+  QualType FnRetType = CurFunctionDecl ? CurFunctionDecl->getResultType() : 
+                                         CurMethodDecl->getResultType();
 
-  if (lhsType->isVoidType()) {
+  if (FnRetType->isVoidType()) {
     if (RetValExp) // C99 6.8.6.4p1 (ext_ since GCC warns)
       Diag(ReturnLoc, diag::ext_return_has_expr,
            (CurFunctionDecl ? CurFunctionDecl->getIdentifier()->getName() :
@@ -639,51 +639,18 @@ Sema::ActOnReturnStmt(SourceLocation ReturnLoc, ExprTy *rex) {
     }
   }
   // we have a non-void function with an expression, continue checking
-  QualType rhsType = RetValExp->getType();
+  QualType RetValType = RetValExp->getType();
 
   // C99 6.8.6.4p3(136): The return statement is not an assignment. The 
   // overlap restriction of subclause 6.5.16.1 does not apply to the case of 
   // function return.  
-  AssignmentCheckResult result = CheckSingleAssignmentConstraints(lhsType, 
-                                                                  RetValExp);
-
-  // decode the result (notice that extensions still return a type).
-  switch (result) {
-  case Compatible:
-    break;
-  case Incompatible:
-    Diag(ReturnLoc, diag::err_typecheck_return_incompatible, 
-         lhsType.getAsString(), rhsType.getAsString(),
-         RetValExp->getSourceRange());
-    break;
-  case PointerFromInt:
-    Diag(ReturnLoc, diag::ext_typecheck_return_pointer_int,
-         lhsType.getAsString(), rhsType.getAsString(),
-         RetValExp->getSourceRange());
-    break;
-  case IntFromPointer:
-    Diag(ReturnLoc, diag::ext_typecheck_return_pointer_int,
-         lhsType.getAsString(), rhsType.getAsString(),
-         RetValExp->getSourceRange());
-    break;
-  case FunctionVoidPointer:
-    Diag(ReturnLoc, diag::ext_typecheck_return_pointer_void_func, 
-         lhsType.getAsString(), rhsType.getAsString(),
-         RetValExp->getSourceRange());
-    break;
-  case IncompatiblePointer:
-    Diag(ReturnLoc, diag::ext_typecheck_return_incompatible_pointer,
-         lhsType.getAsString(), rhsType.getAsString(),
-         RetValExp->getSourceRange());
-    break;
-  case CompatiblePointerDiscardsQualifiers:
-    Diag(ReturnLoc, diag::ext_typecheck_return_discards_qualifiers,
-         lhsType.getAsString(), rhsType.getAsString(),
-         RetValExp->getSourceRange());
-    break;
-  }
+  AssignConvertType ConvTy = CheckSingleAssignmentConstraints(FnRetType, 
+                                                              RetValExp);
+  if (DiagnoseAssignmentResult(ConvTy, ReturnLoc, FnRetType,
+                               RetValType, RetValExp, "returning"))
+    return true;
   
-  if (RetValExp) CheckReturnStackAddr(RetValExp, lhsType, ReturnLoc);
+  if (RetValExp) CheckReturnStackAddr(RetValExp, FnRetType, ReturnLoc);
   
   return new ReturnStmt(ReturnLoc, (Expr*)RetValExp);
 }
index e07245659e7d2156d29f14f0dc7664c44a23e389..891d9317e0ff92baeb897385e8d9ec528a96f2d6 100644 (file)
@@ -764,6 +764,7 @@ DIAG(ext_typecheck_comparison_of_distinct_pointers, WARNING,
 DIAG(err_typecheck_assign_const, ERROR,
      "read-only variable is not assignable")
 
+// assignment related diagnostics (also for argument passing, returning, etc).
 DIAG(err_typecheck_convert_incompatible, ERROR,
      "incompatible type %2 '%1', expected '%0'")
 DIAG(ext_typecheck_convert_pointer_int, EXTENSION,
@@ -771,47 +772,9 @@ DIAG(ext_typecheck_convert_pointer_int, EXTENSION,
 DIAG(ext_typecheck_convert_pointer_void_func, EXTENSION,
      "%2 '%1' converts between void* and function pointer, expected '%0'")
 DIAG(ext_typecheck_convert_incompatible_pointer, EXTENSION,
-     "incompatible pointer types %d '%1', expected '%0'")
+     "incompatible pointer types %2 '%1', expected '%0'")
 DIAG(ext_typecheck_convert_discards_qualifiers, EXTENSION,
-     "%d '%1' discards qualifiers, expected '%0'")
-
-     
-     
-DIAG(err_typecheck_return_incompatible, ERROR,
-     "incompatible type returning '%1', expected '%0'")
-DIAG(ext_typecheck_return_pointer_int, EXTENSION,
-     "incompatible type returning '%1', expected '%0'")
-DIAG(ext_typecheck_return_pointer_void_func, EXTENSION,
-     "returning '%1' to from function expecting '%0' converts between void*"
-     " and function pointer")
-DIAG(ext_typecheck_return_incompatible_pointer, EXTENSION,
-     "incompatible pointer types returning '%1', expected '%0'")
-DIAG(ext_typecheck_return_discards_qualifiers, EXTENSION,
-     "returning '%1' from function expecting '%0' discards qualifiers")
-     
-DIAG(err_typecheck_assign_incompatible, ERROR,
-     "incompatible types assigning '%1' to '%0'")
-DIAG(ext_typecheck_assign_pointer_int, WARNING,
-     "incompatible types assigning '%1' to '%0'")
-DIAG(ext_typecheck_assign_incompatible_pointer, WARNING,
-     "incompatible pointer types assigning '%1' to '%0'")
-DIAG(ext_typecheck_assign_discards_qualifiers, WARNING,
-     "assigning '%1' to '%0' discards qualifiers")
-DIAG(ext_typecheck_assign_pointer_void_func, EXTENSION,
-     "assigning '%1' to '%0' converts between void* and function pointer")
-     
-DIAG(err_typecheck_passing_incompatible, ERROR,
-     "incompatible types passing '%0' to function expecting '%1'")
-DIAG(ext_typecheck_passing_incompatible_pointer, WARNING,
-     "incompatible pointer types passing '%0' to function expecting '%1'")
-DIAG(ext_typecheck_passing_pointer_int, WARNING,
-     "incompatible types passing '%1' to function expecting '%0'")
-DIAG(ext_typecheck_passing_pointer_void_func, EXTENSION,
-     "passing '%1' to function expecting '%0' converts between void*"
-     " and function pointer")
-DIAG(ext_typecheck_passing_discards_qualifiers, WARNING,
-     "passing '%0' to '%1' discards qualifiers")
-     
+     "%2 '%1' discards qualifiers, expected '%0'")
      
 DIAG(err_typecheck_array_not_modifiable_lvalue, ERROR,
      "array type '%0' is not assignable")
index b8207841a433030d1da71836a806312b15727a2e..925c7ea50a1675f32f6166056c7e15cad20acdf3 100644 (file)
@@ -35,7 +35,7 @@ static void test()
   struct xx { int a; } x, y;
   
   c = __builtin_choose_expr(a+3-7, b, x); // expected-error{{'__builtin_choose_expr' requires a constant expression}}
-  c = __builtin_choose_expr(0, b, x); // expected-error{{incompatible types assigning 'struct xx' to 'int'}}
+  c = __builtin_choose_expr(0, b, x); // expected-error{{incompatible type assigning 'struct xx', expected 'int'}}
   c = __builtin_choose_expr(5+3-7, b, x);
   y = __builtin_choose_expr(4+3-7, b, x);
 
index a07155eea40335a228f08c436b4f3d649492b6e8..3d055263bcb91dfb04f5921485dd3d141512aa65 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only -verify %s
+// RUN: clang -fsyntax-only -verify -pedantic %s
 _Complex double X;
 void test1(int c) {
   X = 5;
@@ -14,7 +14,7 @@ void test2() {
 }
 int test3() {
   int a[2];
-  a[0] = test3; // expected-warning{{incompatible types assigning 'int (void)' to 'int'}}
+  a[0] = test3; // expected-warning{{incompatible pointer/int conversion assigning 'int (void)', expected 'int'}}
 }
 short x; void test4(char c) { x += c; }
 int y; void test5(char c) { y += c; }
index 6c4e79cd161284918aa9e8ebecd9b7578c6acd50..3ea277559e0a3e5f56516a27d4806b8d766e84b4 100644 (file)
@@ -16,8 +16,4 @@ static void test() {
   const typeof (*pi) aConstInt; 
   int xx;
   int *i;
-  i = aci; // expected-warning{{incompatible types assigning 'typeof(int const)' to 'int *'}}
-  i = anInt; // expected-warning{{incompatible types assigning 'typeof(TInt)' to 'int *'}}
-  i = aConstInt; // expected-warning{{incompatible types assigning 'typeof(*pi) const' to 'int *'}}
-  i = xx; // expected-warning{{incompatible types assigning 'int' to 'int *'}}
 }
index 57ab14f1ff21b2002a8abe2bd9e624b43b574742..cd84171ee73e77d986f6263eecc5c774dbf6da82 100644 (file)
@@ -16,8 +16,8 @@ void test() {
   id obj = [Test alloc];
   struct S sInst;
 
-  charStarFunc(1); // expected-warning {{incompatible types passing 'int' to function expecting 'char *'}}
-  charFunc("abc"); // expected-warning {{incompatible types passing 'char *' to function expecting 'char'}}
+  charStarFunc(1); // expected-warning {{incompatible pointer/int conversion passing 'int', expected 'char *'}}
+  charFunc("abc"); // expected-warning {{incompatible pointer/int conversion passing 'char *', expected 'char'}}
 
   [obj charStarMeth:1]; // expected-warning {{incompatible pointer/int conversion sending 'int'}}
   [obj structMeth:1]; // expected-error {{incompatible type sending 'int'}}
index f281df1aff29339bc0b71ea2c0cfad9ed2aa0d16..df79681d06c5388a278e266856420655abafa07f 100644 (file)
@@ -45,7 +45,7 @@ typedef int TA[I]; // expected-error {{variable length array declared outside of
 void strFunc(char *);
 const char staticAry[] = "test";
 int checkStaticAry() { 
-  strFunc(staticAry); // expected-warning{{passing 'char const [5]' to 'char *' discards qualifiers}}
+  strFunc(staticAry); // expected-warning{{passing 'char const [5]' discards qualifiers, expected 'char *'}}
 }
 
 
index bf5ea06bab4a6b3545bf8b6f3c9c3638c2098477..1875fab3890186e2a53e950f1196bfa8ebc74de5 100644 (file)
@@ -9,7 +9,7 @@ int ary2[] = { x, y, z }; // expected-error{{initializer element is not constant
 
 extern int fileScopeExtern[3] = { 1, 3, 5 }; // expected-warning{{'extern' variable has an initializer}}
 
-static int ary3[] = { 1, "abc", 3, 4 }; // expected-warning{{incompatible types assigning 'char *' to 'int'}}
+static int ary3[] = { 1, "abc", 3, 4 }; // expected-warning{{incompatible pointer/int conversion initializing 'char *', expected 'int'}}
 
 void func() {
   int x = 1;
@@ -44,11 +44,11 @@ void func() {
     int a,b,c;
   } z = { 1 };
 
-  struct threeElements *p = 7; // expected-warning{{incompatible types assigning 'int' to 'struct threeElements *'}}
+  struct threeElements *p = 7; // expected-warning{{incompatible pointer/int conversion initializing 'int', expected 'struct threeElements *'}}
   
   extern int blockScopeExtern[3] = { 1, 3, 5 }; // expected-error{{'extern' variable cannot have an initializer}}
   
-  static int x2[3] = { 1.0, "abc" , 5.8 }; // expected-warning{{incompatible types assigning 'char *' to 'int'}}
+  static int x2[3] = { 1.0, "abc" , 5.8 }; // expected-warning{{incompatible pointer/int conversion initializing 'char *', expected 'int'}}
 }
 
 void test() {
index 997a8ede0ea911fb99fff1504ef1d48aca1337a6..59a339ad45b01bd9ad43122ff1ed01cda17de09a 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: clang %s -fsyntax-only -verify
+// RUN: clang %s -fsyntax-only -verify -pedantic
 
 int test1(float a, int b) {
   return __builtin_isless(a, b);
@@ -26,8 +26,7 @@ int test6(float a, long double b) {
 void cfstring() {
   CFSTR("\242"); // expected-warning {{ CFString literal contains non-ASCII character }}
   CFSTR("\0"); // expected-warning {{ CFString literal contains NUL character }}
-  CFSTR(242); // expected-error {{ CFString literal is not a string constant }} \
-    expected-warning {{incompatible types}}
+  CFSTR(242); // expected-error {{ CFString literal is not a string constant }} expected-warning {{incompatible pointer/int conversion}}
   CFSTR("foo", "bar"); // expected-error {{ error: too many arguments to function }}
 }
 
index 417dcee2d18315f0f2d357dc0f7b44e34ed4b172..ad8c45e5e0a874aa339d595613d159cc643a8436 100644 (file)
@@ -21,7 +21,7 @@ INTF <MyProto1> * Func1(INTF <MyProto1, MyProto2> *p2)
 
 INTF <MyProto1, MyProto2> * Func2(INTF <MyProto1> *p2)
 {
-       Func(p2);       // expected-warning {{incompatible pointer types passing 'INTF<MyProto1> *' to function expecting 'INTF<MyProto1,MyProto2> *}}
+       Func(p2);       // expected-warning {{incompatible pointer types passing 'INTF<MyProto1> *', expected 'INTF<MyProto1,MyProto2> *}}
        return p2;      // expected-warning {{incompatible pointer types returning 'INTF<MyProto1> *', expected 'INTF<MyProto1,MyProto2> *}}
 }
 
index c4b457ee6801a8b585510962e456d3e394addb07..512565c58b7981778bacdc31cab1326b87dfb3b2 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only -verify %s
+// RUN: clang -fsyntax-only -verify -pedantic %s
 
 #include <objc/objc.h>
 
@@ -33,25 +33,25 @@ int main()
   /* Assigning to a 'MyClass *' variable should always generate a
      warning, unless done from an 'id'.  */
   obj_c = obj;    /* Ok */
-  obj_c = obj_cp; // // expected-warning {{incompatible pointer types assigning 'MyOtherClass *' to 'MyClass *'}}
-  obj_c = obj_C;  // expected-warning {{incompatible pointer types assigning 'Class' to 'MyClass *'}}
+  obj_c = obj_cp; // // expected-warning {{incompatible pointer types assigning 'MyOtherClass *', expected 'MyClass *'}}
+  obj_c = obj_C;  // expected-warning {{incompatible pointer types assigning 'Class', expected 'MyClass *'}}
 
   /* Assigning to an 'id<MyProtocol>' variable should generate a
      warning if done from a 'MyClass *' (which doesn't implement
      MyProtocol), but not from an 'id' or from a 'MyOtherClass *'
      (which implements MyProtocol).  */
   obj_p = obj;    /* Ok */
-  obj_p = obj_c;  // expected-error {{incompatible types assigning 'MyClass *' to 'id<MyProtocol>'}}
+  obj_p = obj_c;  // expected-error {{incompatible type assigning 'MyClass *', expected 'id<MyProtocol>'}}
   obj_p = obj_cp; /* Ok  */
-  obj_p = obj_C;  // expected-error {{incompatible types assigning 'Class' to 'id<MyProtocol>'}}
+  obj_p = obj_C;  // expected-error {{incompatible type assigning 'Class', expected 'id<MyProtocol>'}}
 
   /* Assigning to a 'MyOtherClass *' variable should always generate
      a warning, unless done from an 'id' or an 'id<MyProtocol>' (since
      MyOtherClass implements MyProtocol).  */
   obj_cp = obj;    /* Ok */
-  obj_cp = obj_c;  // expected-warning {{incompatible pointer types assigning 'MyClass *' to 'MyOtherClass *'}}
+  obj_cp = obj_c;  // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'MyOtherClass *'}}
   obj_cp = obj_p;  /* Ok */
-  obj_cp = obj_C;  // expected-warning {{incompatible pointer types assigning 'Class' to 'MyOtherClass *'}}
+  obj_cp = obj_C;  // expected-warning {{incompatible pointer types assigning 'Class', expected 'MyOtherClass *'}}
 
   /* Any comparison involving an 'id' must be without warnings.  */
   if (obj == obj_p) foo() ;  /* Ok  */ /*Bogus warning here in 2.95.4*/
index c7c4cab711862a8f805501a057f024f69bf86932..4aab2d2ee747c4dca53c45e0bd2acbae68db0ca6 100644 (file)
@@ -24,21 +24,21 @@ int main()
   id<MyProtocolAB> obj_ab = nil;
   id<MyProtocolAC> obj_ac = nil;
 
-  obj_a = obj_b;  // expected-error {{incompatible types assigning 'id<MyProtocolB>' to 'id<MyProtocolA>'}}
+  obj_a = obj_b;  // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolA>'}}
   obj_a = obj_ab; /* Ok */
   obj_a = obj_ac; /* Ok */
   
-  obj_b = obj_a;  // expected-error {{incompatible types assigning 'id<MyProtocolA>' to 'id<MyProtocolB>'}}
+  obj_b = obj_a;  // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolB>'}}
   obj_b = obj_ab; /* Ok */
-  obj_b = obj_ac; // expected-error {{incompatible types assigning 'id<MyProtocolAC>' to 'id<MyProtocolB>'}}
+  obj_b = obj_ac; // expected-error {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolB>'}}
   
-  obj_ab = obj_a;  // expected-error {{incompatible types assigning 'id<MyProtocolA>' to 'id<MyProtocolAB>'}}
-  obj_ab = obj_b;  // expected-error {{incompatible types assigning 'id<MyProtocolB>' to 'id<MyProtocolAB>'}}
-  obj_ab = obj_ac; // expected-error {{incompatible types assigning 'id<MyProtocolAC>' to 'id<MyProtocolAB>'}}
+  obj_ab = obj_a;  // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAB>'}}
+  obj_ab = obj_b;  // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAB>'}}
+  obj_ab = obj_ac; // expected-error {{incompatible type assigning 'id<MyProtocolAC>', expected 'id<MyProtocolAB>'}}
   
-  obj_ac = obj_a;  // expected-error {{incompatible types assigning 'id<MyProtocolA>' to 'id<MyProtocolAC>'}}
-  obj_ac = obj_b;  // expected-error {{incompatible types assigning 'id<MyProtocolB>' to 'id<MyProtocolAC>'}}
-  obj_ac = obj_ab; // expected-error {{incompatible types assigning 'id<MyProtocolAB>' to 'id<MyProtocolAC>'}}
+  obj_ac = obj_a;  // expected-error {{incompatible type assigning 'id<MyProtocolA>', expected 'id<MyProtocolAC>'}}
+  obj_ac = obj_b;  // expected-error {{incompatible type assigning 'id<MyProtocolB>', expected 'id<MyProtocolAC>'}}
+  obj_ac = obj_ab; // expected-error {{incompatible type assigning 'id<MyProtocolAB>', expected 'id<MyProtocolAC>'}}
 
   if (obj_a == obj_b) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolA>' and 'id<MyProtocolB>')}}
   if (obj_b == obj_a) foo (); // expected-error {{invalid operands to binary expression ('id<MyProtocolB>' and 'id<MyProtocolA>')}}
index 646c6e58bc881ebb841866ec9c886e13e0a00c68..508c25f01dd1c9a9c1db47aa4c4389db0562962f 100644 (file)
@@ -23,8 +23,8 @@ int main()
   MyClass *obj_c_cat_p = nil;
   MyOtherClass *obj_c_super_p = nil;
 
-  obj_c_cat_p = obj_id_p;   // expected-error {{incompatible types assigning 'id<MyProtocol>' to 'MyClass *'}}
-  obj_c_super_p = obj_id_p;  // expected-error {{incompatible types assigning 'id<MyProtocol>' to 'MyOtherClass *'}}
+  obj_c_cat_p = obj_id_p;   // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'MyClass *'}}
+  obj_c_super_p = obj_id_p;  // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'MyOtherClass *'}}
   obj_id_p = obj_c_cat_p;  /* Ok */
   obj_id_p = obj_c_super_p; /* Ok */
 
index ca2b131fc9674d69b656e364e090ba17a49f98f8..dd9b3967877d00f4a220c63bfd030011ff5299a7 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only -verify %s
+// RUN: clang -fsyntax-only -verify -pedantic %s
 
 #include <objc/Object.h>
 
@@ -9,7 +9,7 @@ extern Object* foo(void);
 
 static Derived *test(void)
 {
-   Derived *m = foo();   // expected-warning {{incompatible pointer types assigning 'Object *' to 'Derived *'}}
+   Derived *m = foo();   // expected-warning {{incompatible pointer types initializing 'Object *', expected 'Derived *'}}
 
    return m;
 }
index e4c949ac7114acf0864e774c31068a6d8d440a02..9d8f211da65721fd4fca10a8590f8025523394e8 100644 (file)
@@ -1,4 +1,4 @@
-// RUN: clang -fsyntax-only -verify %s
+// RUN: clang -fsyntax-only -verify -pedantic %s
 
 #include <objc/objc.h>
 
@@ -23,27 +23,27 @@ int main()
 
   /* These should all generate warnings.  */
   
-  obj = i; // expected-warning {{incompatible types assigning 'int' to 'id'}}
-  obj = j; // expected-warning {{incompatible pointer types assigning 'int *' to 'id'}}
+  obj = i; // expected-warning {{incompatible pointer/int conversion assigning 'int', expected 'id'}}
+  obj = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'id'}}
 
-  obj_p = i; // expected-error {{incompatible types assigning 'int' to 'id<MyProtocol>' }}
-  obj_p = j; // expected-error {{incompatible types assigning 'int *' to 'id<MyProtocol>'}}
+  obj_p = i; // expected-error {{incompatible type assigning 'int', expected 'id<MyProtocol>' }}
+  obj_p = j; // expected-error {{incompatible type assigning 'int *', expected 'id<MyProtocol>'}}
   
-  obj_c = i; // expected-warning {{incompatible types assigning 'int' to 'MyClass *'}}
-  obj_c = j; // expected-warning {{incompatible pointer types assigning 'int *' to 'MyClass *'}}
+  obj_c = i; // expected-warning {{incompatible pointer/int conversion assigning 'int', expected 'MyClass *'}}
+  obj_c = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'MyClass *'}}
 
-  obj_C = i; // expected-warning {{incompatible types assigning 'int' to 'Class'}}
-  obj_C = j; // expected-warning {{incompatible pointer types assigning 'int *' to 'Class'}}
+  obj_C = i; // expected-warning {{incompatible pointer/int conversion assigning 'int', expected 'Class'}}
+  obj_C = j; // expected-warning {{incompatible pointer types assigning 'int *', expected 'Class'}}
   
-  i = obj;   // expected-warning {{incompatible types assigning 'id' to 'int'}}
-  i = obj_p; // expected-error {{incompatible types assigning 'id<MyProtocol>' to 'int'}}
-  i = obj_c; // expected-warning {{incompatible types assigning 'MyClass *' to 'int'}}
-  i = obj_C; // expected-warning {{incompatible types assigning 'Class' to 'int'}}
+  i = obj;   // expected-warning {{incompatible pointer/int conversion assigning 'id', expected 'int'}}
+  i = obj_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'int'}}
+  i = obj_c; // expected-warning {{incompatible pointer/int conversion assigning 'MyClass *', expected 'int'}}
+  i = obj_C; // expected-warning {{incompatible pointer/int conversion assigning 'Class', expected 'int'}}
   
-  j = obj;   // expected-warning {{incompatible pointer types assigning 'id' to 'int *'}}
-  j = obj_p; // expected-error {{incompatible types assigning 'id<MyProtocol>' to 'int *'}}
-  j = obj_c; // expected-warning {{incompatible pointer types assigning 'MyClass *' to 'int *'}}
-  j = obj_C; // expected-warning {{incompatible pointer types assigning 'Class' to 'int *'}}
+  j = obj;   // expected-warning {{incompatible pointer types assigning 'id', expected 'int *'}}
+  j = obj_p; // expected-error {{incompatible type assigning 'id<MyProtocol>', expected 'int *'}}
+  j = obj_c; // expected-warning {{incompatible pointer types assigning 'MyClass *', expected 'int *'}}
+  j = obj_C; // expected-warning {{incompatible pointer types assigning 'Class', expected 'int *'}}
   
   if (obj == i) foo() ; // expected-warning {{comparison between pointer and integer ('id' and 'int')}}
   if (i == obj) foo() ; // expected-warning {{comparison between pointer and integer ('int' and 'id')}}
index 058be26603ec6fa7e1fc8d2886291cf6f00ba793..8c2beee989c74d55cd2cf4db2c03e883868b7643 100644 (file)
@@ -29,7 +29,7 @@ id<MyProto1> Func(INTF <MyProto1, MyProto2> *p2)
 
 id<MyProto1, MyProto2> Gunc2(id <MyProto1>p2)
 {
-       Func(p2);       // expected-error {{incompatible types passing 'id<MyProto1>' to function expecting 'INTF<MyProto1,MyProto2> *'}}
+       Func(p2);       // expected-error {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
        return p2;      // expected-error {{incompatible type returning 'id<MyProto1>', expected 'id<MyProto1,MyProto2>'}}
 }
 
@@ -61,7 +61,7 @@ INTF<MyProto1> * Hunc1(id <MyProto1, MyProto2>p2)
 
 INTF<MyProto1, MyProto2> * Hunc2(id <MyProto1>p2)
 {
-       Func(p2);       // expected-error {{incompatible types passing 'id<MyProto1>' to function expecting 'INTF<MyProto1,MyProto2> *'}}
+       Func(p2);       // expected-error {{incompatible type passing 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
        return p2;      // expected-error {{incompatible type returning 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
 }
 
index 9647c74702d4a8e445b5a821ef6d1cc70469050c..72d3b41dbd8d4b31c77860e5c1cca5cc0274bd6f 100644 (file)
@@ -5,10 +5,10 @@ typedef int int4 __attribute__((vector_size(16)));
 typedef int4* int4p;
 
 void test1(float4 a, int4 *result, int i) {
-    result[i] = a; // expected-error {{assigning 'float4' to 'int4'}}
+    result[i] = a; // expected-error {{assigning 'float4', expected 'int4'}}
 }
 
 void test2(float4 a, int4p result, int i) {
-    result[i] = a; // expected-error {{assigning 'float4' to 'int4'}}
+    result[i] = a; // expected-error {{assigning 'float4', expected 'int4'}}
 }
 
index ff644229d2de2002c23e7842806daac7714813f6..6f681813bc9e41222f79e4c561a4f984ed7b5d7a 100644 (file)
@@ -13,27 +13,27 @@ void f() {
   v4ss v5;
   
   v1 = v2; 
-  v1 = v3; // expected-error {{incompatible types assigning 'v1s' to 'v2s'}}
-  v1 = v4; // expected-error {{incompatible types assigning 'v2f' to 'v2s'}}
+  v1 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2s'}}
+  v1 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v2s'}}
   v1 = v5;
   
   v2 = v1;
-  v2 = v3; // expected-error {{incompatible types assigning 'v1s' to 'v2u'}}
-  v2 = v4; // expected-error {{incompatible types assigning 'v2f' to 'v2u'}}
+  v2 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2u'}}
+  v2 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v2u'}}
   v2 = v5;
   
-  v3 = v1; // expected-error {{incompatible types assigning 'v2s' to 'v1s'}}
-  v3 = v2; // expected-error {{incompatible types assigning 'v2u' to 'v1s'}}
-  v3 = v4; // expected-error {{incompatible types assigning 'v2f' to 'v1s'}}
-  v3 = v5; // expected-error {{incompatible types assigning 'v4ss' to 'v1s'}}
+  v3 = v1; // expected-error {{incompatible type assigning 'v2s', expected 'v1s'}}
+  v3 = v2; // expected-error {{incompatible type assigning 'v2u', expected 'v1s'}}
+  v3 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v1s'}}
+  v3 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v1s'}}
   
-  v4 = v1; // expected-error {{incompatible types assigning 'v2s' to 'v2f'}}
-  v4 = v2; // expected-error {{incompatible types assigning 'v2u' to 'v2f'}}
-  v4 = v3; // expected-error {{incompatible types assigning 'v1s' to 'v2f'}}
-  v4 = v5; // expected-error {{incompatible types assigning 'v4ss' to 'v2f'}}
+  v4 = v1; // expected-error {{incompatible type assigning 'v2s', expected 'v2f'}}
+  v4 = v2; // expected-error {{incompatible type assigning 'v2u', expected 'v2f'}}
+  v4 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2f'}}
+  v4 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v2f'}}
   
   v5 = v1;
   v5 = v2;
-  v5 = v3; // expected-error {{incompatible types assigning 'v1s' to 'v4ss'}}
-  v5 = v4; // expected-error {{incompatible types assigning 'v2f' to 'v4ss'}}
+  v5 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v4ss'}}
+  v5 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v4ss'}}
 }