diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp --- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp +++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeVarargCheck.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "ProTypeVarargCheck.h" +#include "../utils/Matchers.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" @@ -133,7 +134,9 @@ Finder->addMatcher( callExpr(callee(functionDecl(isVariadic(), - unless(hasAnyName(AllowedVariadics))))) + unless(hasAnyName(AllowedVariadics)))), + unless(hasAncestor(expr(matchers::hasUnevaluatedContext()))), + unless(hasAncestor(typeLoc()))) .bind("callvararg"), this); diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst --- a/clang-tools-extra/docs/ReleaseNotes.rst +++ b/clang-tools-extra/docs/ReleaseNotes.rst @@ -176,6 +176,10 @@ ` check to ignore delegate constructors. +- Improved :doc:`cppcoreguidelines-pro-type-vararg + ` check to ignore + false-positives in unevaluated context (e.g., ``decltype``, ``sizeof``, ...). + - Improved :doc:`llvm-namespace-comment ` check to provide fixes for ``inline`` namespaces in the same format as :program:`clang-format`. diff --git a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-vararg.rst b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-vararg.rst --- a/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-vararg.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/cppcoreguidelines/pro-type-vararg.rst @@ -7,7 +7,8 @@ ``va_arg``. To allow for SFINAE use of vararg functions, a call is not flagged if a literal -0 is passed as the only vararg argument. +0 is passed as the only vararg argument or function is used in unevaluated +context. Passing to varargs assumes the correct type will be read. This is fragile because it cannot generally be enforced to be safe in the language and so relies diff --git a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-vararg.cpp b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-vararg.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-vararg.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/pro-type-vararg.cpp @@ -66,3 +66,16 @@ char *tmp1 = in; void *tmp2 = in; } + +namespace PR30542 { + struct X; + template + char IsNullConstant(X*); + template + char (&IsNullConstant(...))[2]; + + static_assert(sizeof(IsNullConstant(0)) == 1, ""); + static_assert(sizeof(IsNullConstant(17)) == 2, ""); + + using Type = decltype(IsNullConstant(17)); +}