#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;
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<BugType> &BT,
const ParmVarDecl *ParamDecl) const;
BT.reset(new BuiltinBug(this, desc));
}
bool uninitRefOrPointer(CheckerContext &C, const SVal &V,
- SourceRange ArgRange,
- const Expr *ArgEx, std::unique_ptr<BugType> &BT,
- const ParmVarDecl *ParamDecl, const char *BD) const;
+ SourceRange ArgRange, const Expr *ArgEx,
+ std::unique_ptr<BugType> &BT,
+ const ParmVarDecl *ParamDecl, const char *BD,
+ int ArgumentNumber) const;
};
} // end anonymous namespace
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<ObjCMethodCall>(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<BugType> &BT,
- const ParmVarDecl *ParamDecl,
- const char *BD) const {
+bool CallAndMessageChecker::uninitRefOrPointer(
+ CheckerContext &C, const SVal &V, SourceRange ArgRange, const Expr *ArgEx,
+ std::unique_ptr<BugType> &BT, const ParmVarDecl *ParamDecl, const char *BD,
+ int ArgumentNumber) const {
if (!Filter.Check_CallAndMessageUnInitRefArg)
return false;
// 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;
if (PSV.isUndef()) {
if (ExplodedNode *N = C.generateErrorNode()) {
LazyInit_BT(BD, BT);
- auto R = llvm::make_unique<BugReport>(*BT, Message, N);
+ auto R = llvm::make_unique<BugReport>(*BT, Os.str(), N);
R->addRange(ArgRange);
if (ArgEx) {
bugreporter::trackNullOrUndefValue(N, ArgEx, *R);
SVal V,
SourceRange ArgRange,
const Expr *ArgEx,
- bool IsFirstArgument,
+ int ArgumentNumber,
bool CheckUninitFields,
const CallEvent &Call,
std::unique_ptr<BugType> &BT,
) 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<BugReport>(*BT, Desc, N);
+ SmallString<200> Buf;
+ llvm::raw_svector_ostream Os(Buf);
+ describeUninitializedArgumentInCall(Call, ArgumentNumber, Os);
+ auto R = llvm::make_unique<BugReport>(*BT, Os.str(), N);
+
R->addRange(ArgRange);
if (ArgEx)
bugreporter::trackNullOrUndefValue(N, ArgEx, *R);
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;
}
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() {
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
// CHECK-NEXT: </array>
// CHECK-NEXT: <key>depth</key><integer>0</integer>
// CHECK-NEXT: <key>extended_message</key>
-// CHECK-NEXT: <string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT: <string>1st function call argument is an uninitialized value</string>
// CHECK-NEXT: <key>message</key>
-// CHECK-NEXT: <string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT: <string>1st function call argument is an uninitialized value</string>
// CHECK-NEXT: </dict>
// CHECK-NEXT: </array>
-// CHECK-NEXT: <key>description</key><string>Function call argument is an uninitialized value</string>
+// CHECK-NEXT: <key>description</key><string>1st function call argument is an uninitialized value</string>
// CHECK-NEXT: <key>category</key><string>Logic error</string>
// CHECK-NEXT: <key>type</key><string>Uninitialized argument value</string>
// CHECK-NEXT: <key>check_name</key><string>core.CallAndMessage</string>
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);
}
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}}
}
//===----------------------------------------------------------------------===//
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);
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 {}
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}}
}
//===----------------------------------------------------------------------===//
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
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()) {
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}}
}
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;
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) {
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) {
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;
}
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
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
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
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}}
}
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_) {}
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}}
}
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) {
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}}
}
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}}
}
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() {
// 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
}
}