Add whole-program vtable optimization feature to Clang.
This patch introduces the -fwhole-program-vtables flag, which enables the
whole-program vtable optimization feature (D16795) in Clang.
Differential Revision: http://reviews.llvm.org/D16821
llvm-svn: 261767
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index e96a812..953053b 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -898,21 +898,34 @@
DeferredVTables.clear();
}
-bool CodeGenModule::IsCFIBlacklistedRecord(const CXXRecordDecl *RD) {
- if (RD->hasAttr<UuidAttr>() &&
- getContext().getSanitizerBlacklist().isBlacklistedType("attr:uuid"))
- return true;
+bool CodeGenModule::NeedVTableBitSets() {
+ return getCodeGenOpts().WholeProgramVTables ||
+ getLangOpts().Sanitize.has(SanitizerKind::CFIVCall) ||
+ getLangOpts().Sanitize.has(SanitizerKind::CFINVCall) ||
+ getLangOpts().Sanitize.has(SanitizerKind::CFIDerivedCast) ||
+ getLangOpts().Sanitize.has(SanitizerKind::CFIUnrelatedCast);
+}
- return getContext().getSanitizerBlacklist().isBlacklistedType(
- RD->getQualifiedNameAsString());
+bool CodeGenModule::IsBitSetBlacklistedRecord(const CXXRecordDecl *RD) {
+ std::string TypeName = RD->getQualifiedNameAsString();
+ auto isInBlacklist = [&](const SanitizerBlacklist &BL) {
+ if (RD->hasAttr<UuidAttr>() && BL.isBlacklistedType("attr:uuid"))
+ return true;
+
+ return BL.isBlacklistedType(TypeName);
+ };
+
+ return isInBlacklist(WholeProgramVTablesBlacklist) ||
+ ((LangOpts.Sanitize.has(SanitizerKind::CFIVCall) ||
+ LangOpts.Sanitize.has(SanitizerKind::CFINVCall) ||
+ LangOpts.Sanitize.has(SanitizerKind::CFIDerivedCast) ||
+ LangOpts.Sanitize.has(SanitizerKind::CFIUnrelatedCast)) &&
+ isInBlacklist(getContext().getSanitizerBlacklist()));
}
void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
const VTableLayout &VTLayout) {
- if (!LangOpts.Sanitize.has(SanitizerKind::CFIVCall) &&
- !LangOpts.Sanitize.has(SanitizerKind::CFINVCall) &&
- !LangOpts.Sanitize.has(SanitizerKind::CFIDerivedCast) &&
- !LangOpts.Sanitize.has(SanitizerKind::CFIUnrelatedCast))
+ if (!NeedVTableBitSets())
return;
CharUnits PointerWidth =
@@ -922,7 +935,7 @@
std::vector<BSEntry> BitsetEntries;
// Create a bit set entry for each address point.
for (auto &&AP : VTLayout.getAddressPoints()) {
- if (IsCFIBlacklistedRecord(AP.first.getBase()))
+ if (IsBitSetBlacklistedRecord(AP.first.getBase()))
continue;
BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second));