Index: lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp +++ lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp @@ -21,6 +21,7 @@ #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/Support/raw_ostream.h" using namespace clang; @@ -71,7 +72,7 @@ private: bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange, - const Expr *ArgEx, bool IsFirstArgument, + const Expr *ArgEx, int ArgumentNumber, bool CheckUninitFields, const CallEvent &Call, std::unique_ptr &BT, const ParmVarDecl *ParamDecl) const; @@ -89,9 +90,10 @@ BT.reset(new BuiltinBug(this, desc)); } bool uninitRefOrPointer(CheckerContext &C, const SVal &V, - SourceRange ArgRange, - const Expr *ArgEx, std::unique_ptr &BT, - const ParmVarDecl *ParamDecl, const char *BD) const; + SourceRange ArgRange, const Expr *ArgEx, + std::unique_ptr &BT, + const ParmVarDecl *ParamDecl, const char *BD, + int ArgumentNumber) const; }; } // end anonymous namespace @@ -111,38 +113,45 @@ C.emitReport(std::move(R)); } -static StringRef describeUninitializedArgumentInCall(const CallEvent &Call, - bool IsFirstArgument) { +static void describeUninitializedArgumentInCall(const CallEvent &Call, + int ArgumentNumber, + llvm::raw_svector_ostream &Os) { switch (Call.getKind()) { case CE_ObjCMessage: { const ObjCMethodCall &Msg = cast(Call); switch (Msg.getMessageKind()) { case OCM_Message: - return "Argument in message expression is an uninitialized value"; + Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1) + << " argument in message expression is an uninitialized value"; + return; case OCM_PropertyAccess: assert(Msg.isSetter() && "Getters have no args"); - return "Argument for property setter is an uninitialized value"; + Os << "Argument for property setter is an uninitialized value"; + return; case OCM_Subscript: - if (Msg.isSetter() && IsFirstArgument) - return "Argument for subscript setter is an uninitialized value"; - return "Subscript index is an uninitialized value"; + if (Msg.isSetter() && (ArgumentNumber == 0)) + Os << "Argument for subscript setter is an uninitialized value"; + else + Os << "Subscript index is an uninitialized value"; + return; } llvm_unreachable("Unknown message kind."); } case CE_Block: - return "Block call argument is an uninitialized value"; + Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1) + << " block call argument is an uninitialized value"; + return; default: - return "Function call argument is an uninitialized value"; + Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1) + << " function call argument is an uninitialized value"; + return; } } -bool CallAndMessageChecker::uninitRefOrPointer(CheckerContext &C, - const SVal &V, - SourceRange ArgRange, - const Expr *ArgEx, - std::unique_ptr &BT, - const ParmVarDecl *ParamDecl, - const char *BD) const { +bool CallAndMessageChecker::uninitRefOrPointer( + CheckerContext &C, const SVal &V, SourceRange ArgRange, const Expr *ArgEx, + std::unique_ptr &BT, const ParmVarDecl *ParamDecl, const char *BD, + int ArgumentNumber) const { if (!Filter.Check_CallAndMessageUnInitRefArg) return false; @@ -153,12 +162,15 @@ // If parameter is declared as pointer to const in function declaration, // then check if corresponding argument in function call is // pointing to undefined symbol value (uninitialized memory). - StringRef Message; + SmallString<200> Buf; + llvm::raw_svector_ostream Os(Buf); if (ParamDecl->getType()->isPointerType()) { - Message = "Function call argument is a pointer to uninitialized value"; + Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1) + << " function call argument is a pointer to uninitialized value"; } else if (ParamDecl->getType()->isReferenceType()) { - Message = "Function call argument is an uninitialized value"; + Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1) + << " function call argument is an uninitialized value"; } else return false; @@ -171,7 +183,7 @@ if (PSV.isUndef()) { if (ExplodedNode *N = C.generateErrorNode()) { LazyInit_BT(BD, BT); - auto R = llvm::make_unique(*BT, Message, N); + auto R = llvm::make_unique(*BT, Os.str(), N); R->addRange(ArgRange); if (ArgEx) { bugreporter::trackNullOrUndefValue(N, ArgEx, *R); @@ -188,7 +200,7 @@ SVal V, SourceRange ArgRange, const Expr *ArgEx, - bool IsFirstArgument, + int ArgumentNumber, bool CheckUninitFields, const CallEvent &Call, std::unique_ptr &BT, @@ -196,17 +208,19 @@ ) const { const char *BD = "Uninitialized argument value"; - if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD)) + if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD, + ArgumentNumber)) return true; if (V.isUndef()) { if (ExplodedNode *N = C.generateErrorNode()) { LazyInit_BT(BD, BT); - // Generate a report for this bug. - StringRef Desc = - describeUninitializedArgumentInCall(Call, IsFirstArgument); - auto R = llvm::make_unique(*BT, Desc, N); + SmallString<200> Buf; + llvm::raw_svector_ostream Os(Buf); + describeUninitializedArgumentInCall(Call, ArgumentNumber, Os); + auto R = llvm::make_unique(*BT, Os.str(), N); + R->addRange(ArgRange); if (ArgEx) bugreporter::trackNullOrUndefValue(N, ArgEx, *R); @@ -435,7 +449,7 @@ if(FD && i < FD->getNumParams()) ParamDecl = FD->getParamDecl(i); if (PreVisitProcessArg(C, Call.getArgSVal(i), Call.getArgSourceRange(i), - Call.getArgExpr(i), /*IsFirstArgument=*/i == 0, + Call.getArgExpr(i), i, checkUninitFields, Call, *BT, ParamDecl)) return; } Index: test/Analysis/NewDelete-checker-test.cpp =================================================================== --- test/Analysis/NewDelete-checker-test.cpp +++ test/Analysis/NewDelete-checker-test.cpp @@ -244,7 +244,7 @@ void testUninitFree() { int *x; - free(x); // expected-warning{{Function call argument is an uninitialized value}} + free(x); // expected-warning{{1st function call argument is an uninitialized value}} } void testUninitDeleteSink() { Index: test/Analysis/diagnostics/undef-value-param.m =================================================================== --- test/Analysis/diagnostics/undef-value-param.m +++ test/Analysis/diagnostics/undef-value-param.m @@ -45,8 +45,8 @@ CreateRefUndef(&storeRef, 4); //expected-note@-1{{Calling 'CreateRefUndef'}} //expected-note@-2{{Returning from 'CreateRefUndef'}} - CFRelease(storeRef); //expected-warning {{Function call argument is an uninitialized value}} - //expected-note@-1{{Function call argument is an uninitialized value}} + CFRelease(storeRef); //expected-warning {{1st function call argument is an uninitialized value}} + //expected-note@-1{{1st function call argument is an uninitialized value}} } @end @@ -918,12 +918,12 @@ // CHECK-NEXT: // CHECK-NEXT: depth0 // CHECK-NEXT: extended_message -// CHECK-NEXT: Function call argument is an uninitialized value +// CHECK-NEXT: 1st function call argument is an uninitialized value // CHECK-NEXT: message -// CHECK-NEXT: Function call argument is an uninitialized value +// CHECK-NEXT: 1st function call argument is an uninitialized value // CHECK-NEXT: // CHECK-NEXT: -// CHECK-NEXT: descriptionFunction call argument is an uninitialized value +// CHECK-NEXT: description1st function call argument is an uninitialized value // CHECK-NEXT: categoryLogic error // CHECK-NEXT: typeUninitialized argument value // CHECK-NEXT: check_namecore.CallAndMessage Index: test/Analysis/malloc.m =================================================================== --- test/Analysis/malloc.m +++ test/Analysis/malloc.m @@ -29,7 +29,7 @@ if (error != ((void*)0)) return error; - rdar10579586(buffer->str_c); // expected-warning {{Function call argument is an uninitialized value}} + rdar10579586(buffer->str_c); // expected-warning {{1st function call argument is an uninitialized value}} free(buffer); return ((void*)0); } Index: test/Analysis/misc-ps-region-store.m =================================================================== --- test/Analysis/misc-ps-region-store.m +++ test/Analysis/misc-ps-region-store.m @@ -396,7 +396,7 @@ int rdar_7332673_test2_aux(char *x); void rdar_7332673_test2() { char *value; - if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Function call argument is an uninitialized value}} + if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{1st function call argument is an uninitialized value}} } //===----------------------------------------------------------------------===// @@ -673,7 +673,7 @@ builder = ^(id object) { id x; if (object) { - builder(x); // expected-warning{{Block call argument is an uninitialized value}} + builder(x); // expected-warning{{1st block call argument is an uninitialized value}} } }; builder(target); Index: test/Analysis/misc-ps.m =================================================================== --- test/Analysis/misc-ps.m +++ test/Analysis/misc-ps.m @@ -796,7 +796,7 @@ void test_bad_call_aux(int x); void test_bad_call(void) { int y; - test_bad_call_aux(y); // expected-warning{{Function call argument is an uninitialized value}} + test_bad_call_aux(y); // expected-warning{{1st function call argument is an uninitialized value}} } @interface TestBadArg {} @@ -805,7 +805,7 @@ void test_bad_msg(TestBadArg *p) { int y; - [p testBadArg:y]; // expected-warning{{Argument in message expression is an uninitialized value}} + [p testBadArg:y]; // expected-warning{{1st argument in message expression is an uninitialized value}} } //===----------------------------------------------------------------------===// Index: test/Analysis/null-deref-ps.c =================================================================== --- test/Analysis/null-deref-ps.c +++ test/Analysis/null-deref-ps.c @@ -286,7 +286,7 @@ void pr4759() { int *p; - pr4759_aux(p); // expected-warning{{Function call argument is an uninitialized value}} + pr4759_aux(p); // expected-warning{{1st function call argument is an uninitialized value}} } // Relax function call arguments invalidation to be aware of const Index: test/Analysis/nullptr.cpp =================================================================== --- test/Analysis/nullptr.cpp +++ test/Analysis/nullptr.cpp @@ -107,7 +107,7 @@ void shouldNotCrash() { decltype(nullptr) p; if (getSymbol()) - invokeF(p); // expected-warning{{Function call argument is an uninit}} + invokeF(p); // expected-warning{{1st function call argument is an uninit}} if (getSymbol()) invokeF(nullptr); if (getSymbol()) { Index: test/Analysis/uninit-const.c =================================================================== --- test/Analysis/uninit-const.c +++ test/Analysis/uninit-const.c @@ -24,16 +24,16 @@ void f_1(void) { int t; int* tp = &t; // expected-note {{'tp' initialized here}} - doStuff_pointerToConstInt(tp); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_1_1(void) { int t; int* tp1 = &t; int* tp2 = tp1; // expected-note {{'tp2' initialized here}} - doStuff_pointerToConstInt(tp2); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(tp2); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } @@ -45,8 +45,8 @@ int t; int* p = f_2_sub(&t); int* tp = p; // expected-note {{'tp' initialized here}} - doStuff_pointerToConstInt(tp); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } int z; @@ -62,14 +62,14 @@ void f_5(void) { int ta[5]; int* tp = ta; // expected-note {{'tp' initialized here}} - doStuff_pointerToConstInt(tp); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_5_1(void) { int ta[5]; // expected-note {{'ta' initialized here}} - doStuff_pointerToConstInt(ta); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(ta); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_6(void) { @@ -92,27 +92,27 @@ void f_8(void) { int g; // expected-note {{'g' declared without an initial value}} - doStuff2(g); // expected-warning {{Function call argument is an uninitialized value}} - // expected-note@-1 {{Function call argument is an uninitialized value}} + doStuff2(g); // expected-warning {{1st function call argument is an uninitialized value}} + // expected-note@-1 {{1st function call argument is an uninitialized value}} } void f_9(void) { int a[6]; int const *ptau = a; // expected-note {{'ptau' initialized here}} - doStuff_arrayOfConstInt(ptau); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_arrayOfConstInt(ptau); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_10(void) { int a[6]; // expected-note {{'a' initialized here}} - doStuff_arrayOfConstInt(a); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_arrayOfConstInt(a); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_11(void) { int t[10]; //expected-note {{'t' initialized here}} - doStuff_constStaticSizedArray(t); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_constStaticSizedArray(t); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f_12(void) { @@ -126,8 +126,8 @@ ptr = (int *)malloc(sizeof(int)); // expected-note {{Value assigned to 'ptr'}} - doStuff_pointerToConstInt(ptr); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_pointerToConstInt(ptr); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} free(ptr); return 0; } @@ -148,16 +148,16 @@ int t; int v; int* tp = &t; // expected-note {{'tp' initialized here}} - doStuff_variadic(tp,v); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_variadic(tp,v); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } // uninit pointer, init val void f_variadic_unp_inv(void) { int t; int v = 3; int* tp = &t; // expected-note {{'tp' initialized here}} - doStuff_variadic(tp,v); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_variadic(tp,v); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } // init pointer, uninit val @@ -165,8 +165,8 @@ int t=5; int v; // expected-note {{'v' declared without an initial value}} int* tp = &t; - doStuff_variadic(tp,v);// expected-warning {{Function call argument is an uninitialized value}} - // expected-note@-1 {{Function call argument is an uninitialized value}} + doStuff_variadic(tp,v);// expected-warning {{2nd function call argument is an uninitialized value}} + // expected-note@-1 {{2nd function call argument is an uninitialized value}} } // init pointer, init val @@ -192,8 +192,8 @@ int u=3; int *vp = &u ; int *tp = &t; // expected-note {{'tp' initialized here}} - doStuff_variadic(tp,vp); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_variadic(tp,vp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } //init pointer, uninit pointer @@ -211,6 +211,6 @@ int u; int *vp = &u ; int *tp = &t; // expected-note {{'tp' initialized here}} - doStuff_variadic(tp,vp); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_variadic(tp,vp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } Index: test/Analysis/uninit-const.cpp =================================================================== --- test/Analysis/uninit-const.cpp +++ test/Analysis/uninit-const.cpp @@ -66,8 +66,8 @@ int &p = t; int &s = p; int &q = s; //expected-note {{'q' initialized here}} - doStuff6(q); //expected-warning {{Function call argument is an uninitialized value}} - //expected-note@-1 {{Function call argument is an uninitialized value}} + doStuff6(q); //expected-warning {{1st function call argument is an uninitialized value}} + //expected-note@-1 {{1st function call argument is an uninitialized value}} } void doStuff6_3(int& q_, int *ptr_) {} @@ -78,15 +78,15 @@ int &p = t; int &s = p; int &q = s; - doStuff6_3(q,ptr); //expected-warning {{Function call argument is an uninitialized value}} - //expected-note@-1 {{Function call argument is an uninitialized value}} + doStuff6_3(q,ptr); //expected-warning {{2nd function call argument is an uninitialized value}} + //expected-note@-1 {{2nd function call argument is an uninitialized value}} } void f6(void) { int k; // expected-note {{'k' declared without an initial value}} - doStuff6(k); // expected-warning {{Function call argument is an uninitialized value}} - // expected-note@-1 {{Function call argument is an uninitialized value}} + doStuff6(k); // expected-warning {{1st function call argument is an uninitialized value}} + // expected-note@-1 {{1st function call argument is an uninitialized value}} } @@ -95,15 +95,15 @@ void f5(void) { int t; int* tp = &t; // expected-note {{'tp' initialized here}} - doStuff_uninit(tp); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_uninit(tp); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } void f4(void) { int y; // expected-note {{'y' declared without an initial value}} - doStuff4(y); // expected-warning {{Function call argument is an uninitialized value}} - // expected-note@-1 {{Function call argument is an uninitialized value}} + doStuff4(y); // expected-warning {{1st function call argument is an uninitialized value}} + // expected-note@-1 {{1st function call argument is an uninitialized value}} } void f3(void) { @@ -123,6 +123,6 @@ void f_uninit(void) { int x; - doStuff_uninit(&x); // expected-warning {{Function call argument is a pointer to uninitialized value}} - // expected-note@-1 {{Function call argument is a pointer to uninitialized value}} + doStuff_uninit(&x); // expected-warning {{1st function call argument is a pointer to uninitialized value}} + // expected-note@-1 {{1st function call argument is a pointer to uninitialized value}} } Index: test/Analysis/uninit-msg-expr.m =================================================================== --- test/Analysis/uninit-msg-expr.m +++ test/Analysis/uninit-msg-expr.m @@ -52,5 +52,5 @@ void f3() { NSMutableArray *aArray = [NSArray array]; NSString *aString; - [aArray addObject:aString]; // expected-warning {{Argument in message expression is an uninitialized value}} + [aArray addObject:aString]; // expected-warning {{1st argument in message expression is an uninitialized value}} } Index: test/Analysis/uninit-vals-ps.c =================================================================== --- test/Analysis/uninit-vals-ps.c +++ test/Analysis/uninit-vals-ps.c @@ -14,7 +14,7 @@ int f1_b() { int x; - return bar(x)+1; // expected-warning{{Function call argument is an uninitialized value}} + return bar(x)+1; // expected-warning{{1st function call argument is an uninitialized value}} } int f2() { Index: test/Analysis/uninit-vals.cpp =================================================================== --- test/Analysis/uninit-vals.cpp +++ test/Analysis/uninit-vals.cpp @@ -27,7 +27,7 @@ // case with undefined values, too. c1.b.a = c2->b.a; #else - c1.b.a = c2->b.a; // expected-warning{{Function call argument is an uninitialized value}} + c1.b.a = c2->b.a; // expected-warning{{1st function call argument is an uninitialized value}} #endif } }