Skip to content

Commit 150fc43

Browse files
committed
Merge commit 'refs/am/changes/f5816a32e3a418490689b48c3f02c101c35394b5_swift/master' into HEAD
Conflicts: lldb/source/DataFormatters/FormatManager.cpp lldb/source/DataFormatters/LanguageCategory.cpp
2 parents 181173c + f5816a3 commit 150fc43

File tree

31 files changed

+615
-270
lines changed

31 files changed

+615
-270
lines changed

clang/lib/StaticAnalyzer/Checkers/CStringChecker.cpp

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,9 @@ ProgramStateRef CStringChecker::checkNonNull(CheckerContext &C,
290290
SmallString<80> buf;
291291
llvm::raw_svector_ostream OS(buf);
292292
assert(CurrentFunctionDescription);
293-
OS << "Null pointer argument in call to " << CurrentFunctionDescription
294-
<< ' ' << IdxOfArg << llvm::getOrdinalSuffix(IdxOfArg)
295-
<< " parameter";
293+
OS << "Null pointer passed as " << IdxOfArg
294+
<< llvm::getOrdinalSuffix(IdxOfArg) << " argument to "
295+
<< CurrentFunctionDescription;
296296

297297
emitNullArgBug(C, stateNull, S, OS.str());
298298
}
@@ -1313,30 +1313,29 @@ void CStringChecker::evalMemcmp(CheckerContext &C, const CallExpr *CE) const {
13131313
ProgramStateRef StSameBuf, StNotSameBuf;
13141314
std::tie(StSameBuf, StNotSameBuf) = state->assume(SameBuf);
13151315

1316-
// If the two arguments might be the same buffer, we know the result is 0,
1316+
// If the two arguments are the same buffer, we know the result is 0,
13171317
// and we only need to check one size.
1318-
if (StSameBuf) {
1318+
if (StSameBuf && !StNotSameBuf) {
13191319
state = StSameBuf;
13201320
state = CheckBufferAccess(C, state, Size, Left);
13211321
if (state) {
13221322
state = StSameBuf->BindExpr(CE, LCtx,
13231323
svalBuilder.makeZeroVal(CE->getType()));
13241324
C.addTransition(state);
13251325
}
1326+
return;
13261327
}
13271328

1328-
// If the two arguments might be different buffers, we have to check the
1329-
// size of both of them.
1330-
if (StNotSameBuf) {
1331-
state = StNotSameBuf;
1332-
state = CheckBufferAccess(C, state, Size, Left, Right);
1333-
if (state) {
1334-
// The return value is the comparison result, which we don't know.
1335-
SVal CmpV = svalBuilder.conjureSymbolVal(nullptr, CE, LCtx,
1336-
C.blockCount());
1337-
state = state->BindExpr(CE, LCtx, CmpV);
1338-
C.addTransition(state);
1339-
}
1329+
// If the two arguments might be different buffers, we have to check
1330+
// the size of both of them.
1331+
assert(StNotSameBuf);
1332+
state = CheckBufferAccess(C, state, Size, Left, Right);
1333+
if (state) {
1334+
// The return value is the comparison result, which we don't know.
1335+
SVal CmpV =
1336+
svalBuilder.conjureSymbolVal(nullptr, CE, LCtx, C.blockCount());
1337+
state = state->BindExpr(CE, LCtx, CmpV);
1338+
C.addTransition(state);
13401339
}
13411340
}
13421341
}
@@ -1536,7 +1535,10 @@ void CStringChecker::evalStrcpyCommon(CheckerContext &C, const CallExpr *CE,
15361535
bool ReturnEnd, bool IsBounded,
15371536
ConcatFnKind appendK,
15381537
bool returnPtr) const {
1539-
CurrentFunctionDescription = "string copy function";
1538+
if (appendK == ConcatFnKind::none)
1539+
CurrentFunctionDescription = "string copy function";
1540+
else
1541+
CurrentFunctionDescription = "string concatenation function";
15401542
ProgramStateRef state = C.getState();
15411543
const LocationContext *LCtx = C.getLocationContext();
15421544

clang/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,7 +1078,10 @@ void EmptyLocalizationContextChecker::checkASTDecl(
10781078
AnalysisDeclContext *DCtx = Mgr.getAnalysisDeclContext(M);
10791079

10801080
const Stmt *Body = M->getBody();
1081-
assert(Body);
1081+
if (!Body) {
1082+
assert(M->isSynthesizedAccessorStub());
1083+
continue;
1084+
}
10821085

10831086
MethodCrawler MC(M->getCanonicalDecl(), BR, this, Mgr, DCtx);
10841087
MC.VisitStmt(Body);

clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class StreamChecker : public Checker<eval::Call,
6464

6565
CallDescriptionMap<FnCheck> Callbacks = {
6666
{{"fopen"}, &StreamChecker::evalFopen},
67+
{{"freopen", 3}, &StreamChecker::evalFreopen},
6768
{{"tmpfile"}, &StreamChecker::evalFopen},
6869
{{"fclose", 1}, &StreamChecker::evalFclose},
6970
{{"fread", 4},
@@ -90,6 +91,7 @@ class StreamChecker : public Checker<eval::Call,
9091
};
9192

9293
void evalFopen(const CallEvent &Call, CheckerContext &C) const;
94+
void evalFreopen(const CallEvent &Call, CheckerContext &C) const;
9395
void evalFclose(const CallEvent &Call, CheckerContext &C) const;
9496
void evalFseek(const CallEvent &Call, CheckerContext &C) const;
9597

@@ -160,6 +162,49 @@ void StreamChecker::evalFopen(const CallEvent &Call, CheckerContext &C) const {
160162
C.addTransition(stateNull);
161163
}
162164

165+
void StreamChecker::evalFreopen(const CallEvent &Call,
166+
CheckerContext &C) const {
167+
ProgramStateRef State = C.getState();
168+
169+
auto *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr());
170+
if (!CE)
171+
return;
172+
173+
Optional<DefinedSVal> StreamVal = Call.getArgSVal(2).getAs<DefinedSVal>();
174+
if (!StreamVal)
175+
return;
176+
// Do not allow NULL as passed stream pointer.
177+
// This is not specified in the man page but may crash on some system.
178+
checkNullStream(*StreamVal, C, State);
179+
// Check if error was generated.
180+
if (C.isDifferent())
181+
return;
182+
183+
SymbolRef StreamSym = StreamVal->getAsSymbol();
184+
// Do not care about special values for stream ("(FILE *)0x12345"?).
185+
if (!StreamSym)
186+
return;
187+
188+
// Generate state for non-failed case.
189+
// Return value is the passed stream pointer.
190+
// According to the documentations, the stream is closed first
191+
// but any close error is ignored. The state changes to (or remains) opened.
192+
ProgramStateRef StateRetNotNull =
193+
State->BindExpr(CE, C.getLocationContext(), *StreamVal);
194+
// Generate state for NULL return value.
195+
// Stream switches to OpenFailed state.
196+
ProgramStateRef StateRetNull = State->BindExpr(CE, C.getLocationContext(),
197+
C.getSValBuilder().makeNull());
198+
199+
StateRetNotNull =
200+
StateRetNotNull->set<StreamMap>(StreamSym, StreamState::getOpened());
201+
StateRetNull =
202+
StateRetNull->set<StreamMap>(StreamSym, StreamState::getOpenFailed());
203+
204+
C.addTransition(StateRetNotNull);
205+
C.addTransition(StateRetNull);
206+
}
207+
163208
void StreamChecker::evalFclose(const CallEvent &Call, CheckerContext &C) const {
164209
ProgramStateRef State = C.getState();
165210
if (checkDoubleClose(Call, C, State))

clang/lib/StaticAnalyzer/Core/RegionStore.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1951,7 +1951,8 @@ RegionStoreManager::getBindingForFieldOrElementCommon(RegionBindingsConstRef B,
19511951
if (hasSymbolicIndex)
19521952
return UnknownVal();
19531953

1954-
if (!hasPartialLazyBinding)
1954+
// Additionally allow introspection of a block's internal layout.
1955+
if (!hasPartialLazyBinding && !isa<BlockDataRegion>(R->getBaseRegion()))
19551956
return UndefinedVal();
19561957
}
19571958

clang/test/Analysis/blocks.m

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ - (id)initWithFormat:(NSString *)format arguments:(va_list)argList __attribute__
4747
aslclient asl_open(const char *ident, const char *facility, uint32_t opts);
4848
int asl_log(aslclient asl, aslmsg msg, int level, const char *format, ...) __attribute__((__format__ (__printf__, 4, 5)));
4949

50+
struct Block_layout {
51+
int flags;
52+
};
53+
5054
//===----------------------------------------------------------------------===//
5155
// Begin actual test cases.
5256
//===----------------------------------------------------------------------===//
@@ -241,3 +245,8 @@ void call_block_with_fewer_arguments() {
241245
b(); // expected-warning {{Block taking 1 argument is called with fewer (0)}}
242246
}
243247
#endif
248+
249+
int getBlockFlags() {
250+
int x = 0;
251+
return ((struct Block_layout *)^{ (void)x; })->flags; // no-warning
252+
}

clang/test/Analysis/bsd-string.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,11 @@ void f3() {
3333
}
3434

3535
void f4() {
36-
strlcpy(NULL, "abcdef", 6); // expected-warning{{Null pointer argument in call to string copy function}}
36+
strlcpy(NULL, "abcdef", 6); // expected-warning{{Null pointer passed as 1st argument to string copy function}}
3737
}
3838

3939
void f5() {
40-
strlcat(NULL, "abcdef", 6); // expected-warning{{Null pointer argument in call to string copy function}}
40+
strlcat(NULL, "abcdef", 6); // expected-warning{{Null pointer passed as 1st argument to string concatenation function}}
4141
}
4242

4343
void f6() {

clang/test/Analysis/bstring.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,12 @@ void memcpy9() {
148148

149149
void memcpy10() {
150150
char a[4] = {0};
151-
memcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
151+
memcpy(0, a, 4); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
152152
}
153153

154154
void memcpy11() {
155155
char a[4] = {0};
156-
memcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
156+
memcpy(a, 0, 4); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
157157
}
158158

159159
void memcpy12() {
@@ -173,7 +173,7 @@ void memcpy_unknown_size (size_t n) {
173173

174174
void memcpy_unknown_size_warn (size_t n) {
175175
char a[4];
176-
void *result = memcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
176+
void *result = memcpy(a, 0, n); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
177177
clang_analyzer_eval(result == a); // no-warning (above is fatal)
178178
}
179179

@@ -268,12 +268,12 @@ void mempcpy9() {
268268

269269
void mempcpy10() {
270270
char a[4] = {0};
271-
mempcpy(0, a, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
271+
mempcpy(0, a, 4); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
272272
}
273273

274274
void mempcpy11() {
275275
char a[4] = {0};
276-
mempcpy(a, 0, 4); // expected-warning{{Null pointer argument in call to memory copy function}}
276+
mempcpy(a, 0, 4); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
277277
}
278278

279279
void mempcpy12() {
@@ -327,7 +327,7 @@ void mempcpy16() {
327327

328328
void mempcpy_unknown_size_warn (size_t n) {
329329
char a[4];
330-
void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer argument in call to memory copy function}}
330+
void *result = mempcpy(a, 0, n); // expected-warning{{Null pointer passed as 2nd argument to memory copy function}}
331331
clang_analyzer_eval(result == a); // no-warning (above is fatal)
332332
}
333333

@@ -462,6 +462,12 @@ int memcmp7 (char *a, size_t x, size_t y, size_t n) {
462462
memcmp(&a[x*y], a, n);
463463
}
464464

465+
int memcmp8(char *a, size_t n) {
466+
char *b = 0;
467+
// Do not warn about the first argument!
468+
return memcmp(a, b, n); // expected-warning{{Null pointer passed as 2nd argument to memory comparison function}}
469+
}
470+
465471
//===----------------------------------------------------------------------===
466472
// bcopy()
467473
//===----------------------------------------------------------------------===

clang/test/Analysis/cstring-ranges.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
// This test verifies argument source range highlighting.
44
// Otherwise we've no idea which of the arguments is null.
5+
// These days we actually also have it in the message,
6+
// but the range is still great to have.
57

68
char *strcpy(char *, const char *);
79

@@ -10,6 +12,6 @@ void foo() {
1012
strcpy(a, b);
1113
}
1214

13-
// CHECK: warning: Null pointer argument in call to string copy function
15+
// CHECK: warning: Null pointer passed as 1st argument to string copy function
1416
// CHECK-NEXT: strcpy(a, b);
1517
// CHECK-NEXT: ^ ~

clang/test/Analysis/localization-aggressive.m

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,3 +293,11 @@ - (void)testTakesLocalizedString {
293293
takesLocalizedString(@"not localized"); // expected-warning {{User-facing text should use localized string macro}}
294294
}
295295
@end
296+
297+
@interface SynthesizedAccessors : NSObject
298+
@property (assign) NSObject *obj;
299+
@end
300+
301+
@implementation SynthesizedAccessors
302+
// no-crash
303+
@end

clang/test/Analysis/null-deref-path-notes.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,40 +13,40 @@ void *memcpy(void *dest, const void *src, unsigned long count);
1313

1414
void f1(char *source) {
1515
char *destination = 0; // expected-note{{'destination' initialized to a null pointer value}}
16-
memcpy(destination + 0, source, 10); // expected-warning{{Null pointer argument in call to memory copy function}}
17-
// expected-note@-1{{Null pointer argument in call to memory copy function}}
16+
memcpy(destination + 0, source, 10); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
17+
// expected-note@-1{{Null pointer passed as 1st argument to memory copy function}}
1818
}
1919

2020
void f2(char *source) {
2121
char *destination = 0; // expected-note{{'destination' initialized to a null pointer value}}
22-
memcpy(destination - 0, source, 10); // expected-warning{{Null pointer argument in call to memory copy function}}
23-
// expected-note@-1{{Null pointer argument in call to memory copy function}}
22+
memcpy(destination - 0, source, 10); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
23+
// expected-note@-1{{Null pointer passed as 1st argument to memory copy function}}
2424
}
2525

2626
void f3(char *source) {
2727
char *destination = 0; // expected-note{{'destination' initialized to a null pointer value}}
2828
destination = destination + 0; // expected-note{{Null pointer value stored to 'destination'}}
29-
memcpy(destination, source, 10); // expected-warning{{Null pointer argument in call to memory copy function}}
30-
// expected-note@-1{{Null pointer argument in call to memory copy function}}
29+
memcpy(destination, source, 10); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
30+
// expected-note@-1{{Null pointer passed as 1st argument to memory copy function}}
3131
}
3232

3333
void f4(char *source) {
3434
char *destination = 0; // expected-note{{'destination' initialized to a null pointer value}}
3535
destination = destination - 0; // expected-note{{Null pointer value stored to 'destination'}}
36-
memcpy(destination, source, 10); // expected-warning{{Null pointer argument in call to memory copy function}}
37-
// expected-note@-1{{Null pointer argument in call to memory copy function}}
36+
memcpy(destination, source, 10); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
37+
// expected-note@-1{{Null pointer passed as 1st argument to memory copy function}}
3838
}
3939

4040
void f5(char *source) {
4141
char *destination1 = 0; // expected-note{{'destination1' initialized to a null pointer value}}
4242
char *destination2 = destination1 + 0; // expected-note{{'destination2' initialized to a null pointer value}}
43-
memcpy(destination2, source, 10); // expected-warning{{Null pointer argument in call to memory copy function}}
44-
// expected-note@-1{{Null pointer argument in call to memory copy function}}
43+
memcpy(destination2, source, 10); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
44+
// expected-note@-1{{Null pointer passed as 1st argument to memory copy function}}
4545
}
4646

4747
void f6(char *source) {
4848
char *destination1 = 0; // expected-note{{'destination1' initialized to a null pointer value}}
4949
char *destination2 = destination1 - 0; // expected-note{{'destination2' initialized to a null pointer value}}
50-
memcpy(destination2, source, 10); // expected-warning{{Null pointer argument in call to memory copy function}}
51-
// expected-note@-1{{Null pointer argument in call to memory copy function}}
50+
memcpy(destination2, source, 10); // expected-warning{{Null pointer passed as 1st argument to memory copy function}}
51+
// expected-note@-1{{Null pointer passed as 1st argument to memory copy function}}
5252
}

clang/test/Analysis/null-deref-ps-region.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ void bar() {
3939

4040
void testConcreteNull() {
4141
int *x = 0;
42-
memset(x, 0, 1); // expected-warning {{Null pointer argument in call to memory set function}}
42+
memset(x, 0, 1); // expected-warning {{Null pointer passed as 1st argument to memory set function}}
4343
}
4444

4545
void testStackArray() {

0 commit comments

Comments
 (0)