Skip to content

Commit f3564d2

Browse files
committed
Feedback fixes
Refactor `isNonNull` parsing and add C++ test for GNU `__null`
1 parent e04ef6b commit f3564d2

File tree

5 files changed

+71
-41
lines changed

5 files changed

+71
-41
lines changed

clang/include/clang/Basic/Builtins.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -392,9 +392,9 @@ class Context {
392392
bool performsCallback(unsigned ID,
393393
llvm::SmallVectorImpl<int> &Encoding) const;
394394

395-
/// Return true if this builtin has parameters at fixed positions
396-
/// that must be non-null.
397-
bool IsNonNull(unsigned ID, llvm::SmallVectorImpl<int> &Indxs) const;
395+
/// Return true if this builtin has parameters that must be non-null.
396+
/// The parameter indices are appended into 'Indxs'.
397+
bool isNonNull(unsigned ID, llvm::SmallVectorImpl<int> &Indxs) const;
398398

399399
/// Return true if this function has no side effects and doesn't
400400
/// read memory, except for possibly errno or raising FP exceptions.

clang/lib/Basic/Builtins.cpp

Lines changed: 21 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -293,22 +293,15 @@ bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
293293
return isLike(ID, FormatIdx, HasVAListArg, "sS");
294294
}
295295

296-
bool Builtin::Context::IsNonNull(unsigned ID,
297-
llvm::SmallVectorImpl<int> &Indxs) const {
298-
299-
const char *CalleePos = ::strchr(getAttributesString(ID), 'N');
300-
if (!CalleePos)
301-
return false;
302-
303-
++CalleePos;
304-
assert(*CalleePos == '<' &&
305-
"Callback callee specifier must be followed by a '<'");
306-
++CalleePos;
296+
static void parseCommaSeparatedIndices(const char *CurrPos,
297+
llvm::SmallVectorImpl<int> &Indxs) {
298+
assert(*CurrPos == '<' && "Expected '<' to start index list");
299+
++CurrPos;
307300

308301
char *EndPos;
309-
int CalleeIdx = ::strtol(CalleePos, &EndPos, 10);
310-
assert(CalleeIdx >= 0 && "Callee index is supposed to be positive!");
311-
Indxs.push_back(CalleeIdx);
302+
int PosIdx = ::strtol(CurrPos, &EndPos, 10);
303+
assert(PosIdx >= 0 && "Index is supposed to be positive!");
304+
Indxs.push_back(PosIdx);
312305

313306
while (*EndPos == ',') {
314307
const char *PayloadPos = EndPos + 1;
@@ -317,7 +310,19 @@ bool Builtin::Context::IsNonNull(unsigned ID,
317310
Indxs.push_back(PayloadIdx);
318311
}
319312

320-
assert(*EndPos == '>' && "Callback callee specifier must end with a '>'");
313+
assert(*EndPos == '>' && "Index list must end with '>'");
314+
}
315+
316+
bool Builtin::Context::isNonNull(unsigned ID,
317+
llvm::SmallVectorImpl<int> &Indxs) const {
318+
319+
const char *AttrPos = ::strchr(getAttributesString(ID), 'N');
320+
if (!AttrPos)
321+
return false;
322+
323+
++AttrPos;
324+
parseCommaSeparatedIndices(AttrPos, Indxs);
325+
321326
return true;
322327
}
323328

@@ -328,23 +333,8 @@ bool Builtin::Context::performsCallback(unsigned ID,
328333
return false;
329334

330335
++CalleePos;
331-
assert(*CalleePos == '<' &&
332-
"Callback callee specifier must be followed by a '<'");
333-
++CalleePos;
334-
335-
char *EndPos;
336-
int CalleeIdx = ::strtol(CalleePos, &EndPos, 10);
337-
assert(CalleeIdx >= 0 && "Callee index is supposed to be positive!");
338-
Encoding.push_back(CalleeIdx);
339-
340-
while (*EndPos == ',') {
341-
const char *PayloadPos = EndPos + 1;
342-
343-
int PayloadIdx = ::strtol(PayloadPos, &EndPos, 10);
344-
Encoding.push_back(PayloadIdx);
345-
}
336+
parseCommaSeparatedIndices(CalleePos, Encoding);
346337

347-
assert(*EndPos == '>' && "Callback callee specifier must end with a '>'");
348338
return true;
349339
}
350340

clang/lib/Sema/SemaDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17142,7 +17142,7 @@ void Sema::AddKnownFunctionAttributes(FunctionDecl *FD) {
1714217142
}
1714317143

1714417144
SmallVector<int, 4> Indxs;
17145-
if (Context.BuiltinInfo.IsNonNull(BuiltinID, Indxs) &&
17145+
if (Context.BuiltinInfo.isNonNull(BuiltinID, Indxs) &&
1714617146
!FD->hasAttr<NonNullAttr>()) {
1714717147
llvm::SmallVector<ParamIdx, 4> ParamIndxs;
1714817148
for (int I : Indxs)

clang/test/Sema/format-strings-nonnull.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
// RUN: %clang_cc1 -fsyntax-only -verify -Wnonnull -Wno-format-security %s
1+
// RUN: %clang_cc1 -fsyntax-only --std=c23 -verify -Wnonnull -Wno-format-security %s
22

3-
#include <stdarg.h>
4-
#include <stddef.h>
3+
#define NULL (void*)0
54

65
typedef struct _FILE FILE;
7-
6+
typedef __SIZE_TYPE__ size_t;
7+
typedef __builtin_va_list va_list;
88
int printf(char const* restrict, ...);
99
int __builtin_printf(char const* restrict, ...);
1010
int fprintf(FILE* restrict, char const* restrict, ...);
@@ -48,7 +48,7 @@ void check_format_string(FILE *fp, va_list ap) {
4848
vfprintf(fp, 0, ap);
4949
// expected-warning@-1{{null passed to a callee that requires a non-null argument}}
5050

51-
vsprintf(buf, NULL, ap);
51+
vsprintf(buf, nullptr, ap);
5252
// expected-warning@-1{{null passed to a callee that requires a non-null argument}}
5353

5454
vsnprintf(buf, 10, fmt, ap);
@@ -57,7 +57,7 @@ void check_format_string(FILE *fp, va_list ap) {
5757
scanf(NULL);
5858
// expected-warning@-1{{null passed to a callee that requires a non-null argument}}
5959

60-
fscanf(fp, NULL);
60+
fscanf(fp, nullptr);
6161
// expected-warning@-1{{null passed to a callee that requires a non-null argument}}
6262

6363
sscanf(buf, fmt);
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// RUN: %clang_cc1 -fsyntax-only -verify -Wnonnull %s
2+
3+
#ifdef __cplusplus
4+
# define EXTERN_C extern "C"
5+
#else
6+
# define EXTERN_C extern
7+
#endif
8+
9+
typedef struct _FILE FILE;
10+
typedef __SIZE_TYPE__ size_t;
11+
typedef __builtin_va_list va_list;
12+
13+
EXTERN_C int printf(const char *, ...);
14+
EXTERN_C int fprintf(FILE *, const char *restrict, ...);
15+
EXTERN_C int sprintf(char* restrict, char const* res, ...);
16+
17+
EXTERN_C int scanf(char const *restrict, ...);
18+
EXTERN_C int fscanf(FILE* restrict, char const* res, ...);
19+
20+
void test(FILE *fp) {
21+
char buf[256];
22+
23+
__builtin_printf(__null, "x");
24+
// expected-warning@-1 {{null passed to a callee that requires a non-null argument}}
25+
26+
printf(__null, "xxd");
27+
// expected-warning@-1 {{null passed to a callee that requires a non-null argument}}
28+
29+
fprintf(fp, __null, 42);
30+
// expected-warning@-1 {{null passed to a callee that requires a non-null argument}}
31+
32+
sprintf(buf, __null);
33+
// expected-warning@-1 {{null passed to a callee that requires a non-null argument}}
34+
35+
scanf(__null);
36+
// expected-warning@-1 {{null passed to a callee that requires a non-null argument}}
37+
38+
fscanf(fp, __null);
39+
// expected-warning@-1 {{null passed to a callee that requires a non-null argument}}
40+
}

0 commit comments

Comments
 (0)