[cfe-commits] r62148 - in /cfe/trunk: include/clang/Basic/DiagnosticKinds.def lib/Sema/SemaExpr.cpp lib/Sema/SemaExprObjC.cpp lib/Sema/SemaOverload.cpp test/SemaCXX/vararg-non-pod.cpp test/SemaObjCXX/vararg-non-pod.mm

Anders Carlsson andersca at mac.com
Mon Jan 12 21:48:52 PST 2009


Author: andersca
Date: Mon Jan 12 23:48:52 2009
New Revision: 62148

URL: http://llvm.org/viewvc/llvm-project?rev=62148&view=rev
Log:
Warn when someone tries to pass a variable with a non-POD type to a varargs function/method/block.


Added:
    cfe/trunk/test/SemaCXX/vararg-non-pod.cpp
    cfe/trunk/test/SemaObjCXX/vararg-non-pod.mm
Modified:
    cfe/trunk/include/clang/Basic/DiagnosticKinds.def
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/lib/Sema/SemaOverload.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticKinds.def
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticKinds.def?rev=62148&r1=62147&r2=62148&view=diff

==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticKinds.def (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticKinds.def Mon Jan 12 23:48:52 2009
@@ -1410,6 +1410,9 @@
      "too few arguments to %select{function|block|method}0 call")
 DIAG(err_typecheck_call_too_many_args, ERROR,
      "too many arguments to %select{function|block|method}0 call")
+DIAG(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")
 DIAG(err_typecheck_closure_too_many_args, ERROR,
      "too many arguments to closure call")
 DIAG(err_typecheck_call_invalid_ordered_compare, ERROR,

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=62148&r1=62147&r2=62148&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jan 12 23:48:52 2009
@@ -1688,6 +1688,17 @@
     // Promote the arguments (C99 6.5.2.2p7).
     for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
       Expr *Arg = Args[i];
+      if (!Arg->getType()->isPODType()) {
+        int CallType = 0;
+        if (Fn->getType()->isBlockPointerType())
+          CallType = 1; // Block
+        else if (isa<MemberExpr>(Fn))
+          CallType = 2;
+        
+        Diag(Arg->getLocStart(), 
+             diag::warn_cannot_pass_non_pod_arg_to_vararg) << 
+        Arg->getType() << CallType;
+      }
       DefaultArgumentPromotion(Arg);
       Call->setArg(i, Arg);
     }

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=62148&r1=62147&r2=62148&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Mon Jan 12 23:48:52 2009
@@ -156,8 +156,15 @@
 
   // Promote additional arguments to variadic methods.
   if (Method->isVariadic()) {
-    for (unsigned i = NumNamedArgs; i < NumArgs; ++i)
+    for (unsigned i = NumNamedArgs; i < NumArgs; ++i) {
+      if (!Args[i]->getType()->isPODType()) {
+        Diag(Args[i]->getLocStart(), 
+             diag::warn_cannot_pass_non_pod_arg_to_vararg) << 
+        Args[i]->getType() << 2; // Method
+      }
+      
       DefaultArgumentPromotion(Args[i]);
+    }
   } else {
     // Check for extra arguments to non-variadic methods.
     if (NumArgs != NumNamedArgs) {

Modified: cfe/trunk/lib/Sema/SemaOverload.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=62148&r1=62147&r2=62148&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaOverload.cpp (original)
+++ cfe/trunk/lib/Sema/SemaOverload.cpp Mon Jan 12 23:48:52 2009
@@ -3576,6 +3576,13 @@
     // Promote the arguments (C99 6.5.2.2p7).
     for (unsigned i = NumArgsInProto; i != NumArgs; i++) {
       Expr *Arg = Args[i];
+        
+      if (!Arg->getType()->isPODType()) {
+        Diag(Arg->getLocStart(), 
+             diag::warn_cannot_pass_non_pod_arg_to_vararg) << 
+        Arg->getType() << 2; // Method
+      }
+
       DefaultArgumentPromotion(Arg);
       TheCall->setArg(i + 1, Arg);
     }

Added: cfe/trunk/test/SemaCXX/vararg-non-pod.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/vararg-non-pod.cpp?rev=62148&view=auto

==============================================================================
--- cfe/trunk/test/SemaCXX/vararg-non-pod.cpp (added)
+++ cfe/trunk/test/SemaCXX/vararg-non-pod.cpp Mon Jan 12 23:48:52 2009
@@ -0,0 +1,49 @@
+// RUN: clang -fsyntax-only -verify -fblocks %s
+
+class C {
+public:
+  C(int);
+  void g(int a, ...);
+  static void h(int a, ...);
+};
+
+void g(int a, ...);
+
+void t1()
+{
+  C c(10);
+  
+  g(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic function; call will abort at runtime}}
+}
+
+void t2()
+{
+  C c(10);
+
+  c.g(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
+  
+  C::h(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic function; call will abort at runtime}}
+}
+
+int (^block)(int, ...);
+
+void t3()
+{
+  C c(10);
+  
+  block(10, c); // expected-warning{{cannot pass object of non-POD type 'class C' through variadic block; call will abort at runtime}}
+}
+
+class D {
+public:
+  void operator() (int a, ...);
+};
+
+void t4()
+{
+  C c(10);
+
+  D d;
+  
+  d(10, c); // expected-warning{{Line 48: cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
+}

Added: cfe/trunk/test/SemaObjCXX/vararg-non-pod.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/vararg-non-pod.mm?rev=62148&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjCXX/vararg-non-pod.mm (added)
+++ cfe/trunk/test/SemaObjCXX/vararg-non-pod.mm Mon Jan 12 23:48:52 2009
@@ -0,0 +1,18 @@
+// RUN: clang -fsyntax-only -verify %s
+
+class C {
+public:
+  C(int);
+};
+
+ at interface D 
+- (void)g:(int)a, ...;
+ at end
+
+void t1(D *d)
+{
+  C c(10);
+
+  [d g:10, c]; // expected-warning{{cannot pass object of non-POD type 'class C' through variadic method; call will abort at runtime}}
+}
+





More information about the cfe-commits mailing list