Skip to content

Commit

Permalink
Revert "[APINotes] Add support for bounds safety annotations"
Browse files Browse the repository at this point in the history
  • Loading branch information
hnrklssn committed Jan 30, 2025
1 parent 6a23220 commit 95b1930
Show file tree
Hide file tree
Showing 20 changed files with 102 additions and 1,081 deletions.
82 changes: 2 additions & 80 deletions clang/include/clang/APINotes/Types.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,72 +300,6 @@ inline bool operator!=(const ContextInfo &LHS, const ContextInfo &RHS) {
return !(LHS == RHS);
}

/* TO_UPSTREAM(BoundsSafety) ON */
class BoundsSafetyInfo {
public:
enum class BoundsSafetyKind {
CountedBy = 0,
CountedByOrNull,
SizedBy,
SizedByOrNull,
EndedBy,
};

private:
/// Whether this property has been audited for nullability.
LLVM_PREFERRED_TYPE(bool)
unsigned KindAudited : 1;

/// The kind of nullability for this property. Only valid if the nullability
/// has been audited.
LLVM_PREFERRED_TYPE(BoundsSafetyKind)
unsigned Kind : 3;

LLVM_PREFERRED_TYPE(bool)
unsigned LevelAudited : 1;

unsigned Level : 3;

public:
std::string ExternalBounds;

BoundsSafetyInfo()
: KindAudited(false), Kind(0), LevelAudited(false), Level(0),
ExternalBounds("") {}

std::optional<BoundsSafetyKind> getKind() const {
return KindAudited ? std::optional<BoundsSafetyKind>(
static_cast<BoundsSafetyKind>(Kind))
: std::nullopt;
}

void setKindAudited(BoundsSafetyKind kind) {
KindAudited = true;
Kind = static_cast<unsigned>(kind);
}

std::optional<unsigned> getLevel() const {
return LevelAudited ? std::optional<unsigned>(Level) : std::nullopt;
}

void setLevelAudited(unsigned level) {
LevelAudited = true;
Level = level;
}

friend bool operator==(const BoundsSafetyInfo &, const BoundsSafetyInfo &);

LLVM_DUMP_METHOD void dump(llvm::raw_ostream &OS) const;
};

inline bool operator==(const BoundsSafetyInfo &LHS,
const BoundsSafetyInfo &RHS) {
return LHS.KindAudited == RHS.KindAudited && LHS.Kind == RHS.Kind &&
LHS.LevelAudited == RHS.LevelAudited && LHS.Level == RHS.Level &&
LHS.ExternalBounds == RHS.ExternalBounds;
}
/* TO_UPSTREAM(BoundsSafety) OFF */

/// API notes for a variable/property.
class VariableInfo : public CommonEntityInfo {
/// Whether this property has been audited for nullability.
Expand Down Expand Up @@ -505,14 +439,10 @@ class ParamInfo : public VariableInfo {
unsigned RawRetainCountConvention : 3;

public:
/* TO_UPSTREAM(BoundsSafety) ON */
std::optional<BoundsSafetyInfo> BoundsSafety;
/* TO_UPSTREAM(BoundsSafety) OFF */

ParamInfo()
: NoEscapeSpecified(false), NoEscape(false),
LifetimeboundSpecified(false), Lifetimebound(false),
RawRetainCountConvention(), BoundsSafety(std::nullopt) {}
RawRetainCountConvention() {}

std::optional<bool> isNoEscape() const {
return NoEscapeSpecified ? std::optional<bool>(NoEscape) : std::nullopt;
Expand Down Expand Up @@ -558,11 +488,6 @@ class ParamInfo : public VariableInfo {
if (!RawRetainCountConvention)
RawRetainCountConvention = RHS.RawRetainCountConvention;

/* TO_UPSTREAM(BoundsSafety) ON */
if (!BoundsSafety)
BoundsSafety = RHS.BoundsSafety;
/* TO_UPSTREAM(BoundsSafety) OFF */

return *this;
}

Expand All @@ -577,10 +502,7 @@ inline bool operator==(const ParamInfo &LHS, const ParamInfo &RHS) {
LHS.NoEscape == RHS.NoEscape &&
LHS.LifetimeboundSpecified == RHS.LifetimeboundSpecified &&
LHS.Lifetimebound == RHS.Lifetimebound &&
LHS.RawRetainCountConvention == RHS.RawRetainCountConvention &&
/* TO_UPSTREAM(BoundsSafety) ON */
LHS.BoundsSafety == RHS.BoundsSafety;
/* TO_UPSTREAM(BoundsSafety) OFF */
LHS.RawRetainCountConvention == RHS.RawRetainCountConvention;
}

inline bool operator!=(const ParamInfo &LHS, const ParamInfo &RHS) {
Expand Down
21 changes: 1 addition & 20 deletions clang/include/clang/Parse/Parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -2021,7 +2021,7 @@ class Parser : public CodeCompletionHandler {
/// Parse a __builtin_bit_cast(T, E), used to implement C++2a std::bit_cast.
ExprResult ParseBuiltinBitCast();

/* TO_UPSTREAM(BoundsSafety) ON */
/* TO_UPSTREAM(BoundsSafety) ON*/
//===--------------------------------------------------------------------===//
/// BoundsSafety: __builtin_unsafe_forge_bidi_indexable(expr, size)
ExprResult ParseUnsafeForgeBidiIndexable();
Expand Down Expand Up @@ -3924,25 +3924,6 @@ class Parser : public CodeCompletionHandler {
/// \param IncludeLoc The location at which this parse was triggered.
TypeResult ParseTypeFromString(StringRef TypeStr, StringRef Context,
SourceLocation IncludeLoc);
/* TO_UPSTREAM(BoundsSafety) ON */
/// Parse the given string as an expression in the argument position for a
/// bounds safety attribute.
///
/// This is a dangerous utility function currently employed only by API notes.
/// It is not a general entry-point for safely parsing expressions from
/// strings.
///
/// \param ExprStr The string to be parsed as an expression.
/// \param Context The name of the context in which this string is being
/// parsed, which will be used in diagnostics.
/// \param ParentDecl If a function or method is provided, the parameters are
/// added to the current parsing context.
/// \param IncludeLoc The location at which this parse was triggered.
ExprResult ParseBoundsAttributeArgFromString(StringRef ExprStr,
StringRef Context,
Decl *ParentDecl,
SourceLocation IncludeLoc);
/* TO_UPSTREAM(BoundsSafety) OFF */

//===--------------------------------------------------------------------===//
// Modules
Expand Down
14 changes: 1 addition & 13 deletions clang/include/clang/Sema/Sema.h
Original file line number Diff line number Diff line change
Expand Up @@ -1131,12 +1131,6 @@ class Sema final : public SemaBase {
std::function<TypeResult(StringRef, StringRef, SourceLocation)>
ParseTypeFromStringCallback;

/* TO_UPSTREAM(BoundsSafety) ON */
/// Callback to the parser to parse a type expressed as a string.
std::function<ExprResult(StringRef, StringRef, Decl *, SourceLocation)>
ParseBoundsAttributeArgFromStringCallback;
/* TO_UPSTREAM(BoundsSafety) OFF */

/// VAListTagName - The declaration name corresponding to __va_list_tag.
/// This is used as part of a hack to omit that class from ADL results.
DeclarationName VAListTagName;
Expand Down Expand Up @@ -15504,13 +15498,7 @@ class Sema final : public SemaBase {
llvm::SmallVectorImpl<TypeCoupledDeclRefInfo> &Decls, bool CountInBytes,
bool OrNull);

/* TO_UPSTREAM(BoundsSafety) ON */
void applyPtrCountedByEndedByAttr(Decl *D, unsigned Level,
AttributeCommonInfo::Kind Kind,
Expr *AttrArg, SourceLocation Loc,
SourceRange Range, StringRef DiagName,
bool OriginatesInAPINotes = false);

/* TO_UPSTREAM(BoundsSafety) ON*/
/// Perform Bounds Safety Semantic checks for assigning to a `__counted_by` or
/// `__counted_by_or_null` pointer type \param LHSTy.
///
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/APINotes/APINotesFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const uint16_t VERSION_MAJOR = 0;
/// API notes file minor version number.
///
/// When the format changes IN ANY WAY, this number should be incremented.
const uint16_t VERSION_MINOR = 35; // BoundsSafety
const uint16_t VERSION_MINOR = 34; // SwiftReturnOwnership

const uint8_t kSwiftConforms = 1;
const uint8_t kSwiftDoesNotConform = 2;
Expand Down
33 changes: 1 addition & 32 deletions clang/lib/APINotes/APINotesReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,31 +322,6 @@ class FieldTableInfo
}
};

/* TO_UPSTREAM(BoundsSafety) ON */
/// Read serialized BoundsSafetyInfo.
void ReadBoundsSafetyInfo(const uint8_t *&Data, BoundsSafetyInfo &Info) {
uint8_t Payload = endian::readNext<uint8_t, llvm::endianness::little>(Data);

if (Payload & 0x01) {
uint8_t Level = (Payload >> 1) & 0x7;
Info.setLevelAudited(Level);
}
Payload >>= 4;

if (Payload & 0x01) {
uint8_t Kind = (Payload >> 1) & 0x7;
assert(Kind >= (uint8_t)BoundsSafetyInfo::BoundsSafetyKind::CountedBy);
assert(Kind <= (uint8_t)BoundsSafetyInfo::BoundsSafetyKind::EndedBy);
Info.setKindAudited((BoundsSafetyInfo::BoundsSafetyKind)Kind);
}

uint16_t ExternalBoundsLen =
endian::readNext<uint16_t, llvm::endianness::little>(Data);
Info.ExternalBounds = std::string(Data, Data + ExternalBoundsLen);
Data += ExternalBoundsLen;
}
/* TO_UPSTREAM(BoundsSafety) OFF */

/// Read serialized ParamInfo.
void ReadParamInfo(const uint8_t *&Data, ParamInfo &Info) {
ReadVariableInfo(Data, Info);
Expand All @@ -363,13 +338,7 @@ void ReadParamInfo(const uint8_t *&Data, ParamInfo &Info) {
if (Payload & 0x01)
Info.setNoEscape(Payload & 0x02);
Payload >>= 2;
/* TO_UPSTREAM(BoundsSafety) ON */
if (Payload & 0x01) {
BoundsSafetyInfo BSI;
ReadBoundsSafetyInfo(Data, BSI);
Info.BoundsSafety = BSI;
}
/* TO_UPSTREAM(BoundsSafety) OFF */
assert(Payload == 0 && "Bad API notes");
}

/// Read serialized FunctionInfo.
Expand Down
30 changes: 0 additions & 30 deletions clang/lib/APINotes/APINotesTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,34 +61,6 @@ LLVM_DUMP_METHOD void ObjCPropertyInfo::dump(llvm::raw_ostream &OS) const {
OS << '\n';
}

LLVM_DUMP_METHOD void BoundsSafetyInfo::dump(llvm::raw_ostream &OS) const {
if (KindAudited) {
assert((BoundsSafetyKind)Kind >= BoundsSafetyKind::CountedBy);
assert((BoundsSafetyKind)Kind <= BoundsSafetyKind::EndedBy);
switch ((BoundsSafetyKind)Kind) {
case BoundsSafetyKind::CountedBy:
OS << "[counted_by] ";
break;
case BoundsSafetyKind::CountedByOrNull:
OS << "[counted_by_or_null] ";
break;
case BoundsSafetyKind::SizedBy:
OS << "[sized_by] ";
break;
case BoundsSafetyKind::SizedByOrNull:
OS << "[sized_by_or_null] ";
break;
case BoundsSafetyKind::EndedBy:
OS << "[ended_by] ";
break;
}
}
if (LevelAudited)
OS << "Level: " << Level << " ";
OS << "ExternalBounds: "
<< (ExternalBounds.empty() ? "<missing>" : ExternalBounds) << '\n';
}

LLVM_DUMP_METHOD void ParamInfo::dump(llvm::raw_ostream &OS) const {
static_cast<const VariableInfo &>(*this).dump(OS);
if (NoEscapeSpecified)
Expand All @@ -97,8 +69,6 @@ LLVM_DUMP_METHOD void ParamInfo::dump(llvm::raw_ostream &OS) const {
OS << (Lifetimebound ? "[Lifetimebound] " : "");
OS << "RawRetainCountConvention: " << RawRetainCountConvention << ' ';
OS << '\n';
if (BoundsSafety)
BoundsSafety->dump(OS);
}

LLVM_DUMP_METHOD void FunctionInfo::dump(llvm::raw_ostream &OS) const {
Expand Down
39 changes: 1 addition & 38 deletions clang/lib/APINotes/APINotesWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1074,48 +1074,15 @@ void APINotesWriter::Implementation::writeGlobalVariableBlock(
}
}

/* TO_UPSTREAM(BoundsSafety) ON */
namespace {
void emitBoundsSafetyInfo(raw_ostream &OS, const BoundsSafetyInfo &BSI) {
llvm::support::endian::Writer writer(OS, llvm::endianness::little);
uint8_t flags = 0;
if (auto kind = BSI.getKind()) {
flags |= 0x01; // 1 bit
flags |= (uint8_t)*kind << 1; // 3 bits
}
flags <<= 4;
if (auto level = BSI.getLevel()) {
flags |= 0x01; // 1 bit
flags |= *level << 1; // 3 bits
}

writer.write<uint8_t>(flags);
writer.write<uint16_t>(BSI.ExternalBounds.size());
writer.write(
ArrayRef<char>{BSI.ExternalBounds.data(), BSI.ExternalBounds.size()});
}

unsigned getBoundsSafetyInfoSize(const BoundsSafetyInfo &BSI) {
return 1 + sizeof(uint16_t) + BSI.ExternalBounds.size();
}
/* TO_UPSTREAM(BoundsSafety) OFF */

unsigned getParamInfoSize(const ParamInfo &PI) {
unsigned BSISize = 0;
/* TO_UPSTREAM(BoundsSafety) ON */
if (auto BSI = PI.BoundsSafety)
BSISize = getBoundsSafetyInfoSize(*BSI);
/* TO_UPSTREAM(BoundsSafety) OFF */
return getVariableInfoSize(PI) + 1 + BSISize;
return getVariableInfoSize(PI) + 1;
}

void emitParamInfo(raw_ostream &OS, const ParamInfo &PI) {
emitVariableInfo(OS, PI);

uint8_t flags = 0;
if (PI.BoundsSafety)
flags |= 0x01;
flags <<= 2;
if (auto noescape = PI.isNoEscape()) {
flags |= 0x01;
if (*noescape)
Expand All @@ -1133,10 +1100,6 @@ void emitParamInfo(raw_ostream &OS, const ParamInfo &PI) {

llvm::support::endian::Writer writer(OS, llvm::endianness::little);
writer.write<uint8_t>(flags);
/* TO_UPSTREAM(BoundsSafety) ON */
if (auto BSI = PI.BoundsSafety)
emitBoundsSafetyInfo(OS, *PI.BoundsSafety);
/* TO_UPSTREAM(BoundsSafety) OFF */
}

/// Retrieve the serialized size of the given FunctionInfo, for use in on-disk
Expand Down
Loading

0 comments on commit 95b1930

Please sign in to comment.