forked from OSchip/llvm-project
Fix use-after-free ASan failures for modules / PCH files that deserialize abi_tag or no_sanitize attributes.
llvm-svn: 269869
This commit is contained in:
parent
14d1cb226c
commit
1997856936
|
@ -9,10 +9,12 @@
|
||||||
#define HEADER
|
#define HEADER
|
||||||
|
|
||||||
int f(int) __attribute__((visibility("default"), overloadable));
|
int f(int) __attribute__((visibility("default"), overloadable));
|
||||||
|
int g(int) __attribute__((abi_tag("foo", "bar", "baz"), no_sanitize("address", "memory"))); // expected-warning {{ignored}}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
double f(double); // expected-error{{overloadable}}
|
double f(double); // expected-error{{overloadable}}
|
||||||
// expected-note@11{{previous overload}}
|
// expected-note@11{{previous overload}}
|
||||||
|
void h() { g(0); }
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -98,6 +98,13 @@ static std::string ReadPCHRecord(StringRef type) {
|
||||||
.Default("Record[Idx++]");
|
.Default("Record[Idx++]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get a type that is suitable for storing an object of the specified type.
|
||||||
|
static StringRef getStorageType(StringRef type) {
|
||||||
|
return StringSwitch<StringRef>(type)
|
||||||
|
.Case("StringRef", "std::string")
|
||||||
|
.Default(type);
|
||||||
|
}
|
||||||
|
|
||||||
// Assumes that the way to get the value is SA->getname()
|
// Assumes that the way to get the value is SA->getname()
|
||||||
static std::string WritePCHRecord(StringRef type, StringRef name) {
|
static std::string WritePCHRecord(StringRef type, StringRef name) {
|
||||||
return "Record." + StringSwitch<std::string>(type)
|
return "Record." + StringSwitch<std::string>(type)
|
||||||
|
@ -645,14 +652,33 @@ namespace {
|
||||||
|
|
||||||
void writePCHReadDecls(raw_ostream &OS) const override {
|
void writePCHReadDecls(raw_ostream &OS) const override {
|
||||||
OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
|
OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n";
|
||||||
OS << " SmallVector<" << Type << ", 4> " << getLowerName()
|
OS << " SmallVector<" << getType() << ", 4> "
|
||||||
<< ";\n";
|
<< getLowerName() << ";\n";
|
||||||
OS << " " << getLowerName() << ".reserve(" << getLowerName()
|
OS << " " << getLowerName() << ".reserve(" << getLowerName()
|
||||||
<< "Size);\n";
|
<< "Size);\n";
|
||||||
OS << " for (unsigned i = " << getLowerName() << "Size; i; --i)\n";
|
|
||||||
|
|
||||||
|
// If we can't store the values in the current type (if it's something
|
||||||
|
// like StringRef), store them in a different type and convert the
|
||||||
|
// container afterwards.
|
||||||
|
std::string StorageType = getStorageType(getType());
|
||||||
|
std::string StorageName = getLowerName();
|
||||||
|
if (StorageType != getType()) {
|
||||||
|
StorageName += "Storage";
|
||||||
|
OS << " SmallVector<" << StorageType << ", 4> "
|
||||||
|
<< StorageName << ";\n";
|
||||||
|
OS << " " << StorageName << ".reserve(" << getLowerName()
|
||||||
|
<< "Size);\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
OS << " for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n";
|
||||||
std::string read = ReadPCHRecord(Type);
|
std::string read = ReadPCHRecord(Type);
|
||||||
OS << " " << getLowerName() << ".push_back(" << read << ");\n";
|
OS << " " << StorageName << ".push_back(" << read << ");\n";
|
||||||
|
|
||||||
|
if (StorageType != getType()) {
|
||||||
|
OS << " for (unsigned i = 0; i != " << getLowerName() << "Size; ++i)\n";
|
||||||
|
OS << " " << getLowerName() << ".push_back("
|
||||||
|
<< StorageName << "[i]);\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void writePCHReadArgs(raw_ostream &OS) const override {
|
void writePCHReadArgs(raw_ostream &OS) const override {
|
||||||
|
|
Loading…
Reference in New Issue