Re: [PATCH] D24579: Revert "Do not warn about format strings that are indexed string literals."
This revision was automatically updated to reflect the committed changes. Closed by commit rL281530: Revert "Do not warn about format strings that are indexed string literals." (authored by srhines). Changed prior to commit: https://reviews.llvm.org/D24579?vs=71417&id=71419#toc Repository: rL LLVM https://reviews.llvm.org/D24579 Files: cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/test/Sema/format-strings.c Index: cfe/trunk/lib/Sema/SemaChecking.cpp === --- cfe/trunk/lib/Sema/SemaChecking.cpp +++ cfe/trunk/lib/Sema/SemaChecking.cpp @@ -3841,95 +3841,7 @@ }; } // end anonymous namespace -static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, - BinaryOperatorKind BinOpKind, - bool AddendIsRight) { - unsigned BitWidth = Offset.getBitWidth(); - unsigned AddendBitWidth = Addend.getBitWidth(); - // There might be negative interim results. - if (Addend.isUnsigned()) { -Addend = Addend.zext(++AddendBitWidth); -Addend.setIsSigned(true); - } - // Adjust the bit width of the APSInts. - if (AddendBitWidth > BitWidth) { -Offset = Offset.sext(AddendBitWidth); -BitWidth = AddendBitWidth; - } else if (BitWidth > AddendBitWidth) { -Addend = Addend.sext(BitWidth); - } - - bool Ov = false; - llvm::APSInt ResOffset = Offset; - if (BinOpKind == BO_Add) -ResOffset = Offset.sadd_ov(Addend, Ov); - else { -assert(AddendIsRight && BinOpKind == BO_Sub && - "operator must be add or sub with addend on the right"); -ResOffset = Offset.ssub_ov(Addend, Ov); - } - - // We add an offset to a pointer here so we should support an offset as big as - // possible. - if (Ov) { -assert(BitWidth <= UINT_MAX / 2 && "index (intermediate) result too big"); -Offset.sext(2 * BitWidth); -sumOffsets(Offset, Addend, BinOpKind, AddendIsRight); -return; - } - - Offset = ResOffset; -} - -namespace { -// This is a wrapper class around StringLiteral to support offsetted string -// literals as format strings. It takes the offset into account when returning -// the string and its length or the source locations to display notes correctly. -class FormatStringLiteral { - const StringLiteral *FExpr; - int64_t Offset; - - public: - FormatStringLiteral(const StringLiteral *fexpr, int64_t Offset = 0) - : FExpr(fexpr), Offset(Offset) {} - - StringRef getString() const { -return FExpr->getString().drop_front(Offset); - } - - unsigned getByteLength() const { -return FExpr->getByteLength() - getCharByteWidth() * Offset; - } - unsigned getLength() const { return FExpr->getLength() - Offset; } - unsigned getCharByteWidth() const { return FExpr->getCharByteWidth(); } - - StringLiteral::StringKind getKind() const { return FExpr->getKind(); } - - QualType getType() const { return FExpr->getType(); } - - bool isAscii() const { return FExpr->isAscii(); } - bool isWide() const { return FExpr->isWide(); } - bool isUTF8() const { return FExpr->isUTF8(); } - bool isUTF16() const { return FExpr->isUTF16(); } - bool isUTF32() const { return FExpr->isUTF32(); } - bool isPascal() const { return FExpr->isPascal(); } - - SourceLocation getLocationOfByte( - unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, - const TargetInfo &Target, unsigned *StartToken = nullptr, - unsigned *StartTokenByteOffset = nullptr) const { -return FExpr->getLocationOfByte(ByteNo + Offset, SM, Features, Target, -StartToken, StartTokenByteOffset); - } - - SourceLocation getLocStart() const LLVM_READONLY { -return FExpr->getLocStart().getLocWithOffset(Offset); - } - SourceLocation getLocEnd() const LLVM_READONLY { return FExpr->getLocEnd(); } -}; -} // end anonymous namespace - -static void CheckFormatString(Sema &S, const FormatStringLiteral *FExpr, +static void CheckFormatString(Sema &S, const StringLiteral *FExpr, const Expr *OrigFormatExpr, ArrayRef Args, bool HasVAListArg, unsigned format_idx, @@ -3950,11 +3862,8 @@ unsigned firstDataArg, Sema::FormatStringType Type, Sema::VariadicCallType CallType, bool InFunctionCall, llvm::SmallBitVector &CheckedVarArgs, - UncoveredArgHandler &UncoveredArg, - llvm::APSInt Offset) { + UncoveredArgHandler &UncoveredArg) { tryAgain: - assert(Offset.isSigned() && "invalid offset"); - if (E->isTypeDependent() || E->isValueDependent()) return SLCT_NotALiteral; @@ -3988,28 +3897,23 @@ CheckLeft = false; } -// We need to maintain the offsets for the right and the left hand side -// separately to check if every possible indexed expression is a valid -// string literal. The
[PATCH] D24579: Revert "Do not warn about format strings that are indexed string literals."
srhines created this revision. srhines added a subscriber: cfe-commits. This reverts r281527 because I messed up the attribution. https://reviews.llvm.org/D24579 Files: lib/Sema/SemaChecking.cpp test/Sema/format-strings.c Index: test/Sema/format-strings.c === --- test/Sema/format-strings.c +++ test/Sema/format-strings.c @@ -652,38 +652,3 @@ // expected-note@-1{{treat the string as an argument to avoid this}} } #pragma GCC diagnostic warning "-Wformat-nonliteral" - -void test_char_pointer_arithmetic(int b) { - const char s1[] = "string"; - const char s2[] = "%s string"; - - printf(s1 - 1); // expected-warning {{format string is not a string literal (potentially insecure)}} - // expected-note@-1{{treat the string as an argument to avoid this}} - - printf(s1 + 2); // no-warning - printf(s2 + 2); // no-warning - - const char s3[] = "%s string"; - printf((s3 + 2) - 2); // expected-warning{{more '%' conversions than data arguments}} - // expected-note@-2{{format string is defined here}} - printf(2 + s2); // no-warning - printf(6 + s2 - 2); // no-warning - printf(2 + (b ? s1 : s2)); // no-warning - - const char s5[] = "string %s"; - printf(2 + (b ? s2 : s5)); // expected-warning{{more '%' conversions than data arguments}} - // expected-note@-2{{format string is defined here}} - printf(2 + (b ? s2 : s5), ""); // no-warning - printf(2 + (b ? s1 : s2 - 2), ""); // no-warning - - const char s6[] = "%s string"; - printf(2 + (b ? s1 : s6 - 2)); // expected-warning{{more '%' conversions than data arguments}} - // expected-note@-2{{format string is defined here}} - printf(1 ? s2 + 2 : s2); // no-warning - printf(0 ? s2 : s2 + 2); // no-warning - printf(2 + s2 + 5 * 3 - 16, ""); // expected-warning{{data argument not used}} - - const char s7[] = "%s string %s %s"; - printf(s7 + 3, ""); // expected-warning{{more '%' conversions than data arguments}} - // expected-note@-2{{format string is defined here}} -} Index: lib/Sema/SemaChecking.cpp === --- lib/Sema/SemaChecking.cpp +++ lib/Sema/SemaChecking.cpp @@ -3841,95 +3841,7 @@ }; } // end anonymous namespace -static void sumOffsets(llvm::APSInt &Offset, llvm::APSInt Addend, - BinaryOperatorKind BinOpKind, - bool AddendIsRight) { - unsigned BitWidth = Offset.getBitWidth(); - unsigned AddendBitWidth = Addend.getBitWidth(); - // There might be negative interim results. - if (Addend.isUnsigned()) { -Addend = Addend.zext(++AddendBitWidth); -Addend.setIsSigned(true); - } - // Adjust the bit width of the APSInts. - if (AddendBitWidth > BitWidth) { -Offset = Offset.sext(AddendBitWidth); -BitWidth = AddendBitWidth; - } else if (BitWidth > AddendBitWidth) { -Addend = Addend.sext(BitWidth); - } - - bool Ov = false; - llvm::APSInt ResOffset = Offset; - if (BinOpKind == BO_Add) -ResOffset = Offset.sadd_ov(Addend, Ov); - else { -assert(AddendIsRight && BinOpKind == BO_Sub && - "operator must be add or sub with addend on the right"); -ResOffset = Offset.ssub_ov(Addend, Ov); - } - - // We add an offset to a pointer here so we should support an offset as big as - // possible. - if (Ov) { -assert(BitWidth <= UINT_MAX / 2 && "index (intermediate) result too big"); -Offset.sext(2 * BitWidth); -sumOffsets(Offset, Addend, BinOpKind, AddendIsRight); -return; - } - - Offset = ResOffset; -} - -namespace { -// This is a wrapper class around StringLiteral to support offsetted string -// literals as format strings. It takes the offset into account when returning -// the string and its length or the source locations to display notes correctly. -class FormatStringLiteral { - const StringLiteral *FExpr; - int64_t Offset; - - public: - FormatStringLiteral(const StringLiteral *fexpr, int64_t Offset = 0) - : FExpr(fexpr), Offset(Offset) {} - - StringRef getString() const { -return FExpr->getString().drop_front(Offset); - } - - unsigned getByteLength() const { -return FExpr->getByteLength() - getCharByteWidth() * Offset; - } - unsigned getLength() const { return FExpr->getLength() - Offset; } - unsigned getCharByteWidth() const { return FExpr->getCharByteWidth(); } - - StringLiteral::StringKind getKind() const { return FExpr->getKind(); } - - QualType getType() const { return FExpr->getType(); } - - bool isAscii() const { return FExpr->isAscii(); } - bool isWide() const { return FExpr->isWide(); } - bool isUTF8() const { return FExpr->isUTF8(); } - bool isUTF16() const { return FExpr->isUTF16(); } - bool isUTF32() const { return FExpr->isUTF32(); } - bool isPascal() const { return FExpr->isPascal(); } - - SourceLocation getLocationOfByte( - unsigned ByteNo, const SourceManager &SM, const LangOptions &Features, - const T