Index: test/Sema/varargs.c
===================================================================
--- test/Sema/varargs.c	(revision 132903)
+++ test/Sema/varargs.c	(working copy)
@@ -61,3 +61,9 @@
   __builtin_va_end(ap);
 }
 
+void f8(int a, ...) {
+  __builtin_va_list ap;
+  __builtin_va_start(ap, a);
+  (void)__builtin_va_arg(ap, void); // expected-error {{second argument to 'va_arg' is of incomplete type 'void'}}
+  __builtin_va_end(ap);
+}
Index: test/SemaTemplate/instantiate-expr-3.cpp
===================================================================
--- test/SemaTemplate/instantiate-expr-3.cpp	(revision 132905)
+++ test/SemaTemplate/instantiate-expr-3.cpp	(working copy)
@@ -117,12 +117,3 @@
 
 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);
-  }
-};
Index: test/SemaCXX/vararg-non-pod.cpp
===================================================================
--- test/SemaCXX/vararg-non-pod.cpp	(revision 132903)
+++ test/SemaCXX/vararg-non-pod.cpp	(working copy)
@@ -101,3 +101,10 @@
   __builtin_va_start(list, somearg);
 }
 
+void t7(int n, ...) {
+  __builtin_va_list list;
+  __builtin_va_start(list, n);
+  (void)__builtin_va_arg(list, C); // expected-warning{{second argument to 'va_arg' is of non-POD type 'C'}}
+  __builtin_va_end(list);
+}
+
Index: include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- include/clang/Basic/DiagnosticSemaKinds.td	(revision 132905)
+++ include/clang/Basic/DiagnosticSemaKinds.td	(working copy)
@@ -3933,6 +3933,9 @@
   "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_incomplete: Warning<
+  "second argument to 'va_arg' is of incomplete type %0">,
+  InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
 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;
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 132905)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -9818,13 +9818,19 @@
       << OrigExpr->getType() << E->getSourceRange());
   }
 
-  // FIXME: Check that type is complete/non-abstract
+  if (!TInfo->getType()->isDependentType()) {
+    unsigned D = 0;
 
-  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());
+    if (TInfo->getType()->isIncompleteType())
+      D = diag::warn_second_parameter_to_va_arg_incomplete;
+    else if (!TInfo->getType()->isPODType())
+      D = diag::warn_second_parameter_to_va_arg_not_pod;
 
+    if (D != 0)
+      return ExprError(Diag(TInfo->getTypeLoc().getBeginLoc(), D)
+          << TInfo->getType() << TInfo->getTypeLoc().getSourceRange());
+  }
+
   QualType T = TInfo->getType().getNonLValueExprType(Context);
   return Owned(new (Context) VAArgExpr(BuiltinLoc, E, TInfo, RPLoc, T));
 }
