]> granicus.if.org Git - clang/blobdiff - lib/CodeGen/CGVTables.cpp
Add whole-program vtable optimization feature to Clang.
[clang] / lib / CodeGen / CGVTables.cpp
index e96a81202074da163d47f2b24efe040cfa59ac8f..953053bd1c31c954c00a0b268d5d1c96ccd8f6c8 100644 (file)
@@ -898,21 +898,34 @@ void CodeGenModule::EmitDeferredVTables() {
   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);
+}
+
+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 getContext().getSanitizerBlacklist().isBlacklistedType(
-      RD->getQualifiedNameAsString());
+  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 @@ void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
   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));