summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGClass.cpp9
-rw-r--r--clang/lib/CodeGen/CGVTables.cpp57
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp4
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h12
-rw-r--r--clang/lib/CodeGen/MicrosoftCXXABI.cpp17
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp11
-rw-r--r--clang/lib/Driver/Tools.cpp39
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp3
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp3
9 files changed, 77 insertions, 78 deletions
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 71b305c773d..351dae9d4dd 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -2489,7 +2489,7 @@ void CodeGenFunction::EmitBitSetCodeForVCall(const CXXRecordDecl *RD,
llvm::Value *VTable,
SourceLocation Loc) {
if (CGM.getCodeGenOpts().WholeProgramVTables &&
- CGM.HasHiddenLTOVisibility(RD)) {
+ !CGM.IsBitSetBlacklistedRecord(RD)) {
llvm::Metadata *MD =
CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
llvm::Value *BitSetName =
@@ -2565,12 +2565,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
llvm::Value *VTable,
CFITypeCheckKind TCK,
SourceLocation Loc) {
- if (!CGM.getCodeGenOpts().SanitizeCfiCrossDso &&
- !CGM.HasHiddenLTOVisibility(RD))
- return;
-
- std::string TypeName = RD->getQualifiedNameAsString();
- if (getContext().getSanitizerBlacklist().isBlacklistedType(TypeName))
+ if (CGM.IsBitSetBlacklistedRecord(RD))
return;
SanitizerScope SanScope(this);
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 478164e273b..f139e2c8504 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -902,43 +902,34 @@ void CodeGenModule::EmitDeferredVTables() {
DeferredVTables.clear();
}
-bool CodeGenModule::HasHiddenLTOVisibility(const CXXRecordDecl *RD) {
- LinkageInfo LV = RD->getLinkageAndVisibility();
- if (!isExternallyVisible(LV.getLinkage()))
- return true;
-
- if (RD->hasAttr<LTOVisibilityPublicAttr>() || RD->hasAttr<UuidAttr>())
- return false;
+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);
+}
- if (getTriple().isOSBinFormatCOFF()) {
- if (RD->hasAttr<DLLExportAttr>() || RD->hasAttr<DLLImportAttr>())
- return false;
- } else {
- if (LV.getVisibility() != HiddenVisibility)
- return false;
- }
+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;
- if (getCodeGenOpts().LTOVisibilityPublicStd) {
- const DeclContext *DC = RD;
- while (1) {
- auto *D = cast<Decl>(DC);
- DC = DC->getParent();
- if (isa<TranslationUnitDecl>(DC->getRedeclContext())) {
- if (auto *ND = dyn_cast<NamespaceDecl>(D))
- if (const IdentifierInfo *II = ND->getIdentifier())
- if (II->isStr("std") || II->isStr("stdext"))
- return false;
- break;
- }
- }
- }
+ return BL.isBlacklistedType(TypeName);
+ };
- return true;
+ 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 (!getCodeGenOpts().PrepareForLTO)
+ if (!NeedVTableBitSets())
return;
CharUnits PointerWidth =
@@ -947,8 +938,12 @@ void CodeGenModule::EmitVTableBitSetEntries(llvm::GlobalVariable *VTable,
typedef std::pair<const CXXRecordDecl *, unsigned> BSEntry;
std::vector<BSEntry> BitsetEntries;
// Create a bit set entry for each address point.
- for (auto &&AP : VTLayout.getAddressPoints())
+ for (auto &&AP : VTLayout.getAddressPoints()) {
+ if (IsBitSetBlacklistedRecord(AP.first.getBase()))
+ continue;
+
BitsetEntries.push_back(std::make_pair(AP.first.getBase(), AP.second));
+ }
// Sort the bit set entries for determinism.
std::sort(BitsetEntries.begin(), BitsetEntries.end(),
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 8ff99a6c404..64fe3652a9d 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -88,7 +88,9 @@ CodeGenModule::CodeGenModule(ASTContext &C, const HeaderSearchOptions &HSO,
PreprocessorOpts(PPO), CodeGenOpts(CGO), TheModule(M), Diags(diags),
Target(C.getTargetInfo()), ABI(createCXXABI(*this)),
VMContext(M.getContext()), Types(*this), VTables(*this),
- SanitizerMD(new SanitizerMetadata(*this)) {
+ SanitizerMD(new SanitizerMetadata(*this)),
+ WholeProgramVTablesBlacklist(CGO.WholeProgramVTablesBlacklistFiles,
+ C.getSourceManager()) {
// Initialize the type cache.
llvm::LLVMContext &LLVMContext = M.getContext();
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index a75e4aa2a32..34d1111889a 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -490,6 +490,8 @@ private:
/// MDNodes.
llvm::DenseMap<QualType, llvm::Metadata *> MetadataIdMap;
+ SanitizerBlacklist WholeProgramVTablesBlacklist;
+
public:
CodeGenModule(ASTContext &C, const HeaderSearchOptions &headersearchopts,
const PreprocessorOptions &ppopts,
@@ -1113,10 +1115,12 @@ public:
void EmitOMPDeclareReduction(const OMPDeclareReductionDecl *D,
CodeGenFunction *CGF = nullptr);
- /// Returns whether the given record has hidden LTO visibility and therefore
- /// may participate in (single-module) CFI and whole-program vtable
- /// optimization.
- bool HasHiddenLTOVisibility(const CXXRecordDecl *RD);
+ /// Returns whether we need bit sets attached to vtables.
+ bool NeedVTableBitSets();
+
+ /// Returns whether the given record is blacklisted from whole-program
+ /// transformations (i.e. CFI or whole-program vtable optimization).
+ bool IsBitSetBlacklistedRecord(const CXXRecordDecl *RD);
/// Emit bit set entries for the given vtable using the given layout if
/// vptr CFI is enabled.
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index 0e15f5054d8..e578863bfc3 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -1503,7 +1503,7 @@ void MicrosoftCXXABI::EmitDestructorCall(CodeGenFunction &CGF,
void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info,
const CXXRecordDecl *RD,
llvm::GlobalVariable *VTable) {
- if (!CGM.getCodeGenOpts().PrepareForLTO)
+ if (!CGM.NeedVTableBitSets())
return;
llvm::NamedMDNode *BitsetsMD =
@@ -1519,13 +1519,15 @@ void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info,
: CharUnits::Zero();
if (Info->PathToBaseWithVPtr.empty()) {
- CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
+ if (!CGM.IsBitSetBlacklistedRecord(RD))
+ CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
return;
}
// Add a bitset entry for the least derived base belonging to this vftable.
- CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint,
- Info->PathToBaseWithVPtr.back());
+ if (!CGM.IsBitSetBlacklistedRecord(Info->PathToBaseWithVPtr.back()))
+ CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint,
+ Info->PathToBaseWithVPtr.back());
// Add a bitset entry for each derived class that is laid out at the same
// offset as the least derived base.
@@ -1543,11 +1545,12 @@ void MicrosoftCXXABI::emitVTableBitSetEntries(VPtrInfo *Info,
Offset = VBI->second.VBaseOffset;
if (!Offset.isZero())
return;
- CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, DerivedRD);
+ if (!CGM.IsBitSetBlacklistedRecord(DerivedRD))
+ CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, DerivedRD);
}
// Finally do the same for the most derived class.
- if (Info->FullOffsetInMDC.isZero())
+ if (Info->FullOffsetInMDC.isZero() && !CGM.IsBitSetBlacklistedRecord(RD))
CGM.CreateVTableBitSetEntry(BitsetsMD, VTable, AddressPoint, RD);
}
@@ -1816,7 +1819,7 @@ llvm::Value *MicrosoftCXXABI::getVirtualFunctionPointer(CodeGenFunction &CGF,
MicrosoftVTableContext::MethodVFTableLocation ML =
CGM.getMicrosoftVTableContext().getMethodVFTableLocation(GD);
- if (CGM.getCodeGenOpts().PrepareForLTO)
+ if (CGM.NeedVTableBitSets())
CGF.EmitBitSetCodeForVCall(getClassAtVTableLocation(getContext(), GD, ML),
VTable, Loc);
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index c63ff4be8a7..50a93a8d431 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -39,7 +39,6 @@ enum : SanitizerMask {
TrappingSupported =
(Undefined & ~Vptr) | UnsignedIntegerOverflow | LocalBounds | CFI,
TrappingDefault = CFI,
- CFIClasses = CFIVCall | CFINVCall | CFIDerivedCast | CFIUnrelatedCast,
};
enum CoverageFeature {
@@ -682,16 +681,6 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
TC.getCompilerRT(Args, "stats")));
addIncludeLinkerOption(TC, Args, CmdArgs, "__sanitizer_stats_register");
}
-
- // Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
- // enabled.
- if (Sanitizers.hasOneOf(CFIClasses) && !TC.getTriple().isOSWindows() &&
- !Args.hasArg(options::OPT_fvisibility_EQ)) {
- TC.getDriver().Diag(clang::diag::err_drv_argument_only_allowed_with)
- << lastArgumentForMask(TC.getDriver(), Args,
- Sanitizers.Mask & CFIClasses)
- << "-fvisibility=";
- }
}
SanitizerMask parseArgValues(const Driver &D, const llvm::opt::Arg *A,
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index f0199aab274..74ac8070561 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -4429,6 +4429,32 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back("-ffunction-sections");
}
+ if (Args.hasFlag(options::OPT_fwhole_program_vtables,
+ options::OPT_fno_whole_program_vtables, false)) {
+ if (!D.isUsingLTO())
+ D.Diag(diag::err_drv_argument_only_allowed_with)
+ << "-fwhole-program-vtables"
+ << "-flto";
+ CmdArgs.push_back("-fwhole-program-vtables");
+
+ clang::SmallString<64> Path(D.ResourceDir);
+ llvm::sys::path::append(Path, "vtables_blacklist.txt");
+ if (llvm::sys::fs::exists(Path)) {
+ SmallString<64> BlacklistOpt("-fwhole-program-vtables-blacklist=");
+ BlacklistOpt += Path.str();
+ CmdArgs.push_back(Args.MakeArgString(BlacklistOpt));
+ }
+
+ for (const Arg *A :
+ Args.filtered(options::OPT_fwhole_program_vtables_blacklist_EQ)) {
+ A->claim();
+ if (!llvm::sys::fs::exists(A->getValue()))
+ D.Diag(clang::diag::err_drv_no_such_file) << A->getValue();
+ }
+
+ Args.AddAllArgs(CmdArgs, options::OPT_fwhole_program_vtables_blacklist_EQ);
+ }
+
if (Args.hasFlag(options::OPT_fdata_sections, options::OPT_fno_data_sections,
UseSeparateSections)) {
CmdArgs.push_back("-fdata-sections");
@@ -5759,17 +5785,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(I->getFilename());
}
- bool WholeProgramVTables =
- Args.hasFlag(options::OPT_fwhole_program_vtables,
- options::OPT_fno_whole_program_vtables, false);
- if (WholeProgramVTables) {
- if (!D.isUsingLTO())
- D.Diag(diag::err_drv_argument_only_allowed_with)
- << "-fwhole-program-vtables"
- << "-flto";
- CmdArgs.push_back("-fwhole-program-vtables");
- }
-
// Finally add the compile command to the compilation.
if (Args.hasArg(options::OPT__SLASH_fallback) &&
Output.getType() == types::TY_Object &&
@@ -6033,13 +6048,11 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
if (Args.hasArg(options::OPT__SLASH_LDd))
CmdArgs.push_back("-D_DEBUG");
CmdArgs.push_back("-D_MT");
- CmdArgs.push_back("-flto-visibility-public-std");
FlagForCRT = "--dependent-lib=libcmt";
break;
case options::OPT__SLASH_MTd:
CmdArgs.push_back("-D_DEBUG");
CmdArgs.push_back("-D_MT");
- CmdArgs.push_back("-flto-visibility-public-std");
FlagForCRT = "--dependent-lib=libcmtd";
break;
default:
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 4bef159f3bf..0c4d5c71d5c 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -482,7 +482,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.DebugColumnInfo = Args.hasArg(OPT_dwarf_column_info);
Opts.EmitCodeView = Args.hasArg(OPT_gcodeview);
Opts.WholeProgramVTables = Args.hasArg(OPT_fwhole_program_vtables);
- Opts.LTOVisibilityPublicStd = Args.hasArg(OPT_flto_visibility_public_std);
+ Opts.WholeProgramVTablesBlacklistFiles =
+ Args.getAllArgValues(OPT_fwhole_program_vtables_blacklist_EQ);
Opts.SplitDwarfFile = Args.getLastArgValue(OPT_split_dwarf_file);
Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs);
Opts.DebugExplicitImport = Triple.isPS4CPU();
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 9bf5fc9e36d..0ba9799d042 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5749,9 +5749,6 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D,
case AttributeList::AT_InternalLinkage:
handleInternalLinkageAttr(S, D, Attr);
break;
- case AttributeList::AT_LTOVisibilityPublic:
- handleSimpleAttribute<LTOVisibilityPublicAttr>(S, D, Attr);
- break;
// Microsoft attributes:
case AttributeList::AT_MSNoVTable:
OpenPOWER on IntegriCloud