diff options
-rw-r--r-- | clang/include/clang/AST/FormatString.h | 8 | ||||
-rw-r--r-- | clang/include/clang/AST/OSLog.h | 8 | ||||
-rw-r--r-- | clang/lib/AST/OSLog.cpp | 4 | ||||
-rw-r--r-- | clang/lib/AST/PrintfFormatString.cpp | 12 | ||||
-rw-r--r-- | clang/test/CodeGen/builtins.c | 7 |
5 files changed, 33 insertions, 6 deletions
diff --git a/clang/include/clang/AST/FormatString.h b/clang/include/clang/AST/FormatString.h index 598d341ac82..39eb6258a61 100644 --- a/clang/include/clang/AST/FormatString.h +++ b/clang/include/clang/AST/FormatString.h @@ -475,13 +475,15 @@ class PrintfSpecifier : public analyze_format_string::FormatSpecifier { OptionalFlag HasObjCTechnicalTerm; // '[tt]' OptionalFlag IsPrivate; // '{private}' OptionalFlag IsPublic; // '{public}' + OptionalFlag IsSensitive; // '{sensitive}' OptionalAmount Precision; public: PrintfSpecifier() : FormatSpecifier(/* isPrintf = */ true), HasThousandsGrouping("'"), IsLeftJustified("-"), HasPlusPrefix("+"), HasSpacePrefix(" "), HasAlternativeForm("#"), HasLeadingZeroes("0"), - HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public") {} + HasObjCTechnicalTerm("tt"), IsPrivate("private"), IsPublic("public"), + IsSensitive("sensitive") {} static PrintfSpecifier Parse(const char *beg, const char *end); @@ -512,6 +514,9 @@ public: } void setIsPrivate(const char *position) { IsPrivate.setPosition(position); } void setIsPublic(const char *position) { IsPublic.setPosition(position); } + void setIsSensitive(const char *position) { + IsSensitive.setPosition(position); + } void setUsesPositionalArg() { UsesPositionalArg = true; } // Methods for querying the format specifier. @@ -551,6 +556,7 @@ public: const OptionalFlag &hasObjCTechnicalTerm() const { return HasObjCTechnicalTerm; } const OptionalFlag &isPrivate() const { return IsPrivate; } const OptionalFlag &isPublic() const { return IsPublic; } + const OptionalFlag &isSensitive() const { return IsSensitive; } bool usesPositionalArg() const { return UsesPositionalArg; } /// Changes the specifier and length according to a QualType, retaining any diff --git a/clang/include/clang/AST/OSLog.h b/clang/include/clang/AST/OSLog.h index 41e5c5a9ced..c8895156d0b 100644 --- a/clang/include/clang/AST/OSLog.h +++ b/clang/include/clang/AST/OSLog.h @@ -60,7 +60,10 @@ public: IsPrivate = 0x1, // The item is marked "public" in the format string. - IsPublic = 0x2 + IsPublic = 0x2, + + // The item is marked "sensitive" in the format string. + IsSensitive = 0x4 | IsPrivate }; private: @@ -73,7 +76,8 @@ private: public: OSLogBufferItem(Kind kind, const Expr *expr, CharUnits size, unsigned flags) : TheKind(kind), TheExpr(expr), Size(size), Flags(flags) { - assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic)) && + assert(((Flags == 0) || (Flags == IsPrivate) || (Flags == IsPublic) || + (Flags == IsSensitive)) && "unexpected privacy flag"); } diff --git a/clang/lib/AST/OSLog.cpp b/clang/lib/AST/OSLog.cpp index 9124fd58a05..d70aa605182 100644 --- a/clang/lib/AST/OSLog.cpp +++ b/clang/lib/AST/OSLog.cpp @@ -120,7 +120,9 @@ public: ArgsData.back().FieldWidth = Args[FS.getFieldWidth().getArgIndex()]; } - if (FS.isPrivate()) + if (FS.isSensitive()) + ArgsData.back().Flags |= OSLogBufferItem::IsSensitive; + else if (FS.isPrivate()) ArgsData.back().Flags |= OSLogBufferItem::IsPrivate; else if (FS.isPublic()) ArgsData.back().Flags |= OSLogBufferItem::IsPublic; diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp index 71c28de99c9..a92375b4528 100644 --- a/clang/lib/AST/PrintfFormatString.cpp +++ b/clang/lib/AST/PrintfFormatString.cpp @@ -127,7 +127,8 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, do { StringRef Str(I, E - I); - std::string Match = "^[[:space:]]*(private|public)[[:space:]]*(,|})"; + std::string Match = "^[[:space:]]*(private|public|sensitive)" + "[[:space:]]*(,|})"; llvm::Regex R(Match); SmallVector<StringRef, 2> Matches; @@ -138,7 +139,11 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, // Set the privacy flag if the privacy annotation in the // comma-delimited segment is at least as strict as the privacy // annotations in previous comma-delimited segments. - if (MatchedStr.equals("private")) + if (MatchedStr.equals("sensitive")) + PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsSensitive; + else if (PrivacyFlags != + clang::analyze_os_log::OSLogBufferItem::IsSensitive && + MatchedStr.equals("private")) PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPrivate; else if (PrivacyFlags == 0 && MatchedStr.equals("public")) PrivacyFlags = clang::analyze_os_log::OSLogBufferItem::IsPublic; @@ -168,6 +173,9 @@ static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H, case clang::analyze_os_log::OSLogBufferItem::IsPublic: FS.setIsPublic(MatchedStr.data()); break; + case clang::analyze_os_log::OSLogBufferItem::IsSensitive: + FS.setIsSensitive(MatchedStr.data()); + break; default: llvm_unreachable("Unexpected privacy flag value"); } diff --git a/clang/test/CodeGen/builtins.c b/clang/test/CodeGen/builtins.c index 829f725617f..40d7ca32d77 100644 --- a/clang/test/CodeGen/builtins.c +++ b/clang/test/CodeGen/builtins.c @@ -443,10 +443,17 @@ void test_builtin_os_log(void *buf, int i, const char *data) { // CHECK: call void @__os_log_helper_1_3_1_8_33( __builtin_os_log_format(buf, "%{ xyz, private }s", "abc"); + // CHECK: call void @__os_log_helper_1_3_1_8_37( + __builtin_os_log_format(buf, "%{ xyz, sensitive }s", "abc"); + // The strictest privacy annotation in the string wins. // CHECK: call void @__os_log_helper_1_3_1_8_33( __builtin_os_log_format(buf, "%{ private, public, private, public}s", "abc"); + + // CHECK: call void @__os_log_helper_1_3_1_8_37( + __builtin_os_log_format(buf, "%{ private, sensitive, private, public}s", + "abc"); } // CHECK-LABEL: define linkonce_odr hidden void @__os_log_helper_1_3_4_4_0_8_34_4_17_8_49 |