inclyc created this revision. Herald added a project: All. inclyc added a reviewer: aaron.ballman. inclyc published this revision for review. Herald added a project: clang. Herald added a subscriber: cfe-commits.
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 Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D137839 Files: clang/lib/Sema/SemaChecking.cpp clang/test/SemaCXX/format-strings.cpp Index: clang/test/SemaCXX/format-strings.cpp =================================================================== --- clang/test/SemaCXX/format-strings.cpp +++ clang/test/SemaCXX/format-strings.cpp @@ -203,6 +203,9 @@ 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 } Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -8554,6 +8554,15 @@ 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
Index: clang/test/SemaCXX/format-strings.cpp =================================================================== --- clang/test/SemaCXX/format-strings.cpp +++ clang/test/SemaCXX/format-strings.cpp @@ -203,6 +203,9 @@ 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 } Index: clang/lib/Sema/SemaChecking.cpp =================================================================== --- clang/lib/Sema/SemaChecking.cpp +++ clang/lib/Sema/SemaChecking.cpp @@ -8554,6 +8554,15 @@ 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
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits