Skip to content

Commit d7dd2c4

Browse files
committed
Re-land "[-Wunsafe-buffer-usage] Warning Libc functions (#101583)"
Revert commit 2345796, and re-land with a new flag "-Wunsafe-buffer-usage-in-libc-call" for the new warning. (rdar://117182250)
1 parent b525ead commit d7dd2c4

9 files changed

+766
-16
lines changed

clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#define LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H
1616

1717
#include "clang/AST/Decl.h"
18+
#include "clang/AST/Expr.h"
1819
#include "clang/AST/Stmt.h"
1920
#include "clang/Basic/SourceLocation.h"
2021
#include "llvm/Support/Debug.h"
@@ -106,6 +107,20 @@ class UnsafeBufferUsageHandler {
106107
virtual void handleUnsafeOperation(const Stmt *Operation,
107108
bool IsRelatedToDecl, ASTContext &Ctx) = 0;
108109

110+
/// Invoked when a call to an unsafe libc function is found.
111+
/// \param PrintfInfo
112+
/// is 0 if the callee function is not a member of the printf family;
113+
/// is 1 if the callee is `sprintf`;
114+
/// is 2 if arguments of the call have `__size_by` relation but are not in a
115+
/// safe pattern;
116+
/// is 3 if string arguments do not guarantee null-termination
117+
/// is 4 if the callee takes va_list
118+
/// \param UnsafeArg one of the actual arguments that is unsafe, non-null
119+
/// only when `2 <= PrintfInfo <= 3`
120+
virtual void handleUnsafeLibcCall(const CallExpr *Call, unsigned PrintfInfo,
121+
ASTContext &Ctx,
122+
const Expr *UnsafeArg = nullptr) = 0;
123+
109124
/// Invoked when an unsafe operation with a std container is found.
110125
virtual void handleUnsafeOperationInContainer(const Stmt *Operation,
111126
bool IsRelatedToDecl,
@@ -151,6 +166,10 @@ class UnsafeBufferUsageHandler {
151166
virtual bool
152167
ignoreUnsafeBufferInContainer(const SourceLocation &Loc) const = 0;
153168

169+
/// \return true iff unsafe libc call should NOT be reported at `Loc`
170+
virtual bool
171+
ignoreUnsafeBufferInLibcCall(const SourceLocation &Loc) const = 0;
172+
154173
virtual std::string
155174
getUnsafeBufferUsageAttributeTextAt(SourceLocation Loc,
156175
StringRef WSSuffix = "") const = 0;

clang/include/clang/Analysis/Analyses/UnsafeBufferUsageGadgets.def

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
#define WARNING_GADGET(name) GADGET(name)
1919
#endif
2020

21-
/// A `WARNING_GADGET` subset, where the code pattern of each gadget
22-
/// corresponds uses of a (possibly hardened) contatiner (e.g., `std::span`).
23-
#ifndef WARNING_CONTAINER_GADGET
24-
#define WARNING_CONTAINER_GADGET(name) WARNING_GADGET(name)
21+
/// A `WARNING_GADGET` subset, each of which may be enable/disable separately
22+
/// with different flags
23+
#ifndef WARNING_OPTIONAL_GADGET
24+
#define WARNING_OPTIONAL_GADGET(name) WARNING_GADGET(name)
2525
#endif
2626

2727
/// Safe gadgets correspond to code patterns that aren't unsafe but need to be
@@ -38,7 +38,8 @@ WARNING_GADGET(PointerArithmetic)
3838
WARNING_GADGET(UnsafeBufferUsageAttr)
3939
WARNING_GADGET(UnsafeBufferUsageCtorAttr)
4040
WARNING_GADGET(DataInvocation)
41-
WARNING_CONTAINER_GADGET(SpanTwoParamConstructor) // Uses of `std::span(arg0, arg1)`
41+
WARNING_OPTIONAL_GADGET(UnsafeLibcFunctionCall)
42+
WARNING_OPTIONAL_GADGET(SpanTwoParamConstructor) // Uses of `std::span(arg0, arg1)`
4243
FIXABLE_GADGET(ULCArraySubscript) // `DRE[any]` in an Unspecified Lvalue Context
4344
FIXABLE_GADGET(DerefSimplePtrArithFixable)
4445
FIXABLE_GADGET(PointerDereference)
@@ -52,5 +53,5 @@ FIXABLE_GADGET(PointerInit)
5253

5354
#undef FIXABLE_GADGET
5455
#undef WARNING_GADGET
55-
#undef WARNING_CONTAINER_GADGET
56+
#undef WARNING_OPTIONAL_GADGET
5657
#undef GADGET

clang/include/clang/Basic/DiagnosticGroups.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1558,7 +1558,8 @@ def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">;
15581558

15591559
// Warnings and fixes to support the "safe buffers" programming model.
15601560
def UnsafeBufferUsageInContainer : DiagGroup<"unsafe-buffer-usage-in-container">;
1561-
def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer]>;
1561+
def UnsafeBufferUsageInLibcCall : DiagGroup<"unsafe-buffer-usage-in-libc-call">;
1562+
def UnsafeBufferUsage : DiagGroup<"unsafe-buffer-usage", [UnsafeBufferUsageInContainer, UnsafeBufferUsageInLibcCall]>;
15621563

15631564
// Warnings and notes related to the function effects system underlying
15641565
// the nonblocking and nonallocating attributes.

clang/include/clang/Basic/DiagnosticSemaKinds.td

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12416,6 +12416,13 @@ def warn_unsafe_buffer_operation : Warning<
1241612416
"unsafe buffer access|function introduces unsafe buffer manipulation|unsafe invocation of span::data|"
1241712417
"field %1 prone to unsafe buffer manipulation}0">,
1241812418
InGroup<UnsafeBufferUsage>, DefaultIgnore;
12419+
def warn_unsafe_buffer_libc_call : Warning<
12420+
"function %0 is unsafe">,
12421+
InGroup<UnsafeBufferUsageInLibcCall>, DefaultIgnore;
12422+
def note_unsafe_buffer_printf_call : Note<
12423+
"%select{|change to 'snprintf' for explicit bounds checking | buffer pointer and size may not match"
12424+
"|string argument is not guaranteed to be null-terminated"
12425+
"|'va_list' is unsafe}0">;
1241912426
def note_unsafe_buffer_operation : Note<
1242012427
"used%select{| in pointer arithmetic| in buffer access}0 here">;
1242112428
def note_unsafe_buffer_variable_fixit_group : Note<

0 commit comments

Comments
 (0)