Author: Arthur Eubanks Date: 2026-07-06T21:46:06Z New Revision: 94b325469b20255d31879c80204800510ac4fd66
URL: https://github.com/llvm/llvm-project/commit/94b325469b20255d31879c80204800510ac4fd66 DIFF: https://github.com/llvm/llvm-project/commit/94b325469b20255d31879c80204800510ac4fd66.diff LOG: Revert "[Clang][Sema] Add -Wstringop-overread warning for source buffer overreads (#183004)" (#207840) This reverts commit 86f2e71cb8d165b59ad31a442b2391e23826133e. And revert followup ab1ef459069d1dbf4ee9e5a802537ababe294b25 (#205201). Causes crashes: https://github.com/llvm/llvm-project/pull/183004#issuecomment-4897195939 Added: Modified: clang/docs/ReleaseNotes.md clang/include/clang/Basic/DiagnosticSemaKinds.td clang/lib/Sema/SemaChecking.cpp clang/test/AST/ByteCode/builtin-functions.cpp clang/test/Analysis/bstring.c clang/test/Analysis/malloc.c clang/test/Analysis/pr22954.c clang/test/Sema/builtin-memcpy.c clang/test/Sema/builtin-object-size.c clang/test/Sema/warn-fortify-source.c clang/test/SemaCXX/warn-memset-bad-sizeof.cpp compiler-rt/test/asan/TestCases/Windows/issue64990.cpp Removed: clang/test/Sema/warn-stringop-overread.c ################################################################################ diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 3ec47eb8b18c3..ed38ad5fbfe05 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -683,9 +683,6 @@ latest release, please see the [Clang Web Site](https://clang.llvm.org) or the - Clang now rejects inline asm constraints and clobbers that contain an embedded null character, instead of silently truncating them. (#GH173900) -- Added `-Wstringop-overread` to warn when `memcpy`, `memmove`, `memcmp`, - and related builtins read more bytes than the source buffer size (#GH83728). - - Diagnostics for the C++11 range-based for statement now report the correct iterator type in notes for invalid iterator types. diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 05f49a4dbd1ca..38d9e4046d3a5 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -969,10 +969,6 @@ def warn_fortify_source_size_mismatch : Warning< "'%0' size argument is too large; destination buffer has size %1," " but size argument is %2">, InGroup<FortifySource>; -def warn_stringop_overread - : Warning<"'%0' reading %1 byte%s1 from a region of size %2">, - InGroup<DiagGroup<"stringop-overread">>; - def warn_fortify_strlen_overflow: Warning< "'%0' will always overflow; destination buffer has size %1," " but the source string has length %2 (including NUL byte)">, diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index c3b3c15415442..d52c12670a57b 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1147,23 +1147,36 @@ static bool ProcessFormatStringLiteral(const Expr *FormatExpr, return false; } -namespace { -/// Helper class for buffer overflow/overread checking in fortified functions. -class FortifiedBufferChecker { -public: - FortifiedBufferChecker(Sema &S, FunctionDecl *FD, CallExpr *TheCall) - : S(S), TheCall(TheCall), FD(FD), - DABAttr(FD ? FD->getAttr<DiagnoseAsBuiltinAttr>() : nullptr) { - const TargetInfo &TI = S.getASTContext().getTargetInfo(); - SizeTypeWidth = TI.getTypeWidth(TI.getSizeType()); +void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, + CallExpr *TheCall) { + if (TheCall->isValueDependent() || TheCall->isTypeDependent() || + isConstantEvaluatedContext()) + return; + + bool UseDABAttr = false; + const FunctionDecl *UseDecl = FD; + + const auto *DABAttr = FD->getAttr<DiagnoseAsBuiltinAttr>(); + if (DABAttr) { + UseDecl = DABAttr->getFunction(); + assert(UseDecl && "Missing FunctionDecl in DiagnoseAsBuiltin attribute!"); + UseDABAttr = true; } - std::optional<unsigned> TranslateIndex(unsigned Index) { + unsigned BuiltinID = UseDecl->getBuiltinID(/*ConsiderWrappers=*/true); + + if (!BuiltinID) + return; + + const TargetInfo &TI = getASTContext().getTargetInfo(); + unsigned SizeTypeWidth = TI.getTypeWidth(TI.getSizeType()); + + auto TranslateIndex = [&](unsigned Index) -> std::optional<unsigned> { // If we refer to a diagnose_as_builtin attribute, we need to change the // argument index to refer to the arguments of the called function. Unless // the index is out of bounds, which presumably means it's a variadic // function. - if (!DABAttr) + if (!UseDABAttr) return Index; unsigned DABIndices = DABAttr->argIndices_size(); unsigned NewIndex = Index < DABIndices @@ -1172,25 +1185,25 @@ class FortifiedBufferChecker { if (NewIndex >= TheCall->getNumArgs()) return std::nullopt; return NewIndex; - } + }; - std::optional<llvm::APSInt> - ComputeExplicitObjectSizeArgument(unsigned Index) { + auto ComputeExplicitObjectSizeArgument = + [&](unsigned Index) -> std::optional<llvm::APSInt> { std::optional<unsigned> IndexOptional = TranslateIndex(Index); if (!IndexOptional) return std::nullopt; unsigned NewIndex = *IndexOptional; Expr::EvalResult Result; Expr *SizeArg = TheCall->getArg(NewIndex); - if (!SizeArg->EvaluateAsInt(Result, S.getASTContext())) + if (!SizeArg->EvaluateAsInt(Result, getASTContext())) return std::nullopt; llvm::APSInt Integer = Result.Val.getInt(); - assert(Integer.isUnsigned() && - "size arg should be unsigned after implicit conversion to size_t"); + Integer.setIsUnsigned(true); return Integer; - } + }; - std::optional<llvm::APSInt> ComputeSizeArgument(unsigned Index) { + auto ComputeSizeArgument = + [&](unsigned Index) -> std::optional<llvm::APSInt> { // If the parameter has a pass_object_size attribute, then we should use its // (potentially) more strict checking mode. Otherwise, conservatively assume // type 0. @@ -1212,14 +1225,15 @@ class FortifiedBufferChecker { const Expr *ObjArg = TheCall->getArg(NewIndex); if (std::optional<uint64_t> ObjSize = - ObjArg->tryEvaluateObjectSize(S.getASTContext(), BOSType)) { + ObjArg->tryEvaluateObjectSize(getASTContext(), BOSType)) { // Get the object size in the target's size_t width. return llvm::APSInt::getUnsigned(*ObjSize).extOrTrunc(SizeTypeWidth); } return std::nullopt; - } + }; - std::optional<llvm::APSInt> ComputeStrLenArgument(unsigned Index) { + auto ComputeStrLenArgument = + [&](unsigned Index) -> std::optional<llvm::APSInt> { std::optional<unsigned> IndexOptional = TranslateIndex(Index); if (!IndexOptional) return std::nullopt; @@ -1228,95 +1242,33 @@ class FortifiedBufferChecker { const Expr *ObjArg = TheCall->getArg(NewIndex); if (std::optional<uint64_t> Result = - ObjArg->tryEvaluateStrLen(S.getASTContext())) { + ObjArg->tryEvaluateStrLen(getASTContext())) { // Add 1 for null byte. return llvm::APSInt::getUnsigned(*Result + 1).extOrTrunc(SizeTypeWidth); } return std::nullopt; - } - - unsigned getSizeTypeWidth() const { return SizeTypeWidth; } - - unsigned getBuiltinID() const { - const FunctionDecl *UseDecl = FD; - if (DABAttr) { - UseDecl = DABAttr->getFunction(); - assert(UseDecl && "Missing FunctionDecl in DiagnoseAsBuiltin attribute!"); - } - return UseDecl->getBuiltinID(/*ConsiderWrappers=*/true); - } - - /// Return function name after stripping __builtin_ and _chk affixes. - std::string getFunctionName() const { - unsigned ID = getBuiltinID(); - if (!ID) { - // Use callee name directly if not a builtin. - const FunctionDecl *Callee = TheCall->getDirectCallee(); - assert(Callee && "expected callee"); - return Callee->getName().str(); - } - std::string Name = S.getASTContext().BuiltinInfo.getName(ID); - StringRef Ref = Name; - // Strip __builtin___*_chk or __builtin_ prefix. - if (!(Ref.consume_front("__builtin___") && Ref.consume_back("_chk"))) - Ref.consume_front("__builtin_"); - assert(!Ref.empty() && "expected non-empty function name"); - return Ref.str(); - } - - /// Check for source buffer overread in memory functions. - void checkSourceOverread(unsigned SrcArgIdx, unsigned SizeArgIdx) { - if (S.isConstantEvaluatedContext()) - return; - - const Expr *SrcArg = TheCall->getArg(SrcArgIdx); - const Expr *SizeArg = TheCall->getArg(SizeArgIdx); - if (SrcArg->isInstantiationDependent() || - SizeArg->isInstantiationDependent()) - return; - - std::optional<llvm::APSInt> CopyLen = - ComputeExplicitObjectSizeArgument(SizeArgIdx); - std::optional<llvm::APSInt> SrcBufSize = ComputeSizeArgument(SrcArgIdx); - - if (!CopyLen || !SrcBufSize) - return; - - // Warn only if copy length exceeds source buffer size. - if (llvm::APSInt::compareValues(*CopyLen, *SrcBufSize) <= 0) - return; - - S.DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall, - S.PDiag(diag::warn_stringop_overread) - << getFunctionName() << CopyLen->getZExtValue() - << SrcBufSize->getZExtValue()); - } - -private: - Sema &S; - CallExpr *TheCall; - FunctionDecl *FD; - const DiagnoseAsBuiltinAttr *DABAttr; - unsigned SizeTypeWidth; -}; -} // anonymous namespace - -void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, - CallExpr *TheCall) { - if (TheCall->isInstantiationDependent() || isConstantEvaluatedContext()) - return; - - FortifiedBufferChecker Checker(*this, FD, TheCall); - - unsigned BuiltinID = Checker.getBuiltinID(); - if (!BuiltinID) - return; - - unsigned SizeTypeWidth = Checker.getSizeTypeWidth(); + }; std::optional<llvm::APSInt> SourceSize; std::optional<llvm::APSInt> DestinationSize; unsigned DiagID = 0; + bool IsChkVariant = false; + + auto GetFunctionName = [&]() { + std::string FunctionNameStr = + getASTContext().BuiltinInfo.getName(BuiltinID); + llvm::StringRef FunctionName = FunctionNameStr; + // Skim off the details of whichever builtin was called to produce a better + // diagnostic, as it's unlikely that the user wrote the __builtin + // explicitly. + if (IsChkVariant) { + FunctionName = FunctionName.drop_front(std::strlen("__builtin___")); + FunctionName = FunctionName.drop_back(std::strlen("_chk")); + } else { + FunctionName.consume_front("__builtin_"); + } + return FunctionName.str(); + }; switch (BuiltinID) { default: @@ -1328,8 +1280,8 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, case Builtin::BI__builtin_strcpy: case Builtin::BIstrcpy: { DiagID = diag::warn_fortify_strlen_overflow; - SourceSize = Checker.ComputeStrLenArgument(1); - DestinationSize = Checker.ComputeSizeArgument(0); + SourceSize = ComputeStrLenArgument(1); + DestinationSize = ComputeSizeArgument(0); break; } @@ -1337,8 +1289,9 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, case Builtin::BI__builtin___stpcpy_chk: case Builtin::BI__builtin___strcpy_chk: { DiagID = diag::warn_fortify_strlen_overflow; - SourceSize = Checker.ComputeStrLenArgument(1); - DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2); + SourceSize = ComputeStrLenArgument(1); + DestinationSize = ComputeExplicitObjectSizeArgument(2); + IsChkVariant = true; break; } @@ -1364,14 +1317,14 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, unsigned SourceSize) { DiagID = diag::warn_fortify_scanf_overflow; unsigned Index = ArgIndex + DataIndex; - std::string FunctionName = Checker.getFunctionName(); + std::string FunctionName = GetFunctionName(); DiagRuntimeBehavior(TheCall->getArg(Index)->getBeginLoc(), TheCall, PDiag(DiagID) << FunctionName << (Index + 1) << DestSize << SourceSize); }; auto ShiftedComputeSizeArgument = [&](unsigned Index) { - return Checker.ComputeSizeArgument(Index + DataIndex); + return ComputeSizeArgument(Index + DataIndex); }; ScanfDiagnosticFormatHandler H(ShiftedComputeSizeArgument, Diagnose); const char *FormatBytes = FormatStrRef.data(); @@ -1404,9 +1357,10 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, SourceSize = llvm::APSInt::getUnsigned(H.getSizeLowerBound()) .extOrTrunc(SizeTypeWidth); if (BuiltinID == Builtin::BI__builtin___sprintf_chk) { - DestinationSize = Checker.ComputeExplicitObjectSizeArgument(2); + DestinationSize = ComputeExplicitObjectSizeArgument(2); + IsChkVariant = true; } else { - DestinationSize = Checker.ComputeSizeArgument(0); + DestinationSize = ComputeSizeArgument(0); } break; } @@ -1424,24 +1378,19 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, case Builtin::BI__builtin___memccpy_chk: case Builtin::BI__builtin___mempcpy_chk: { DiagID = diag::warn_builtin_chk_overflow; - SourceSize = - Checker.ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 2); + SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 2); DestinationSize = - Checker.ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); - - if (BuiltinID == Builtin::BI__builtin___memcpy_chk || - BuiltinID == Builtin::BI__builtin___memmove_chk || - BuiltinID == Builtin::BI__builtin___mempcpy_chk) { - Checker.checkSourceOverread(/*SrcArgIdx=*/1, /*SizeArgIdx=*/2); - } + ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); + IsChkVariant = true; break; } case Builtin::BI__builtin___snprintf_chk: case Builtin::BI__builtin___vsnprintf_chk: { DiagID = diag::warn_builtin_chk_overflow; - SourceSize = Checker.ComputeExplicitObjectSizeArgument(1); - DestinationSize = Checker.ComputeExplicitObjectSizeArgument(3); + SourceSize = ComputeExplicitObjectSizeArgument(1); + DestinationSize = ComputeExplicitObjectSizeArgument(3); + IsChkVariant = true; break; } @@ -1457,9 +1406,8 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, // size larger than the destination buffer though; this is a runtime abort // in _FORTIFY_SOURCE mode, and is quite suspicious otherwise. DiagID = diag::warn_fortify_source_size_mismatch; - SourceSize = - Checker.ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); - DestinationSize = Checker.ComputeSizeArgument(0); + SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); + DestinationSize = ComputeSizeArgument(0); break; } @@ -1474,52 +1422,23 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, case Builtin::BImempcpy: case Builtin::BI__builtin_mempcpy: { DiagID = diag::warn_fortify_source_overflow; - SourceSize = - Checker.ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); - DestinationSize = Checker.ComputeSizeArgument(0); - - // Buffer overread doesn't make sense for memset/bzero. - if (BuiltinID != Builtin::BImemset && - BuiltinID != Builtin::BI__builtin_memset && - BuiltinID != Builtin::BIbzero && - BuiltinID != Builtin::BI__builtin_bzero) { - Checker.checkSourceOverread(/*SrcArgIdx=*/1, /*SizeArgIdx=*/2); - } + SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); + DestinationSize = ComputeSizeArgument(0); break; } case Builtin::BIbcopy: case Builtin::BI__builtin_bcopy: { DiagID = diag::warn_fortify_source_overflow; - SourceSize = - Checker.ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); - DestinationSize = Checker.ComputeSizeArgument(1); - Checker.checkSourceOverread(/*SrcArgIdx=*/0, /*SizeArgIdx=*/2); + SourceSize = ComputeExplicitObjectSizeArgument(TheCall->getNumArgs() - 1); + DestinationSize = ComputeSizeArgument(1); break; } - - // memchr(buf, val, size) - case Builtin::BImemchr: - case Builtin::BI__builtin_memchr: { - Checker.checkSourceOverread(/*SrcArgIdx=*/0, /*SizeArgIdx=*/2); - return; - } - - // memcmp/bcmp(buf0, buf1, size) - // Two checks since each buffer is read - case Builtin::BImemcmp: - case Builtin::BI__builtin_memcmp: - case Builtin::BIbcmp: - case Builtin::BI__builtin_bcmp: { - Checker.checkSourceOverread(/*SrcArgIdx=*/0, /*SizeArgIdx=*/2); - Checker.checkSourceOverread(/*SrcArgIdx=*/1, /*SizeArgIdx=*/2); - return; - } case Builtin::BIsnprintf: case Builtin::BI__builtin_snprintf: case Builtin::BIvsnprintf: case Builtin::BI__builtin_vsnprintf: { DiagID = diag::warn_fortify_source_size_mismatch; - SourceSize = Checker.ComputeExplicitObjectSizeArgument(1); + SourceSize = ComputeExplicitObjectSizeArgument(1); const auto *FormatExpr = TheCall->getArg(2)->IgnoreParenImpCasts(); StringRef FormatStrRef; size_t StrLen; @@ -1543,12 +1462,12 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, FormatSize.toString(FormatSizeStr, /*Radix=*/10); DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall, PDiag(TruncationDiagID) - << Checker.getFunctionName() - << SpecifiedSizeStr << FormatSizeStr); + << GetFunctionName() << SpecifiedSizeStr + << FormatSizeStr); } } } - DestinationSize = Checker.ComputeSizeArgument(0); + DestinationSize = ComputeSizeArgument(0); const Expr *LenArg = TheCall->getArg(1)->IgnoreCasts(); const Expr *Dest = TheCall->getArg(0)->IgnoreCasts(); IdentifierInfo *FnInfo = FD->getIdentifier(); @@ -1560,7 +1479,7 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, llvm::APSInt::compareValues(*SourceSize, *DestinationSize) <= 0) return; - std::string FunctionName = Checker.getFunctionName(); + std::string FunctionName = GetFunctionName(); SmallString<16> DestinationStr; SmallString<16> SourceStr; diff --git a/clang/test/AST/ByteCode/builtin-functions.cpp b/clang/test/AST/ByteCode/builtin-functions.cpp index b14ae91c753cb..d6990d1725072 100644 --- a/clang/test/AST/ByteCode/builtin-functions.cpp +++ b/clang/test/AST/ByteCode/builtin-functions.cpp @@ -1,17 +1,17 @@ -// RUN: %clang_cc1 -Wno-string-plus-int -Wno-stringop-overread -fexperimental-new-constant-interpreter -triple x86_64 %s -verify=expected,both -// RUN: %clang_cc1 -Wno-string-plus-int -Wno-stringop-overread -triple x86_64 %s -verify=ref,both +// RUN: %clang_cc1 -Wno-string-plus-int -fexperimental-new-constant-interpreter -triple x86_64 %s -verify=expected,both +// RUN: %clang_cc1 -Wno-string-plus-int -triple x86_64 %s -verify=ref,both // -// RUN: %clang_cc1 -Wno-string-plus-int -Wno-stringop-overread -fexperimental-new-constant-interpreter -triple i686 %s -verify=expected,both -// RUN: %clang_cc1 -Wno-string-plus-int -Wno-stringop-overread -triple i686 %s -verify=ref,both +// RUN: %clang_cc1 -Wno-string-plus-int -fexperimental-new-constant-interpreter -triple i686 %s -verify=expected,both +// RUN: %clang_cc1 -Wno-string-plus-int -triple i686 %s -verify=ref,both // -// RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -Wno-stringop-overread -fexperimental-new-constant-interpreter -triple x86_64 %s -verify=expected,both -// RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -Wno-stringop-overread -triple x86_64 %s -verify=ref,both +// RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -fexperimental-new-constant-interpreter -triple x86_64 %s -verify=expected,both +// RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -triple x86_64 %s -verify=ref,both // -// RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -Wno-stringop-overread -fexperimental-new-constant-interpreter -triple i686 %s -verify=expected,both -// RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -Wno-stringop-overread -triple i686 %s -verify=ref,both +// RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -fexperimental-new-constant-interpreter -triple i686 %s -verify=expected,both +// RUN: %clang_cc1 -std=c++20 -Wno-string-plus-int -triple i686 %s -verify=ref,both // -// RUN: %clang_cc1 -triple avr -std=c++20 -Wno-string-plus-int -Wno-stringop-overread -fexperimental-new-constant-interpreter %s -verify=expected,both -// RUN: %clang_cc1 -triple avr -std=c++20 -Wno-string-plus-int -Wno-stringop-overread -verify=ref,both %s +// RUN: %clang_cc1 -triple avr -std=c++20 -Wno-string-plus-int -fexperimental-new-constant-interpreter %s -verify=expected,both +// RUN: %clang_cc1 -triple avr -std=c++20 -Wno-string-plus-int -verify=ref,both %s #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define LITTLE_END 1 diff --git a/clang/test/Analysis/bstring.c b/clang/test/Analysis/bstring.c index 7c33b09409725..b337c71eb02c7 100644 --- a/clang/test/Analysis/bstring.c +++ b/clang/test/Analysis/bstring.c @@ -1,5 +1,4 @@ // RUN: %clang_analyze_cc1 -verify %s \ -// RUN: -Wno-stringop-overread \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix.cstring \ // RUN: -analyzer-disable-checker=unix.cstring.UninitializedRead \ @@ -8,7 +7,6 @@ // RUN: -analyzer-config eagerly-assume=false // // RUN: %clang_analyze_cc1 -verify %s -DUSE_BUILTINS \ -// RUN: -Wno-stringop-overread \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix.cstring \ // RUN: -analyzer-disable-checker=unix.cstring.UninitializedRead \ @@ -17,7 +15,6 @@ // RUN: -analyzer-config eagerly-assume=false // // RUN: %clang_analyze_cc1 -verify %s -DVARIANT \ -// RUN: -Wno-stringop-overread \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix.cstring \ // RUN: -analyzer-disable-checker=unix.cstring.UninitializedRead \ @@ -26,7 +23,6 @@ // RUN: -analyzer-config eagerly-assume=false // // RUN: %clang_analyze_cc1 -verify %s -DUSE_BUILTINS -DVARIANT \ -// RUN: -Wno-stringop-overread \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=unix.cstring \ // RUN: -analyzer-disable-checker=unix.cstring.UninitializedRead \ diff --git a/clang/test/Analysis/malloc.c b/clang/test/Analysis/malloc.c index efb2d52d3a321..849ab3a3a0f37 100644 --- a/clang/test/Analysis/malloc.c +++ b/clang/test/Analysis/malloc.c @@ -1,6 +1,5 @@ // RUN: %clang_analyze_cc1 -Wno-strict-prototypes -Wno-error=implicit-int -verify %s \ // RUN: -Wno-alloc-size \ -// RUN: -Wno-stringop-overread \ // RUN: -analyzer-checker=core \ // RUN: -analyzer-checker=alpha.deadcode.UnreachableCode \ // RUN: -analyzer-checker=unix \ diff --git a/clang/test/Analysis/pr22954.c b/clang/test/Analysis/pr22954.c index b3910da6c70ab..3d1cac1972066 100644 --- a/clang/test/Analysis/pr22954.c +++ b/clang/test/Analysis/pr22954.c @@ -3,7 +3,7 @@ // At the moment the whole of the destination array content is invalidated. // If a.s1 region has a symbolic offset, the whole region of 'a' is invalidated. // Specific triple set to test structures of size 0. -// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -Wno-error=int-conversion -Wno-stringop-overread -verify -analyzer-config eagerly-assume=false %s +// RUN: %clang_analyze_cc1 -triple x86_64-pc-linux-gnu -analyzer-checker=core,unix.Malloc,debug.ExprInspection -Wno-error=int-conversion -verify -analyzer-config eagerly-assume=false %s typedef __typeof(sizeof(int)) size_t; diff --git a/clang/test/Sema/builtin-memcpy.c b/clang/test/Sema/builtin-memcpy.c index 94f71e4c42a58..2a55e78034a02 100644 --- a/clang/test/Sema/builtin-memcpy.c +++ b/clang/test/Sema/builtin-memcpy.c @@ -7,8 +7,7 @@ /// Zero-sized structs should not crash. int b() { struct { } a[10]; - __builtin_memcpy(&a[2], a, 2); // c-warning {{buffer has size 0, but size argument is 2}} \ - // c-warning {{'memcpy' reading 2 bytes from a region of size 0}} + __builtin_memcpy(&a[2], a, 2); // c-warning {{buffer has size 0, but size argument is 2}} return 0; } diff --git a/clang/test/Sema/builtin-object-size.c b/clang/test/Sema/builtin-object-size.c index 8d48d3f569d91..a763c24fd6620 100644 --- a/clang/test/Sema/builtin-object-size.c +++ b/clang/test/Sema/builtin-object-size.c @@ -50,7 +50,7 @@ void f5(void) { char buf[10]; memset((void *)0x100000000ULL, 0, 0x1000); - memcpy((char *)NULL + 0x10000, buf, 0x10); // expected-warning {{'memcpy' reading 16 bytes from a region of size 10}} + memcpy((char *)NULL + 0x10000, buf, 0x10); memcpy1((char *)NULL + 0x10000, buf, 0x10); // expected-error {{argument value 4 is outside the valid range [0, 3]}} } diff --git a/clang/test/Sema/warn-fortify-source.c b/clang/test/Sema/warn-fortify-source.c index 0a6c44f59af9e..530fa8104bd56 100644 --- a/clang/test/Sema/warn-fortify-source.c +++ b/clang/test/Sema/warn-fortify-source.c @@ -100,7 +100,7 @@ void call_stpcpy(void) { void call_memmove(void) { char s1[10], s2[20]; - __builtin_memmove(s2, s1, 20); // expected-warning {{'memmove' reading 20 bytes from a region of size 10}} + __builtin_memmove(s2, s1, 20); __builtin_memmove(s1, s2, 20); // expected-warning {{'memmove' will always overflow; destination buffer has size 10, but size argument is 20}} } @@ -271,13 +271,11 @@ template <int A, int B> void call_memcpy_dep() { char bufferA[A]; char bufferB[B]; - memcpy(bufferA, bufferB, 10); + memcpy(bufferA, bufferB, 10); // expected-warning{{'memcpy' will always overflow; destination buffer has size 9, but size argument is 10}} } void call_call_memcpy() { - call_memcpy_dep<10, 9>(); // expected-note {{in instantiation of function template specialization 'call_memcpy_dep<10, 9>' requested here}} - // expected-warning@-5 {{'memcpy' reading 10 bytes from a region of size 9}} + call_memcpy_dep<10, 9>(); call_memcpy_dep<9, 10>(); // expected-note {{in instantiation of function template specialization 'call_memcpy_dep<9, 10>' requested here}} - // expected-warning@-7 {{'memcpy' will always overflow; destination buffer has size 9, but size argument is 10}} } #endif diff --git a/clang/test/Sema/warn-stringop-overread.c b/clang/test/Sema/warn-stringop-overread.c deleted file mode 100644 index e4a6289a1df2a..0000000000000 --- a/clang/test/Sema/warn-stringop-overread.c +++ /dev/null @@ -1,175 +0,0 @@ -// RUN: %clang_cc1 %s -verify -// RUN: %clang_cc1 %s -verify -DUSE_BUILTINS -// RUN: %clang_cc1 -xc++ %s -verify -// RUN: %clang_cc1 -xc++ %s -verify -DUSE_BUILTINS - -typedef __SIZE_TYPE__ size_t; - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(USE_BUILTINS) -#define memcpy(x,y,z) __builtin_memcpy(x,y,z) -#define memmove(x,y,z) __builtin_memmove(x,y,z) -#define memchr(x,y,z) __builtin_memchr(x,y,z) -#define memcmp(x,y,z) __builtin_memcmp(x,y,z) -#else -void *memcpy(void *dst, const void *src, size_t c); -void *memmove(void *dst, const void *src, size_t c); -void *memchr(const void *s, int c, size_t n); -int memcmp(const void *s1, const void *s2, size_t n); -#endif - -int bcmp(const void *s1, const void *s2, size_t n); -void bcopy(const void *src, void *dst, size_t n); - -#ifdef __cplusplus -} -#endif - -void test_memcpy_overread(void) { - char dst[100]; - int src = 0; - memcpy(dst, &src, sizeof(src) + 1); // expected-warning {{'memcpy' reading 5 bytes from a region of size 4}} -} - -void test_memcpy_array_overread(void) { - int dest[10]; - int src[5] = {1, 2, 3, 4, 5}; - memcpy(dest, src, 10 * sizeof(int)); // expected-warning {{'memcpy' reading 40 bytes from a region of size 20}} -} - -void test_memcpy_struct_overread(void) { - struct S { - int x; - int y; - }; - char dst[100]; - struct S src = {1, 2}; - memcpy(dst, &src, sizeof(struct S) + 1); // expected-warning {{'memcpy' reading 9 bytes from a region of size 8}} -} - -void test_memmove_overread(void) { - char dst[100]; - char src[10]; - memmove(dst, src, 20); // expected-warning {{'memmove' reading 20 bytes from a region of size 10}} -} - -void test_memcpy_no_warning_exact_size(void) { - char dst[100]; - int src = 0; - memcpy(dst, &src, sizeof(src)); // no warning -} - -void test_memcpy_no_warning_smaller_size(void) { - char dst[100]; - int src[10]; - memcpy(dst, src, 5 * sizeof(int)); // no warning -} - -void test_memcpy_both_overflow(void) { - char dst[5]; - int src = 0; - memcpy(dst, &src, 10); // expected-warning {{'memcpy' reading 10 bytes from a region of size 4}} - // expected-warning@-1 {{'memcpy' will always overflow; destination buffer has size 5, but size argument is 10}} -} - -void test_memchr_overread(void) { - char buf[4]; - memchr(buf, 'a', 8); // expected-warning {{'memchr' reading 8 bytes from a region of size 4}} -} - -void test_memchr_no_warning(void) { - char buf[10]; - memchr(buf, 'a', 10); // no warning -} - -void test_memcmp_overread_first(void) { - char a[4], b[100]; - memcmp(a, b, 8); // expected-warning {{'memcmp' reading 8 bytes from a region of size 4}} -} - -void test_memcmp_overread_second(void) { - char a[100], b[4]; - memcmp(a, b, 8); // expected-warning {{'memcmp' reading 8 bytes from a region of size 4}} -} - -void test_memcmp_overread_both(void) { - char a[4], b[2]; - memcmp(a, b, 8); // expected-warning {{'memcmp' reading 8 bytes from a region of size 4}} \ - // expected-warning {{'memcmp' reading 8 bytes from a region of size 2}} -} - -void test_memcmp_no_warning(void) { - char a[10], b[10]; - memcmp(a, b, 10); // no warning -} - -void test_memcpy_src_offset_overread(void) { - char src[] = {1, 2, 3, 4}; - char dst[10]; - memcpy(dst, src + 2, 3); // expected-warning {{'memcpy' reading 3 bytes from a region of size 2}} -} - -void test_memcpy_src_offset_no_warning(void) { - char src[] = {1, 2, 3, 4}; - char dst[10]; - memcpy(dst, src + 2, 2); // no warning -} - -void test_bcmp_overread(void) { - char a[4], b[100]; - bcmp(a, b, 8); // expected-warning {{'bcmp' reading 8 bytes from a region of size 4}} -} - -void test_bcmp_no_warning(void) { - char a[10], b[10]; - bcmp(a, b, 10); // no warning -} - -void test_bcopy_overread(void) { - char src[4], dst[100]; - bcopy(src, dst, 8); // expected-warning {{'bcopy' reading 8 bytes from a region of size 4}} -} - -void test_bcopy_no_warning(void) { - char src[10], dst[10]; - bcopy(src, dst, 10); // no warning -} - -void test_memcpy_chk_overread(void) { - char dst[100]; - char src[4]; - __builtin___memcpy_chk(dst, src, 8, sizeof(dst)); // expected-warning {{'memcpy' reading 8 bytes from a region of size 4}} -} - -void test_memmove_chk_overread(void) { - char dst[100]; - char src[4]; - __builtin___memmove_chk(dst, src, 8, sizeof(dst)); // expected-warning {{'memmove' reading 8 bytes from a region of size 4}} -} - -#ifdef __cplusplus -template <int N> -void test_memcpy_dependent_dest() { - char dst[N]; - int src = 0; - memcpy(dst, &src, sizeof(src) + 1); // expected-warning {{'memcpy' reading 5 bytes from a region of size 4}} -} - -void call_test_memcpy_dependent_dest() { - test_memcpy_dependent_dest<100>(); // expected-note {{in instantiation}} -} - -// FIXME: We should warn here at the template definition since src and size are -// not dependent, but checkFortifiedBuiltinMemoryFunction exits when any part of -// the call is dependent (and thus uninstantiated). -template <int N> -void test_memcpy_dependent_dest_uninstantiated() { - char dst[N]; - int src = 0; - memcpy(dst, &src, sizeof(src) + 1); // missing-warning {{'memcpy' reading 5 bytes from a region of size 4}} -} - -#endif diff --git a/clang/test/SemaCXX/warn-memset-bad-sizeof.cpp b/clang/test/SemaCXX/warn-memset-bad-sizeof.cpp index 405652e3daf5e..6f1cd4dd639ec 100644 --- a/clang/test/SemaCXX/warn-memset-bad-sizeof.cpp +++ b/clang/test/SemaCXX/warn-memset-bad-sizeof.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument -Wno-stringop-overread %s +// RUN: %clang_cc1 -fsyntax-only -verify -Wno-sizeof-array-argument %s // extern "C" void *bzero(void *, unsigned); extern "C" void *memset(void *, int, unsigned); diff --git a/compiler-rt/test/asan/TestCases/Windows/issue64990.cpp b/compiler-rt/test/asan/TestCases/Windows/issue64990.cpp index 7fccff0313c62..5222ec6e08191 100644 --- a/compiler-rt/test/asan/TestCases/Windows/issue64990.cpp +++ b/compiler-rt/test/asan/TestCases/Windows/issue64990.cpp @@ -1,5 +1,5 @@ // Repro for the issue #64990: Asan with Windows EH generates __asan_xxx runtime calls without required funclet tokens -// RUN: %clang_cl_asan %Od %if MSVC %{ /Oi %} %s -EHsc -Wno-stringop-overread %Fe%t +// RUN: %clang_cl_asan %Od %if MSVC %{ /Oi %} %s -EHsc %Fe%t // RUN: not %run %t 2>&1 | FileCheck %s // UNSUPPORTED: target={{.*-windows-gnu}} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
