aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td3
-rw-r--r--lib/Sema/SemaExpr.cpp6
-rw-r--r--test/SemaTemplate/instantiate-expr-3.cpp9
3 files changed, 17 insertions, 1 deletions
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 50c409bd03..922b0197f1 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -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,
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 0549e94995..a44b4475ce 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -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));
diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp
index ca88b00300..1febd282cc 100644
--- a/test/SemaTemplate/instantiate-expr-3.cpp
+++ b/test/SemaTemplate/instantiate-expr-3.cpp
@@ -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);
+ }
+};