summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/PrintfFormatString.cpp
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2014-09-09 23:10:54 +0000
committerFariborz Jahanian <fjahanian@apple.com>2014-09-09 23:10:54 +0000
commit6485fe4b07b0ea3003b727729ee8f0b8867e0381 (patch)
treebd4486bd8e1d8173443f97eda5c39dfb74835e3a /clang/lib/Analysis/PrintfFormatString.cpp
parentdeb174fed5f86357c52c62d214e64deff446fc01 (diff)
downloadbcm5719-llvm-6485fe4b07b0ea3003b727729ee8f0b8867e0381.tar.gz
bcm5719-llvm-6485fe4b07b0ea3003b727729ee8f0b8867e0381.zip
Objective-C. Under a special flag, -Wcstring-format-directive,
off by default, issue a warning if %s directive is used in certain CF/NS formatting APIs, to assist user in deprecating use of such %s in these APIs. rdar://18182443 llvm-svn: 217467
Diffstat (limited to 'clang/lib/Analysis/PrintfFormatString.cpp')
-rw-r--r--clang/lib/Analysis/PrintfFormatString.cpp54
1 files changed, 45 insertions, 9 deletions
diff --git a/clang/lib/Analysis/PrintfFormatString.cpp b/clang/lib/Analysis/PrintfFormatString.cpp
index c6453b66549..146635b8870 100644
--- a/clang/lib/Analysis/PrintfFormatString.cpp
+++ b/clang/lib/Analysis/PrintfFormatString.cpp
@@ -54,7 +54,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
const char *E,
unsigned &argIndex,
const LangOptions &LO,
- const TargetInfo &Target) {
+ const TargetInfo &Target,
+ bool Warn) {
using namespace clang::analyze_format_string;
using namespace clang::analyze_printf;
@@ -83,7 +84,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
if (I == E) {
// No more characters left?
- H.HandleIncompleteSpecifier(Start, E - Start);
+ if (Warn)
+ H.HandleIncompleteSpecifier(Start, E - Start);
return true;
}
@@ -93,7 +95,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
if (I == E) {
// No more characters left?
- H.HandleIncompleteSpecifier(Start, E - Start);
+ if (Warn)
+ H.HandleIncompleteSpecifier(Start, E - Start);
return true;
}
@@ -118,7 +121,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
if (I == E) {
// No more characters left?
- H.HandleIncompleteSpecifier(Start, E - Start);
+ if (Warn)
+ H.HandleIncompleteSpecifier(Start, E - Start);
return true;
}
@@ -129,7 +133,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
if (I == E) {
// No more characters left?
- H.HandleIncompleteSpecifier(Start, E - Start);
+ if (Warn)
+ H.HandleIncompleteSpecifier(Start, E - Start);
return true;
}
@@ -137,7 +142,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
if (*I == '.') {
++I;
if (I == E) {
- H.HandleIncompleteSpecifier(Start, E - Start);
+ if (Warn)
+ H.HandleIncompleteSpecifier(Start, E - Start);
return true;
}
@@ -147,7 +153,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
if (I == E) {
// No more characters left?
- H.HandleIncompleteSpecifier(Start, E - Start);
+ if (Warn)
+ H.HandleIncompleteSpecifier(Start, E - Start);
return true;
}
}
@@ -155,7 +162,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
// Look for the length modifier.
if (ParseLengthModifier(FS, I, E, LO) && I == E) {
// No more characters left?
- H.HandleIncompleteSpecifier(Start, E - Start);
+ if (Warn)
+ H.HandleIncompleteSpecifier(Start, E - Start);
return true;
}
@@ -239,7 +247,7 @@ bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
// Keep looking for a format specifier until we have exhausted the string.
while (I != E) {
const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
- LO, Target);
+ LO, Target, true);
// Did a fail-stop error of any kind occur when parsing the specifier?
// If so, don't do any more processing.
if (FSR.shouldStop())
@@ -257,6 +265,34 @@ bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
return false;
}
+bool clang::analyze_format_string::ParseFormatStringHasSArg(const char *I,
+ const char *E,
+ const LangOptions &LO,
+ const TargetInfo &Target) {
+
+ unsigned argIndex = 0;
+
+ // Keep looking for a %s format specifier until we have exhausted the string.
+ FormatStringHandler H;
+ while (I != E) {
+ const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
+ LO, Target, false);
+ // Did a fail-stop error of any kind occur when parsing the specifier?
+ // If so, don't do any more processing.
+ if (FSR.shouldStop())
+ return false;
+ // Did we exhaust the string or encounter an error that
+ // we can recover from?
+ if (!FSR.hasValue())
+ continue;
+ const analyze_printf::PrintfSpecifier &FS = FSR.getValue();
+ // Return true if this a %s format specifier.
+ if (FS.getConversionSpecifier().getKind() == ConversionSpecifier::Kind::sArg)
+ return true;
+ }
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Methods on PrintfSpecifier.
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud