Author: rsmith Date: Tue May 17 19:16:51 2016 New Revision: 269869 URL: http://llvm.org/viewvc/llvm-project?rev=269869&view=rev Log: Fix use-after-free ASan failures for modules / PCH files that deserialize abi_tag or no_sanitize attributes.
Modified: cfe/trunk/test/PCH/attrs.c cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Modified: cfe/trunk/test/PCH/attrs.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/attrs.c?rev=269869&r1=269868&r2=269869&view=diff ============================================================================== --- cfe/trunk/test/PCH/attrs.c (original) +++ cfe/trunk/test/PCH/attrs.c Tue May 17 19:16:51 2016 @@ -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 Modified: cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?rev=269869&r1=269868&r2=269869&view=diff ============================================================================== --- cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp (original) +++ cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp Tue May 17 19:16:51 2016 @@ -98,6 +98,13 @@ static std::string ReadPCHRecord(StringR .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() static std::string WritePCHRecord(StringRef type, StringRef name) { return "Record." + StringSwitch<std::string>(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 { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits