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);
}
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.
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
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:
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");
}
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;
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;
// 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;
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");
}
// 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