summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaChecking.cpp30
-rw-r--r--clang/test/Sema/format-strings-fixit.c6
-rw-r--r--clang/test/SemaObjC/format-strings-objc-fixit.m31
3 files changed, 58 insertions, 9 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index eb5b5890495..966d3493926 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -3621,20 +3621,32 @@ bool Sema::CheckFormatArguments(ArrayRef<const Expr *> Args,
// format is either NSString or CFString. This is a hack to prevent
// diag when using the NSLocalizedString and CFCopyLocalizedString macros
// which are usually used in place of NS and CF string literals.
- if (Type == FST_NSString &&
- SourceMgr.isInSystemMacro(Args[format_idx]->getLocStart()))
+ SourceLocation FormatLoc = Args[format_idx]->getLocStart();
+ if (Type == FST_NSString && SourceMgr.isInSystemMacro(FormatLoc))
return false;
// If there are no arguments specified, warn with -Wformat-security, otherwise
// warn only with -Wformat-nonliteral.
- if (Args.size() == firstDataArg)
- Diag(Args[format_idx]->getLocStart(),
- diag::warn_format_nonliteral_noargs)
+ if (Args.size() == firstDataArg) {
+ const SemaDiagnosticBuilder &D =
+ Diag(FormatLoc, diag::warn_format_nonliteral_noargs);
+ switch (Type) {
+ default:
+ D << OrigFormatExpr->getSourceRange();
+ break;
+ case FST_Kprintf:
+ case FST_FreeBSDKPrintf:
+ case FST_Printf:
+ D << FixItHint::CreateInsertion(FormatLoc, "\"%s\", ");
+ break;
+ case FST_NSString:
+ D << FixItHint::CreateInsertion(FormatLoc, "@\"%@\", ");
+ break;
+ }
+ } else {
+ Diag(FormatLoc, diag::warn_format_nonliteral)
<< OrigFormatExpr->getSourceRange();
- else
- Diag(Args[format_idx]->getLocStart(),
- diag::warn_format_nonliteral)
- << OrigFormatExpr->getSourceRange();
+ }
return false;
}
diff --git a/clang/test/Sema/format-strings-fixit.c b/clang/test/Sema/format-strings-fixit.c
index b982eb45e5f..fb617dd500f 100644
--- a/clang/test/Sema/format-strings-fixit.c
+++ b/clang/test/Sema/format-strings-fixit.c
@@ -16,6 +16,8 @@ typedef __UINTMAX_TYPE__ uintmax_t;
typedef __PTRDIFF_TYPE__ ptrdiff_t;
typedef __WCHAR_TYPE__ wchar_t;
+extern const char *NonliteralString;
+
void test() {
// Basic types
printf("%s", (int) 123);
@@ -94,6 +96,9 @@ void test() {
printf("%G", (long double) 42);
printf("%a", (long double) 42);
printf("%A", (long double) 42);
+
+ // nonliteral format
+ printf(NonliteralString);
}
int scanf(char const *, ...);
@@ -218,6 +223,7 @@ void test2(int intSAParm[static 2]) {
// CHECK: printf("%LG", (long double) 42);
// CHECK: printf("%La", (long double) 42);
// CHECK: printf("%LA", (long double) 42);
+// CHECK: printf("%s", NonliteralString);
// CHECK: scanf("%99s", str);
// CHECK: scanf("%s", vstr);
diff --git a/clang/test/SemaObjC/format-strings-objc-fixit.m b/clang/test/SemaObjC/format-strings-objc-fixit.m
new file mode 100644
index 00000000000..feaebeec57f
--- /dev/null
+++ b/clang/test/SemaObjC/format-strings-objc-fixit.m
@@ -0,0 +1,31 @@
+// RUN: cp %s %t
+// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin -Wno-objc-root-class -pedantic -Wall -fixit %t
+// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin -Wno-objc-root-class -fsyntax-only -pedantic -Wall -Werror %t
+// RUN: %clang_cc1 -x objective-c -triple x86_64-apple-darwin -Wno-objc-root-class -E -o - %t | FileCheck %s
+
+typedef signed char BOOL;
+typedef unsigned int NSUInteger;
+typedef struct _NSZone NSZone;
+@class NSCoder, NSString, NSEnumerator;
+@protocol NSObject - (BOOL)isEqual:(id)object; @end
+@protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end
+@protocol NSMutableCopying - (id)mutableCopyWithZone:(NSZone *)zone; @end
+@protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end
+@interface NSObject <NSObject> {} @end
+@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding> - (NSUInteger)length; @end
+extern void NSLog(NSString *format, ...);
+
+/* This is a test of the various code modification hints that are
+ provided as part of warning or extension diagnostics. All of the
+ warnings will be fixed by -fixit, and the resulting file should
+ compile cleanly with -Werror -pedantic. */
+
+extern NSString *NonliteralString;
+
+void test() {
+ // nonliteral format
+ NSLog(NonliteralString);
+}
+
+// Validate the fixes.
+// CHECK: NSLog(@"%@", NonliteralString);
OpenPOWER on IntegriCloud