diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-08-18 22:48:41 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-08-18 22:48:41 +0000 |
commit | 8f7462237ff542a4556775f98709ed300aa1731a (patch) | |
tree | da743fcb3ca3b9493028eb0bae288da319cc70ac | |
parent | 8e6431adab313e283a992698f6fc7afe62420999 (diff) |
Enhance -Wstrl-incorrect-size to not report a FIXIT for destinations that are flexible arrays or have size 1.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138004 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 28 | ||||
-rw-r--r-- | test/Sema/warn-strlcpycat-size.c | 27 |
2 files changed, 45 insertions, 10 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 882668e515..82c97a63cd 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2071,18 +2071,26 @@ void Sema::CheckStrlcpycatArguments(const CallExpr *Call, // pointers if we know the actual size, like if DstArg is 'array+2' // we could say 'sizeof(array)-2'. const Expr *DstArg = Call->getArg(0)->IgnoreParenImpCasts(); + QualType DstArgTy = DstArg->getType(); - if (DstArg->getType()->isArrayType()) { - llvm::SmallString<128> sizeString; - llvm::raw_svector_ostream OS(sizeString); - OS << "sizeof("; - DstArg->printPretty(OS, Context, 0, Context.PrintingPolicy); - OS << ")"; - - Diag(OriginalSizeArg->getLocStart(), diag::note_strlcpycat_wrong_size) - << FixItHint::CreateReplacement(OriginalSizeArg->getSourceRange(), - OS.str()); + // Only handle constant-sized or VLAs, but not flexible members. + if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(DstArgTy)) { + // Only issue the FIXIT for arrays of size > 1. + if (CAT->getSize().getSExtValue() <= 1) + return; + } else if (!DstArgTy->isVariableArrayType()) { + return; } + + llvm::SmallString<128> sizeString; + llvm::raw_svector_ostream OS(sizeString); + OS << "sizeof("; + DstArg->printPretty(OS, Context, 0, Context.PrintingPolicy); + OS << ")"; + + Diag(OriginalSizeArg->getLocStart(), diag::note_strlcpycat_wrong_size) + << FixItHint::CreateReplacement(OriginalSizeArg->getSourceRange(), + OS.str()); } //===--- CHECK: Return Address of Stack Variable --------------------------===// diff --git a/test/Sema/warn-strlcpycat-size.c b/test/Sema/warn-strlcpycat-size.c index e9e617488c..34830120d5 100644 --- a/test/Sema/warn-strlcpycat-size.c +++ b/test/Sema/warn-strlcpycat-size.c @@ -26,3 +26,30 @@ void f(void) strlcpy((*s5)->f2[x], s2, sizeof(s2)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} expected-note {{change size argument to be the size of the destination}} strlcpy(s1+3, s2, sizeof(s2)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} } + +// Don't issue FIXIT for flexible arrays. +struct S { + int y; + char x[]; +}; + +void flexible_arrays(struct S *s) { + char str[] = "hi"; + strlcpy(s->x, str, sizeof(str)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} +} + +// Don't issue FIXIT for destinations of size 1. +void size_1() { + char z[1]; + char str[] = "hi"; + + strlcpy(z, str, sizeof(str)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} +} + +// Support VLAs. +void vlas(int size) { + char z[size]; + char str[] = "hi"; + + strlcpy(z, str, sizeof(str)); // expected-warning {{size argument in 'strlcpy' call appears to be size of the source; expected the size of the destination}} expected-note {{change size argument to be the size of the destination}} +} |