Skip to content

[alpha.webkit.UncountedCallArgsChecker] os_log functions should be treated as safe. #131500

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,14 @@ bool isPtrConversion(const FunctionDecl *F) {
return false;
}

bool isTrivialBuiltinFunction(const FunctionDecl *F) {
if (!F || !F->getDeclName().isIdentifier())
return false;
auto Name = F->getName();
return Name.starts_with("__builtin") || Name == "__libcpp_verbose_abort" ||
Name.starts_with("os_log") || Name.starts_with("_os_log");
}

bool isSingleton(const FunctionDecl *F) {
assert(F);
// FIXME: check # of params == 1
Expand Down Expand Up @@ -601,8 +609,7 @@ class TrivialFunctionAnalysisVisitor
Name == "isMainThreadOrGCThread" || Name == "isMainRunLoop" ||
Name == "isWebThread" || Name == "isUIThread" ||
Name == "mayBeGCThread" || Name == "compilerFenceForCrash" ||
Name == "bitwise_cast" || Name.find("__builtin") == 0 ||
Name == "__libcpp_verbose_abort")
Name == "bitwise_cast" || isTrivialBuiltinFunction(Callee))
return true;

return IsFunctionTrivial(Callee);
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ std::optional<bool> isGetterOfSafePtr(const clang::CXXMethodDecl *Method);
/// pointer types.
bool isPtrConversion(const FunctionDecl *F);

/// \returns true if \p F is a builtin function which is considered trivial.
bool isTrivialBuiltinFunction(const FunctionDecl *F);

/// \returns true if \p F is a static singleton function.
bool isSingleton(const FunctionDecl *F);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ class RawPtrRefCallArgsChecker
if (Callee && TFA.isTrivial(Callee) && !Callee->isVirtualAsWritten())
return true;

if (isTrivialBuiltinFunction(Callee))
return true;

if (CE->getNumArgs() == 0)
return false;

Expand Down
2 changes: 1 addition & 1 deletion clang/test/Analysis/Checkers/WebKit/mock-system-header.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ enum os_log_type_t : uint8_t {

typedef struct os_log_s *os_log_t;
os_log_t os_log_create(const char *subsystem, const char *category);
void os_log_msg(os_log_t oslog, os_log_type_t type, const char *msg);
void os_log_msg(os_log_t oslog, os_log_type_t type, const char *msg, ...);
6 changes: 5 additions & 1 deletion clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -695,9 +695,13 @@ RefPtr<RefCounted> object();
void someFunction(const RefCounted&);

void test2() {
someFunction(*object());
someFunction(*object());
}

void system_header() {
callMethod<RefCountable>(object);
}

void log(RefCountable* obj) {
os_log_msg(os_log_create("WebKit", "DOM"), OS_LOG_TYPE_INFO, "obj: %p next: %p", obj, obj->next());
}
4 changes: 4 additions & 0 deletions clang/test/Analysis/Checkers/WebKit/uncounted-obj-arg.mm
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,7 @@ @interface WrapperObj : NSObject
static void foo(WrapperObj *configuration) {
configuration._protectedWebExtensionControllerConfiguration->copy();
}

void log(RefCountable* obj) {
os_log_msg(os_log_create("WebKit", "DOM"), OS_LOG_TYPE_INFO, "obj: %p next: %p", obj, obj->next());
}