From: Richard Smith Date: Wed, 18 May 2016 00:16:51 +0000 (+0000) Subject: Fix use-after-free ASan failures for modules / PCH files that deserialize abi_tag... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=284f294745a816dc782640308ae977b313dbcb17;p=clang Fix use-after-free ASan failures for modules / PCH files that deserialize abi_tag or no_sanitize attributes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269869 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/PCH/attrs.c b/test/PCH/attrs.c index 6a4b8f667c..5b70680460 100644 --- a/test/PCH/attrs.c +++ b/test/PCH/attrs.c @@ -9,10 +9,12 @@ #define HEADER int f(int) __attribute__((visibility("default"), overloadable)); +int g(int) __attribute__((abi_tag("foo", "bar", "baz"), no_sanitize("address", "memory"))); // expected-warning {{ignored}} #else double f(double); // expected-error{{overloadable}} // expected-note@11{{previous overload}} +void h() { g(0); } #endif diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index e6005cbada..edb613c092 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -98,6 +98,13 @@ static std::string ReadPCHRecord(StringRef type) { .Default("Record[Idx++]"); } +// Get a type that is suitable for storing an object of the specified type. +static StringRef getStorageType(StringRef type) { + return StringSwitch(type) + .Case("StringRef", "std::string") + .Default(type); +} + // Assumes that the way to get the value is SA->getname() static std::string WritePCHRecord(StringRef type, StringRef name) { return "Record." + StringSwitch(type) @@ -644,15 +651,34 @@ namespace { } void writePCHReadDecls(raw_ostream &OS) const override { - OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; - OS << " SmallVector<" << Type << ", 4> " << getLowerName() - << ";\n"; - OS << " " << getLowerName() << ".reserve(" << getLowerName() + OS << " unsigned " << getLowerName() << "Size = Record[Idx++];\n"; + OS << " SmallVector<" << getType() << ", 4> " + << getLowerName() << ";\n"; + OS << " " << getLowerName() << ".reserve(" << getLowerName() << "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); - 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 {