Skip to content

Commit 2dfaf28

Browse files
committed
Remove BINJI_HACK workarounds for WASI nullability issues
This commit removes all BINJI_HACK workarounds that were added to suppress nullability warnings in WASI/POSIX code. These workarounds are no longer needed as we now build for standard Linux/macOS targets with full POSIX support, rather than WASI which has limited platform APIs. Key changes: - Removed WASIStubs.cpp entirely (no longer needed) - Cleaned up nullability suppressions in Unix/*.inc platform files - Removed workarounds from threading primitives (Mutex, RWMutex, ThreadPool, Parallel) - Simplified raw_socket_stream.cpp by removing WASI-specific code paths - Removed cmake workarounds for atomic and compiler version checks - Updated .gitignore to exclude .o files - Cleaned up nullsafe-headers README to focus on core functionality The codebase now builds cleanly with strict nullability checking enabled. Tests pass: clang/test/Sema/strict-nullability.c ✓
1 parent b5ec04b commit 2dfaf28

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+45
-713
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,5 @@ pythonenv*
7878
/clang/utils/analyzer/projects/*/RefScanBuildResults
7979
# automodapi puts generated documentation files here.
8080
/lldb/docs/python_api/
81+
**/.claude/settings.local.json
82+
*.o

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Null pointer dereferences are just one category of memory safety bugs. Here's ho
5050
5151
### Why This Still Matters
5252
53-
While Null-Safe C doesn't solve all memory safety issues, null pointer dereferences are a significant problem:
53+
While Null-Safe Clang doesn't solve all memory safety issues, null pointer dereferences are a significant problem:
5454
5555
- One in four memory safety bugs involve null pointer dereferences ([Microsoft Security Response Center](https://github.com/microsoft/MSRC-Security-Research/blob/master/papers/2019/The%20Memory%20Safety%20Story.pdf))
5656
- Zero runtime overhead - nullability checks are compile-time only, no runtime checks inserted

clang/include/clang/Basic/ParsedAttrInfo.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,9 +177,7 @@ const std::list<std::unique_ptr<ParsedAttrInfo>> &getAttributePluginInstances();
177177
} // namespace clang
178178

179179
namespace llvm {
180-
#ifndef BINJI_HACK
181180
extern template class CLANG_TEMPLATE_ABI Registry<clang::ParsedAttrInfo>;
182-
#endif
183181
} // namespace llvm
184182

185183
#endif // LLVM_CLANG_BASIC_PARSEDATTRINFO_H

clang/lib/Frontend/ModuleDependencyCollector.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ void ModuleDependencyCollector::attachToPreprocessor(Preprocessor &PP) {
9292
}
9393

9494
static bool isCaseSensitivePath(llvm::vfs::FileSystem &VFS, StringRef Path) {
95-
#ifndef BINJI_HACK
9695
SmallString<256> TmpDest = Path, UpperDest, RealDest;
9796
// Remove component traversals, links, etc.
9897
if (VFS.getRealPath(Path, TmpDest))
@@ -108,10 +107,6 @@ static bool isCaseSensitivePath(llvm::vfs::FileSystem &VFS, StringRef Path) {
108107
if (!VFS.getRealPath(UpperDest, RealDest) && Path == RealDest)
109108
return false;
110109
return true;
111-
#else
112-
// BINJI_HACK: WASI VFS doesn't support getRealPath, assume case sensitive
113-
return true;
114-
#endif
115110
}
116111

117112
void ModuleDependencyCollector::writeFileMap() {

clang/lib/Frontend/PrecompiledPreamble.cpp

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,7 @@ class TemporaryFiles {
159159
void removeFile(StringRef File);
160160

161161
private:
162-
#ifndef BINJI_HACK
163162
std::mutex Mutex;
164-
#endif
165163
llvm::StringSet<> Files;
166164
};
167165

@@ -171,26 +169,20 @@ TemporaryFiles &TemporaryFiles::getInstance() {
171169
}
172170

173171
TemporaryFiles::~TemporaryFiles() {
174-
#ifndef BINJI_HACK
175172
std::lock_guard<std::mutex> Guard(Mutex);
176-
#endif
177173
for (const auto &File : Files)
178174
llvm::sys::fs::remove(File.getKey());
179175
}
180176

181177
void TemporaryFiles::addFile(StringRef File) {
182-
#ifndef BINJI_HACK
183178
std::lock_guard<std::mutex> Guard(Mutex);
184-
#endif
185179
auto IsInserted = Files.insert(File).second;
186180
(void)IsInserted;
187181
assert(IsInserted && "File has already been added");
188182
}
189183

190184
void TemporaryFiles::removeFile(StringRef File) {
191-
#ifndef BINJI_HACK
192185
std::lock_guard<std::mutex> Guard(Mutex);
193-
#endif
194186
auto WasPresent = Files.erase(File);
195187
(void)WasPresent;
196188
assert(WasPresent && "File was not tracked");

clang/nullsafe-headers/README.md

Lines changed: 10 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Null-Safe C Standard Library Headers
22

3-
Nullability-annotated C standard library headers using Clang's `_Nonnull` and `_Nullable` attributes.
3+
Nullability-annotated C standard library headers for use with Null-Safe Clang. Uses Clang's `_Nonnull` and `_Nullable` attributes to catch null pointer dereferences at compile time.
44

55
## Quick Start
66

@@ -21,7 +21,7 @@ void example(const char* input) {
2121
2222
Compile:
2323
```bash
24-
clang -I/path/to/nullsafe-headers/include mycode.c
24+
clang -Iclang/nullsafe-headers/include mycode.c
2525
```
2626

2727
## What's Included
@@ -38,7 +38,7 @@ clang -I/path/to/nullsafe-headers/include mycode.c
3838
void process_data(size_t size) {
3939
char* buffer = malloc(size); // Returns _Nullable
4040

41-
// ERROR with cbang - buffer might be NULL
41+
// ERROR - buffer might be NULL
4242
buffer[0] = 'x';
4343

4444
// CORRECT - check first
@@ -53,7 +53,7 @@ void process_data(size_t size) {
5353
5454
```c
5555
void safe_copy(char* dest, const char* src) {
56-
// ERROR with cbang - both might be NULL, but strcpy requires _Nonnull
56+
// ERROR - both might be NULL, but strcpy requires _Nonnull
5757
strcpy(dest, src);
5858
5959
// CORRECT
@@ -69,7 +69,7 @@ void safe_copy(char* dest, const char* src) {
6969
void read_config(const char* filename) {
7070
FILE* fp = fopen(filename, "r"); // Returns _Nullable
7171

72-
// ERROR with cbang - fp might be NULL
72+
// ERROR - fp might be NULL
7373
char buf[100];
7474
fgets(buf, sizeof(buf), fp);
7575

@@ -83,94 +83,18 @@ void read_config(const char* filename) {
8383
}
8484
```
8585
86-
### Search Functions
87-
88-
```c
89-
void find_and_replace(char* str, char old, char new) {
90-
char* pos = strchr(str, old); // Returns _Nullable
91-
92-
// ERROR with cbang - pos might be NULL
93-
*pos = new;
94-
95-
// CORRECT
96-
while (pos) {
97-
*pos = new;
98-
pos = strchr(pos + 1, old);
99-
}
100-
}
101-
```
102-
103-
## Build System Integration
104-
105-
**Makefile:**
106-
```makefile
107-
CFLAGS += -I$(LLVM_PROJECT)/clang/nullsafe-headers/include
108-
```
109-
110-
**CMake:**
111-
```cmake
112-
include_directories(${LLVM_PROJECT}/clang/nullsafe-headers/include)
113-
```
114-
115-
## Annotating Third-Party Libraries
116-
117-
Want null-safe headers for other libraries? Here's how:
118-
119-
### Popular Libraries to Annotate
120-
121-
- **OpenSSL** - Crypto functions (many return NULL on error)
122-
- **zlib** - Compression (gzopen returns NULL on failure)
123-
- **libcurl** - HTTP client (curl_easy_init returns NULL on failure)
124-
- **SQLite** - Database (sqlite3_open returns status, but many functions return NULL)
125-
- **libpng/libjpeg** - Image processing (create functions return NULL)
126-
- **POSIX** - pthread, socket APIs (many nullable returns)
127-
128-
### How to Annotate
129-
130-
1. **Start with a wrapper header:**
131-
```c
132-
/*
133-
* curl_nullsafe.h - Null-safe libcurl wrapper
134-
*/
135-
#ifndef CURL_NULLSAFE_H
136-
#define CURL_NULLSAFE_H
137-
138-
#include <curl/curl.h>
139-
140-
/* Override key functions with annotations */
141-
CURL* _Nullable curl_easy_init(void);
142-
CURLcode curl_easy_setopt(CURL* _Nonnull handle, CURLoption option, ...);
143-
void curl_easy_cleanup(CURL* _Nullable handle);
144-
char* _Nullable curl_easy_escape(CURL* _Nonnull handle,
145-
const char* _Nonnull string,
146-
int length);
147-
148-
#endif
149-
```
150-
151-
2. **Focus on common patterns:**
152-
- Constructor functions → usually return `_Nullable`
153-
- Destructor/cleanup functions → usually accept `_Nullable`
154-
- Getters that can fail → return `_Nullable`
155-
- Required parameters → mark `_Nonnull`
156-
157-
3. **Test against real usage:**
158-
```bash
159-
clang -I. -include curl_nullsafe.h mycode.c
160-
```
161-
16286
## FAQ
16387
164-
**Q: Does this require cbang?**
165-
A: No. Works with any Clang. cbang provides better flow-sensitive analysis.
88+
**Q: Does this require Null-Safe Clang?**
89+
A: No. Works with any Clang. Null-Safe Clang provides better flow-sensitive analysis.
16690
16791
**Q: Do I need to recompile libc?**
16892
A: No. These are just declarations; links to system libc.
16993
17094
**Q: What about third-party libraries?**
17195
A: Use `-isystem` to suppress warnings:
17296
```bash
173-
clang -I./nullsafe-headers/include -isystem /usr/include/python3.9 mycode.c
97+
clang -Inullsafe-headers/include -isystem /usr/include/python3.9 mycode.c
17498
```
17599

176100
**Q: Performance overhead?**
@@ -181,9 +105,8 @@ A: Zero. All checks are compile-time only.
181105
Guidelines for adding annotations:
182106
1. Mark `_Nonnull` only when NULL causes undefined behavior
183107
2. Mark `_Nullable` when NULL is explicitly allowed as input
184-
3. Unmarked return types default to `_Nullable` (conservative)
108+
3. Return types default to `_Nullable` (conservative)
185109
4. Test against real libc to verify correctness
186110

187-
## License
111+
See the [main README](../../README.md) for more information about Null-Safe Clang.
188112

189-
Apache 2.0 with LLVM exceptions (same as LLVM/Clang).

direct_deref.o

-1.12 KB
Binary file not shown.

exact_cjson.o

-1.14 KB
Binary file not shown.

exact_pattern.o

-1.1 KB
Binary file not shown.

llvm/cmake/modules/CheckAtomic.cmake

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
5555
if (NOT HAVE_CXX_ATOMICS_WITH_LIB)
5656
message(FATAL_ERROR "Host compiler must support std::atomic!")
5757
endif()
58-
elseif(EMSCRIPTEN)
59-
# BINJI_HACK: Emscripten provides atomics via JS polyfills, skip check
60-
set(HAVE_CXX_ATOMICS_WITH_LIB TRUE)
6158
else()
6259
message(FATAL_ERROR "Host compiler appears to require libatomic, but cannot find it.")
6360
endif()
@@ -79,9 +76,6 @@ elseif(LLVM_COMPILER_IS_GCC_COMPATIBLE OR CMAKE_CXX_COMPILER_ID MATCHES "XL")
7976
if (NOT HAVE_CXX_ATOMICS64_WITH_LIB)
8077
message(FATAL_ERROR "Host compiler must support 64-bit std::atomic!")
8178
endif()
82-
elseif(EMSCRIPTEN)
83-
# BINJI_HACK: Emscripten provides atomics via JS polyfills, skip check
84-
set(HAVE_CXX_ATOMICS64_WITH_LIB TRUE)
8579
else()
8680
message(FATAL_ERROR "Host compiler appears to require libatomic for 64-bit operations, but cannot find it.")
8781
endif()

0 commit comments

Comments
 (0)