]> granicus.if.org Git - clang/commitdiff
Enhance -Wstrl-incorrect-size to not report a FIXIT for destinations that are flexibl...
authorTed Kremenek <kremenek@apple.com>
Thu, 18 Aug 2011 22:48:41 +0000 (22:48 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 18 Aug 2011 22:48:41 +0000 (22:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@138004 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaChecking.cpp
test/Sema/warn-strlcpycat-size.c

index 882668e515165784a9ba8b581356cee59f008b2e..82c97a63cdb14bce9b0adb1eec3963ff8f7713b8 100644 (file)
@@ -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 --------------------------===//
index e9e617488c4b1613c454b16f50715d7a08d21f9a..34830120d5d7ad06d848dd791a8f024f84602843 100644 (file)
@@ -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}}
+}