[Sema] check InitListExpr format strings like {"foo"}

Adds InitListExpr case in format string checks.

e.g.

    int sprintf(char *__restrict, const char * __restrict, ...);

    int foo()
    {
        char data[100];
        constexpr const char* fmt2{"%d"};  // no-warning
        sprintf(data, fmt2, 123);
    }

Fixes: https://github.com/llvm/llvm-project/issues/58900

Reviewed By: aaron.ballman

Differential Revision: https://reviews.llvm.org/D137839
This commit is contained in:
Yingchi Long 2022-11-11 22:45:08 +08:00
parent d9ef5574d4
commit 2ec79afd89
No known key found for this signature in database
GPG Key ID: 296C3FEFEA88ABC5
2 changed files with 15 additions and 0 deletions

View File

@ -8585,6 +8585,15 @@ tryAgain:
return SLCT_UncheckedLiteral;
switch (E->getStmtClass()) {
case Stmt::InitListExprClass:
// Handle expressions like {"foobar"}.
if (const clang::Expr *SLE = maybeConstEvalStringLiteral(S.Context, E)) {
return checkFormatStringExpr(S, SLE, Args, APK, format_idx, firstDataArg,
Type, CallType, /*InFunctionCall*/ false,
CheckedVarArgs, UncoveredArg, Offset,
IgnoreStringsWithoutSpecifiers);
}
return SLCT_NotALiteral;
case Stmt::BinaryConditionalOperatorClass:
case Stmt::ConditionalOperatorClass: {
// The expression is a literal if both sub-expressions were, and it was

View File

@ -203,6 +203,12 @@ void f() {
printf(string_linebreak(), 1, 2, 3, 4); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
printf(not_literal(), 1, 2, 3, 4); // expected-warning {{format string is not a string literal}}
printf(wrap_constexpr(), 1, 2); // expected-warning {{format specifies type 'char *' but the argument has type 'int'}}
constexpr const char *fmt {"%d%d"};
printf(fmt, 1, 1); // no-warning
constexpr const char *fmt2 {"%d"}; // expected-note{{format string is defined here}}
printf(fmt2, "oops"); // expected-warning{{format specifies type 'int' but the argument has type}}
}