Skip to content

Commit

Permalink
Re-land "[-Wunsafe-buffer-usage] Warning Libc functions (llvm#101583)"
Browse files Browse the repository at this point in the history
Revert commit 2345796, and re-land
with a new flag "-Wunsafe-buffer-usage-in-libc-call" for the new
warning.

(rdar://117182250)
  • Loading branch information
ziqingluo-90 committed Sep 5, 2024
1 parent b525ead commit d7dd2c4
Show file tree
Hide file tree
Showing 9 changed files with 766 additions and 16 deletions.
19 changes: 19 additions & 0 deletions clang/include/clang/Analysis/Analyses/UnsafeBufferUsage.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#define LLVM_CLANG_ANALYSIS_ANALYSES_UNSAFEBUFFERUSAGE_H

#include "clang/AST/Decl.h"
#include "clang/AST/Expr.h"
#include "clang/AST/Stmt.h"
#include "clang/Basic/SourceLocation.h"
#include "llvm/Support/Debug.h"
Expand Down Expand Up @@ -106,6 +107,20 @@ class UnsafeBufferUsageHandler {
virtual void handleUnsafeOperation(const Stmt *Operation,
bool IsRelatedToDecl, ASTContext &Ctx) = 0;

/// Invoked when a call to an unsafe libc function is found.
/// \param PrintfInfo
/// is 0 if the callee function is not a member of the printf family;
/// is 1 if the callee is `sprintf`;
/// is 2 if arguments of the call have `__size_by` relation but are not in a
/// safe pattern;
/// is 3 if string arguments do not guarantee null-termination
/// is 4 if the callee takes va_list
/// \param UnsafeArg one of the actual arguments that is unsafe, non-null
/// only when `2 <= PrintfInfo <= 3`
virtual void handleUnsafeLibcCall(const CallExpr *Call, unsigned PrintfInfo,
ASTContext &Ctx,
const Expr *UnsafeArg = nullptr) = 0;

/// Invoked when an unsafe operation with a std container is found.
virtual void handleUnsafeOperationInContainer(const Stmt *Operation,
bool IsRelatedToDecl,
Expand Down Expand Up @@ -151,6 +166,10 @@ class UnsafeBufferUsageHandler {
virtual bool
ignoreUnsafeBufferInContainer(const SourceLocation &Loc) const = 0;

/// \return true iff unsafe libc call should NOT be reported at `Loc`
virtual bool
ignoreUnsafeBufferInLibcCall(const SourceLocation &Loc) const = 0;

virtual std::string
getUnsafeBufferUsageAttributeTextAt(SourceLocation Loc,
StringRef WSSuffix = "") const = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
#define WARNING_GADGET(name) GADGET(name)
#endif

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

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

#undef FIXABLE_GADGET
#undef WARNING_GADGET
#undef WARNING_CONTAINER_GADGET
#undef WARNING_OPTIONAL_GADGET
#undef GADGET
3 changes: 2 additions & 1 deletion clang/include/clang/Basic/DiagnosticGroups.td
Original file line number Diff line number Diff line change
Expand Up @@ -1558,7 +1558,8 @@ def ReadOnlyPlacementChecks : DiagGroup<"read-only-types">;

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

// Warnings and notes related to the function effects system underlying
// the nonblocking and nonallocating attributes.
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -12416,6 +12416,13 @@ def warn_unsafe_buffer_operation : Warning<
"unsafe buffer access|function introduces unsafe buffer manipulation|unsafe invocation of span::data|"
"field %1 prone to unsafe buffer manipulation}0">,
InGroup<UnsafeBufferUsage>, DefaultIgnore;
def warn_unsafe_buffer_libc_call : Warning<
"function %0 is unsafe">,
InGroup<UnsafeBufferUsageInLibcCall>, DefaultIgnore;
def note_unsafe_buffer_printf_call : Note<
"%select{|change to 'snprintf' for explicit bounds checking | buffer pointer and size may not match"
"|string argument is not guaranteed to be null-terminated"
"|'va_list' is unsafe}0">;
def note_unsafe_buffer_operation : Note<
"used%select{| in pointer arithmetic| in buffer access}0 here">;
def note_unsafe_buffer_variable_fixit_group : Note<
Expand Down
Loading

0 comments on commit d7dd2c4

Please sign in to comment.