]> granicus.if.org Git - clang/commitdiff
implement -Wformat-security properly, which is enabled by default.
authorChris Lattner <sabre@nondot.org>
Wed, 29 Apr 2009 04:59:47 +0000 (04:59 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 29 Apr 2009 04:59:47 +0000 (04:59 +0000)
This enables one specific class of non-literal format warnings.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70368 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticGroups.td
include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaChecking.cpp
test/Sema/format-strings.c

index e0d33e2d2453e649b6c41ec1b4a3998d18e66c86..be35943a12d567587b765e2ef40347e218e092c6 100644 (file)
@@ -35,8 +35,8 @@ def ExtraTokens : DiagGroup<"extra-tokens">;
 def FormatExtraArgs : DiagGroup<"format-extra-args">;
 
 def Format : DiagGroup<"format", [FormatExtraArgs]>;
-def FormatNonLiteral : DiagGroup<"format-nonliteral", [Format]>;
 def FormatSecurity : DiagGroup<"format-security", [Format]>;
+def FormatNonLiteral : DiagGroup<"format-nonliteral", [FormatSecurity]>;
 def FormatY2K : DiagGroup<"format-y2k", [Format]>;
 def Format2 : DiagGroup<"format=2",
                         [FormatNonLiteral, FormatSecurity, FormatY2K]>;
index 536fd01d9154f9a04cb4375c54e11f85b5413c0c..6fcdff96e0dda51cf83cf4bbbdf74d3fdbef3ace 100644 (file)
@@ -1057,8 +1057,11 @@ def err_builtin_direct_init_more_than_one_arg : Error<
   "initializer of a builtin type can only take one argument">;
 def err_value_init_for_array_type : Error<
   "array types cannot be value-initialized">;
-def warn_printf_not_string_constant : Warning<
+def warn_printf_nonliteral_noargs : Warning<
   "format string is not a string literal (potentially insecure)">,
+  InGroup<FormatSecurity>;
+def warn_printf_nonliteral : Warning<
+  "format string is not a string literal">,
   InGroup<FormatNonLiteral>, DefaultIgnore;
 
 def err_unexpected_interface : Error<
index d355ba4e992c9ad84d26fe20df29e42d929e9790..3e46300b604de31d25229eebd1a83e03c7bc4858 100644 (file)
@@ -604,9 +604,16 @@ Sema::CheckPrintfArguments(const CallExpr *TheCall, bool HasVAListArg,
       if (isa<ParmVarDecl>(DR->getDecl()))
         return;
 
-  Diag(TheCall->getArg(format_idx)->getLocStart(), 
-       diag::warn_printf_not_string_constant)
-       << OrigFormatExpr->getSourceRange();
+  // If there are no arguments specified, warn with -Wformat-security, otherwise
+  // warn only with -Wformat-nonliteral.
+  if (TheCall->getNumArgs() == format_idx+1)
+    Diag(TheCall->getArg(format_idx)->getLocStart(), 
+         diag::warn_printf_nonliteral_noargs)
+      << OrigFormatExpr->getSourceRange();
+  else
+    Diag(TheCall->getArg(format_idx)->getLocStart(), 
+         diag::warn_printf_nonliteral)
+           << OrigFormatExpr->getSourceRange();
 }
 
 void Sema::CheckPrintfString(const StringLiteral *FExpr,
index c7392c1f0c9368762fe560bee344aae72f5ded9e..50903b0cf83673e0c08bfefaca3da1fed12a1b34 100644 (file)
@@ -113,3 +113,15 @@ void test_constant_bindings(void) {
   printf(s4); // expected-warning{{not a string literal}}
   printf(s5); // expected-warning{{not a string literal}}
 }
+
+
+// Test what happens when -Wformat-security only.
+#pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#pragma GCC diagnostic warning "-Wformat-security"
+
+void test9(char *P) {
+  int x;
+  printf(P);   // expected-warning {{format string is not a string literal (potentially insecure)}}
+  printf(P, 42);
+  printf("%n", &x); // expected-warning {{use of '%n' in format string discouraged }}
+}