]> granicus.if.org Git - clang/commitdiff
Give a diagnostic when using non-POD types in a va_arg
authorDavid Majnemer <david.majnemer@gmail.com>
Mon, 13 Jun 2011 06:37:03 +0000 (06:37 +0000)
committerDavid Majnemer <david.majnemer@gmail.com>
Mon, 13 Jun 2011 06:37:03 +0000 (06:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132905 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
test/SemaTemplate/instantiate-expr-3.cpp

index 50c409bd03b4d17bb8b42d7883f3ac3fd04dbd9d..922b0197f18e0d11574f664ecdfe4d6f038757ce 100644 (file)
@@ -3933,6 +3933,9 @@ def warn_second_parameter_of_va_start_not_last_named_argument : Warning<
   "second parameter of 'va_start' not last named argument">;
 def err_first_argument_to_va_arg_not_of_type_va_list : Error<
   "first argument to 'va_arg' is of type %0 and not 'va_list'">;
+def warn_second_parameter_to_va_arg_not_pod : Warning<
+  "second argument to 'va_arg' is of non-POD type %0">,
+  InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
 
 def warn_return_missing_expr : Warning<
   "non-void %select{function|method}1 %0 should return a value">, DefaultError,
index 0549e9499560a0017d9de299eafecfce84175955..a44b4475ce8b74337d1adf83ef1562d79ea0ac3a 100644 (file)
@@ -9819,7 +9819,11 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
   }
 
   // FIXME: Check that type is complete/non-abstract
-  // FIXME: Warn if a non-POD type is passed in.
+
+  if (!TInfo->getType()->isDependentType() && !TInfo->getType()->isPODType())
+    return ExprError(Diag(TInfo->getTypeLoc().getBeginLoc(),
+                         diag::warn_second_parameter_to_va_arg_not_pod)
+      << TInfo->getType() << TInfo->getTypeLoc().getSourceRange());
 
   QualType T = TInfo->getType().getNonLValueExprType(Context);
   return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
index ca88b00300dcfa7de409a6543a96b72b5819ebd9..1febd282cce901eb29267241d412fe19bf7d76d9 100644 (file)
@@ -117,3 +117,12 @@ struct VaArg1 {
 
 template struct VaArg1<__builtin_va_list, int>;
 template struct VaArg1<int, int>; // expected-note{{instantiation}}
+
+struct VaArg2 {
+  virtual void f(int n, ...) {
+    __builtin_va_list va;
+    __builtin_va_start(va, n);
+    (void)__builtin_va_arg(va, VaArg2); // expected-error {{second argument to 'va_arg' is of non-POD type 'VaArg2'}}
+    __builtin_va_end(va);
+  }
+};