diff options
-rw-r--r-- | include/clang/Basic/DiagnosticSemaKinds.td | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 6 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-expr-3.cpp | 9 |
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); + } +}; |