Clang error: second argument to 'va_arg' is of non-POD type A [-Wnon-pod-varargs] (warn_second_parameter_to_va_arg_not_pod)

From emmtrix Wiki
Jump to navigation Jump to search
Text error: second argument to 'va_arg' is of non-POD type A
Type Downgradable Error
Category Semantic Issue
Internal Id warn_second_parameter_to_va_arg_not_pod
Active by Default Yes
Flags -Wno-class-varargs (5 elements)
-Wno-non-pod-varargs (4 elements)
Internal Message second argument to 'va_arg' is of non-POD type %0
Regular Expression (?:error|warning|fatal error)\: second argument to 'va_arg' is of non\-POD type (.*?) \[[^\]]*\-Wnon\-pod\-varargs[^\]]*\]
First Commit 2011-06-13 254a5c07e7c9 Give a diagnostic when using non-POD types in a va_arg

Description

The downgradable error is issued by the Clang compiler when a non-POD (Plain Old Data) type is used as the second argument to the va_arg macro. A POD type in C++ is a type that has a trivial constructor, trivial copy and move constructors, and a trivial destructor, which basically means it can be copied bit by bit with no need for any copying semantics. Non-POD types, due to their complexity (such as having user-defined constructors or destructors, non-static data members of non-POD types, etc.), are not suitable for use with va_arg. This is because va_arg makes assumptions about the type it is dealing with that do not hold for non-POD types, potentially leading to undefined behavior. The error message is generated to alert the developer of this misuse, which could lead to errors in handling variable argument lists. By generating this error, Clang helps ensure that types used with va_arg are safe to be manipulated in such a context.  
AI Generated

Example

In the following example, a structure named C is defined with a default constructor, which disqualifies it from being a Plain Old Data (POD) type according to C++ rules. The function f is designed to illustrate the issue of using such non-POD types with the va_arg macro, leading to a downgradable error from the Clang compiler. The va_arg macro is used within f to attempt to retrieve an argument of type C from a va_list named a. This action triggers a diagnostic message indicating that the second argument to va_arg is of a non-POD type, specifically 'C'. Such types are not suitable for operations assumed by va_arg due to potential complexities, such as user-defined constructors or destructors, that could lead to undefined behavior.  
AI Generated


Flags -xc++ -fsyntax-only -ferror-limit=0

[Try out in Compiler Explorer]

Source
#include <stdarg.h>

struct C {
  C() {}
};

void f(va_list a) {
  C c = va_arg(a, C); // non-POD type
}
Compiler Output
<source>:8:19: error: second argument to 'va_arg' is of non-POD type 'C' [-Wnon-pod-varargs]
/opt/compiler-explorer/clang-17.0.1/lib/clang/17/include/stdarg.h:36:50: note: expanded from macro 'va_arg'


Clang Internals (17.0.6)

Git Commit Message

Give a diagnostic when using non-POD types in a va_arg

llvm-svn: 132905

Used in Clang Sources

This section lists all occurrences of the diagnostic within the Clang's codebase. For each occurrence, an auto-extracted snipped from the source code is listed including key elements like control structures, functions, or classes. It should illustrate the conditions under which the diagnostic is activated.

clang/lib/Sema/SemaExpr.cpp (line 17288)

ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc, Expr *E, TypeSourceInfo *TInfo, SourceLocation RPLoc) {
  // ...
  if (!TInfo->getType()->isDependentType()) {
    // ...
    if (!TInfo->getType().isPODType(Context)) {
      Diag(TInfo->getTypeLoc().getBeginLoc(), TInfo->getType()->isObjCLifetimeType() ? diag::warn_second_parameter_to_va_arg_ownership_qualified : diag::warn_second_parameter_to_va_arg_not_pod) << TInfo->getType() << TInfo->getTypeLoc().getSourceRange();

Triggered in Clang Tests

This section lists all internal Clang test cases that trigger the diagnostic.

clang/test/SemaCXX/vararg-non-pod.cpp

  • clang/test/SemaCXX/vararg-non-pod.cpp:177:32: warning: second argument to 'va_arg' is of non-POD type 'C' [-Wnon-pod-varargs]