https://github.com/Pppp1116 created https://github.com/llvm/llvm-project/pull/190448
None >From 62726850715f8d97ba74858638345433c3ba8d43 Mon Sep 17 00:00:00 2001 From: Pppp1116 <[email protected]> Date: Sat, 4 Apr 2026 08:06:21 +0100 Subject: [PATCH] Add a fortify warning for literal strcpy overflow --- clang/include/clang/Basic/DiagnosticSemaKinds.td | 4 ++++ clang/lib/Sema/SemaChecking.cpp | 16 ++++++++++++++++ .../Sema/warn-fortify-literal-copy-overflow.c | 10 ++++++++++ 3 files changed, 30 insertions(+) create mode 100644 clang/test/Sema/warn-fortify-literal-copy-overflow.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index eddf9c50033e1..086a88eba6e1b 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -965,6 +965,10 @@ def warn_fortify_strlen_overflow: Warning< " but the source string has length %2 (including NUL byte)">, InGroup<FortifySource>; +def warn_fortify_literal_copy_too_large : Warning< + "copying %0 bytes into buffer of size %1 (including null terminator)">, + InGroup<FortifySource>; + def subst_format_overflow : TextSubstitution< "'%0' will always overflow; destination buffer has size %1," " but format string expands to at least %2">; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index de8b965144971..974607648b939 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1247,6 +1247,7 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, std::optional<llvm::APSInt> DestinationSize; unsigned DiagID = 0; bool IsChkVariant = false; + bool UseLiteralCopyOverflowDiag = false; auto GetFunctionName = [&]() { std::string FunctionNameStr = @@ -1276,6 +1277,10 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, DiagID = diag::warn_fortify_strlen_overflow; SourceSize = ComputeStrLenArgument(1); DestinationSize = ComputeSizeArgument(0); + UseLiteralCopyOverflowDiag = + (BuiltinID == Builtin::BI__builtin_strcpy || + BuiltinID == Builtin::BIstrcpy) && + isa<StringLiteral>(TheCall->getArg(1)->IgnoreParenCasts()); break; } @@ -1286,6 +1291,9 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, SourceSize = ComputeStrLenArgument(1); DestinationSize = ComputeExplicitObjectSizeArgument(2); IsChkVariant = true; + UseLiteralCopyOverflowDiag = + BuiltinID == Builtin::BI__builtin___strcpy_chk && + isa<StringLiteral>(TheCall->getArg(1)->IgnoreParenCasts()); break; } @@ -1470,6 +1478,14 @@ void Sema::checkFortifiedBuiltinMemoryFunction(FunctionDecl *FD, SmallString<16> SourceStr; DestinationSize->toString(DestinationStr, /*Radix=*/10); SourceSize->toString(SourceStr, /*Radix=*/10); + + if (UseLiteralCopyOverflowDiag) { + DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall, + PDiag(diag::warn_fortify_literal_copy_too_large) + << SourceStr << DestinationStr); + return; + } + DiagRuntimeBehavior(TheCall->getBeginLoc(), TheCall, PDiag(DiagID) << FunctionName << DestinationStr << SourceStr); diff --git a/clang/test/Sema/warn-fortify-literal-copy-overflow.c b/clang/test/Sema/warn-fortify-literal-copy-overflow.c new file mode 100644 index 0000000000000..c3e96dbae217c --- /dev/null +++ b/clang/test/Sema/warn-fortify-literal-copy-overflow.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -Wfortify-source -verify %s + +char *strcpy(char *, const char *); + +void literal_strcpy_overflow(void) { + char buf[4]; + char ok[5]; + strcpy(buf, "abcd"); // expected-warning{{copying 5 bytes into buffer of size 4 (including null terminator)}} + strcpy(ok, "abcd"); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
