Clang warning: passing object of class type A through variadic ...... [-Wclass-varargs] (warn_pass_class_arg_to_vararg)

From emmtrix Wiki
Jump to navigation Jump to search
Text
error: passing object of class type A through variadic
function
block
method
constructor
 
; did you mean to call 'D'?

Type Warning
Category Semantic Issue
Internal Id warn_pass_class_arg_to_vararg
Active by Default No
Flags -Wclass-varargs (5 elements)
Internal Message passing object of class type %0 through variadic %select{function|block|method|constructor}1%select{|; did you mean to call '%3'?}2
Regular Expression (?:warning|error|fatal error)\: passing object of class type (.*?) through variadic (?:function|block|method|constructor)(?:|; did you mean to call '(.*?)'\?) \[(?:\-Werror,)?\-Wclass\-varargs[^\]]*\]
First Commit 2014-02-28 2868a736f88e Add a -Wclass-varargs to warn on objects of any class type being passed through an ellipsis. Since C...

Description

The warning is issued by the Clang compiler when an object of a class type is passed to a variadic function, variadic method, variadic block, or through a variadic constructor. This situation arises because the variadic portion of such calls expects arguments that can be easily handled using C's default argument promotions, which do not include non-POD (Plain Old Data) class types. Passing class types through these variadic contexts can lead to undefined behavior due to incorrect argument handling.

This diagnostic specifically targets the issue where an object might be passed directly to a variadic argument list without considering whether the object's type is safely passed in such a manner. In some cases, the compiler can suggest a method to be called on the object to obtain a more suitable argument type for the variadic function, such as using the .c_str() method for string-like class objects to retrieve a plain C string (const char*) representation of the object.

The warning can be enabled with the -Wclass-varargs flag. This diagnostic is crucial for identifying potential misuses of variadic functions with class types, which could lead to subtle bugs or runtime errors. By addressing warnings issued by this diagnostic, the code quality can be improved to ensure more predictable and safer execution.

 
AI Generated

Example

In the following example, a class C is defined with a public constructor and a member function print that displays a message indicating an instance of C is being used. The function f is defined to take a character pointer followed by variadic arguments. The main function creates an instance of C and attempts to pass it to the function f as part of its variadic arguments. This situation triggers a warning because an object of class type C is being passed through a variadic function, which is not supported due to the potential for undefined behavior. The compiler generates a warning message indicating the issue and suggesting that, in general, if a suitable method existed (like .c_str() for string objects to obtain a C-style string), calling it might resolve the problem. However, no specific method call suggestion is made in this case, as C does not have a method that would yield a type compatible with variadic arguments.  
AI Generated


Flags -xc++ -Wclass-varargs

[Try out in Compiler Explorer]

Source
#include <stdio.h>

class C {
public:
  C() {}
  void print() const { printf("C instance\n"); }
};

void f(const char *s, ...) {}

int main() {
  C v;
  f("%s", v); // MyClass passed to variadic function
  return 0;
}
Compiler Output
<source>:13:11: warning: passing object of class type 'C' through variadic function [-Wclass-varargs]


Clang Internals (17.0.6)

Git Commit Message

Add a -Wclass-varargs to warn on objects of any class type being passed through an ellipsis. Since C++11 relaxed the rules on this, we allow a lot more bad code through silently, such as:

  const char *format = "%s";
  std::experimental::string_view view = "foo";
  printf(format, view);

In this case, not only warn about a class type being used here, but also suggest that calling c_str() might be a good idea.

llvm-svn: 202461

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 1004)

void Sema::checkVariadicArgument(const Expr *E, VariadicCallType CT) {
  // ...
  case VAK_Valid:
    if (Ty->isRecordType()) {
      // ...
      DiagRuntimeBehavior(E->getBeginLoc(), nullptr, PDiag(diag::warn_pass_class_arg_to_vararg) << Ty << CT << hasCStrMethod(E) << ".c_str()");

Triggered in Clang Tests

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

clang/test/SemaCXX/vararg-class.cpp

  • clang/test/SemaCXX/vararg-class.cpp:15:5: warning: passing object of class type 'A' through variadic function [-Wclass-varargs]
  • clang/test/SemaCXX/vararg-class.cpp:17:5: warning: passing object of class type 'C' through variadic function; did you mean to call '.c_str()'? [-Wclass-varargs]
  • clang/test/SemaCXX/vararg-class.cpp:18:5: warning: passing object of class type 'D' through variadic function; did you mean to call '.c_str()'? [-Wclass-varargs]
  • clang/test/SemaCXX/vararg-class.cpp:19:5: warning: passing object of class type 'E' through variadic function [-Wclass-varargs]
  • clang/test/SemaCXX/vararg-class.cpp:20:5: warning: passing object of class type 'F' through variadic function; did you mean to call '.c_str()'? [-Wclass-varargs]