implement rdar://6780761, making sema reject some code that otherwise
authorChris Lattner <sabre@nondot.org>
Sun, 12 Apr 2009 08:11:20 +0000 (08:11 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 12 Apr 2009 08:11:20 +0000 (08:11 +0000)
crashes codegen.

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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaOverload.cpp
test/SemaObjC/method-bad-param.m

index 5b3ecb92992dc86d3ab236ab4d12cceb3f707ab4..6c76e4aa2700789166e3be91ac3d76ef46871d2d 100644 (file)
@@ -1190,6 +1190,11 @@ def err_typecheck_call_too_many_args : Error<
 def warn_call_wrong_number_of_arguments : Warning<
   "too %select{few|many}0 arguments in call to %1">;
 def err_deleted_function_use : Error<"attempt to use a deleted function">;
+
+def err_cannot_pass_objc_interface_to_vararg : Error<
+  "cannot pass object with interface type %0 by-value through variadic "
+  "%select{function|block|method}1">;
+
 def warn_cannot_pass_non_pod_arg_to_vararg : Warning<
   "cannot pass object of non-POD type %0 through variadic "
   "%select{function|block|method}1; call will abort at runtime">;
index 8138379af7c1a0bbd483bcf7903ccc9d2cfe2adf..5018833267d1d2eb908c25619a1b7e962d30f1bd 100644 (file)
@@ -2210,7 +2210,7 @@ public:
   
   // DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
   // will warn if the resulting type is not a POD type.
-  void DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
+  bool DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT);
   
   // UsualArithmeticConversions - performs the UsualUnaryConversions on it's
   // operands and then handles various conversions that are common to binary
index f2820df93e8dfe9a28ced6ec5196386311441435..e380f78ad056f2f8177e257d6c06e1663277a0db 100644 (file)
@@ -154,16 +154,25 @@ void Sema::DefaultArgumentPromotion(Expr *&Expr) {
   UsualUnaryConversions(Expr);
 }
 
-// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
-// will warn if the resulting type is not a POD type.
-void Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
+/// DefaultVariadicArgumentPromotion - Like DefaultArgumentPromotion, but
+/// will warn if the resulting type is not a POD type, and rejects ObjC
+/// interfaces passed by value.  This returns true if the argument type is
+/// completely illegal.
+bool Sema::DefaultVariadicArgumentPromotion(Expr *&Expr, VariadicCallType CT) {
   DefaultArgumentPromotion(Expr);
   
-  if (!Expr->getType()->isPODType()) {
-    Diag(Expr->getLocStart(), 
-         diag::warn_cannot_pass_non_pod_arg_to_vararg) << 
-    Expr->getType() << CT;
+  if (Expr->getType()->isObjCInterfaceType()) {
+    Diag(Expr->getLocStart(),
+         diag::err_cannot_pass_objc_interface_to_vararg)
+      << Expr->getType() << CT;
+    return true;
   }
+  
+  if (!Expr->getType()->isPODType())
+    Diag(Expr->getLocStart(), diag::warn_cannot_pass_non_pod_arg_to_vararg)
+      << Expr->getType() << CT;
+
+  return false;
 }
 
 
@@ -2223,7 +2232,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn,
     // Promote the arguments (C99 6.5.2.2p7).
     for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
       Expr *Arg = Args[i];
-      DefaultVariadicArgumentPromotion(Arg, CallType);
+      Invalid |= DefaultVariadicArgumentPromotion(Arg, CallType);
       Call->setArg(i, Arg);
     }
   }
index 54a18ac832a2a46b4ea98ebe3ec34bd57d95c21f..8d8fae035a1e57d26ec64200238fbc9a26d68565 100644 (file)
@@ -164,7 +164,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
   unsigned NumNamedArgs = Sel.getNumArgs();
   assert(NumArgs >= NumNamedArgs && "Too few arguments for selector!");
 
-  bool anyIncompatibleArgs = false;
+  bool IsError = false;
   for (unsigned i = 0; i < NumNamedArgs; i++) {
     Expr *argExpr = Args[i];
     assert(argExpr && "CheckMessageArgumentTypes(): missing expression");
@@ -183,7 +183,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
     if (Args[i] != argExpr) // The expression was converted.
       Args[i] = argExpr; // Make sure we store the converted expression.
     
-    anyIncompatibleArgs |= 
+    IsError |= 
       DiagnoseAssignmentResult(Result, argExpr->getLocStart(), lhsType, rhsType,
                                argExpr, "sending");
   }
@@ -191,7 +191,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
   // Promote additional arguments to variadic methods.
   if (Method->isVariadic()) {
     for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
-      DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
+      IsError |= DefaultVariadicArgumentPromotion(Args[i], VariadicMethod);
   } else {
     // Check for extra arguments to non-variadic methods.
     if (NumArgs != NumNamedArgs) {
@@ -203,7 +203,7 @@ bool Sema::CheckMessageArgumentTypes(Expr **Args, unsigned NumArgs,
     }
   }
 
-  return anyIncompatibleArgs;
+  return IsError;
 }
 
 bool Sema::isSelfExpr(Expr *RExpr) {
index 0a12a71bb74f0590dfaa088c7885b31f1165f00e..875a38253dabf1deac0bda10380da579219af2f6 100644 (file)
@@ -4178,11 +4178,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
   else if (NumArgs > NumArgsInProto)
     NumArgsToCheck = NumArgsInProto;
 
+  bool IsError = false;
+
   // Initialize the implicit object parameter.
-  if (PerformObjectArgumentInitialization(Object, Method))
-    return true;
+  IsError |= PerformObjectArgumentInitialization(Object, Method);
   TheCall->setArg(0, Object);
 
+
   // Check the argument types.
   for (unsigned i = 0; i != NumArgsToCheck; i++) {
     Expr *Arg;
@@ -4191,8 +4193,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
       
       // Pass the argument.
       QualType ProtoArgType = Proto->getArgType(i);
-      if (PerformCopyInitialization(Arg, ProtoArgType, "passing"))
-        return true;
+      IsError |= PerformCopyInitialization(Arg, ProtoArgType, "passing");
     } else {
       Arg = new (Context) CXXDefaultArgExpr(Method->getParamDecl(i));
     }
@@ -4205,12 +4206,13 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object,
     // Promote the arguments (C99 6.5.2.2p7).
     for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
       Expr *Arg = Args[i];
-
-      DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
+      IsError |= DefaultVariadicArgumentPromotion(Arg, VariadicMethod);
       TheCall->setArg(i + 1, Arg);
     }
   }
 
+  if (IsError) return true;
+
   return CheckFunctionCall(Method, TheCall.take()).release();
 }
 
index 824f72d29be50c3a1ef4c544cde757340a53e73d..f797188669ade133acffde5c153d71e7f1e76e69 100644 (file)
@@ -22,3 +22,9 @@
 
 void somefunc(foo x) {} // expected-error {{Objective-C interface type 'foo' cannot be passed by value}}
 foo somefunc2() {} // expected-error {{Objective-C interface type 'foo' cannot be returned by value}}
+
+// rdar://6780761
+void f0(foo *a0) {
+  extern void g0(int x, ...);
+  g0(1, *(foo*)0);  // expected-error {{cannot pass object with interface type 'foo' by-value through variadic function}}
+}