diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 81ad5b477e0..3d500077b7a 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1764,9 +1764,14 @@ void AddressSanitizerModule::SetComdatForGlobalMetadata( C = M.getOrInsertComdat(G->getName()); } - // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF. - if (TargetTriple.isOSBinFormatCOFF()) + // Make this IMAGE_COMDAT_SELECT_NODUPLICATES on COFF. Also upgrade private + // linkage to internal linkage so that a symbol table entry is emitted. This + // is necessary in order to create the comdat group. + if (TargetTriple.isOSBinFormatCOFF()) { C->setSelectionKind(Comdat::NoDuplicates); + if (G->hasPrivateLinkage()) + G->setLinkage(GlobalValue::InternalLinkage); + } G->setComdat(C); } diff --git a/test/Instrumentation/AddressSanitizer/global_metadata_windows.ll b/test/Instrumentation/AddressSanitizer/global_metadata_windows.ll index 86390966c62..eeac65e1847 100644 --- a/test/Instrumentation/AddressSanitizer/global_metadata_windows.ll +++ b/test/Instrumentation/AddressSanitizer/global_metadata_windows.ll @@ -12,16 +12,25 @@ target triple = "x86_64-pc-windows-msvc19.0.24215" $mystr = comdat any ; CHECK: $dead_global = comdat noduplicates +; CHECK: $private_str = comdat noduplicates + ; CHECK: @dead_global = local_unnamed_addr global { i32, [60 x i8] } { i32 42, [60 x i8] zeroinitializer }, comdat, align 32 +; CHECK: @private_str = internal unnamed_addr constant { [8 x i8], [56 x i8] } { [8 x i8] c"private\00", [56 x i8] zeroinitializer }, comdat, align 32 + ; CHECK: @__asan_global_dead_global = private global { {{.*}} }, section ".ASAN$GL", comdat($dead_global), align 64 +; CHECK: @__asan_global_private_str = private global { {{.*}} }, section ".ASAN$GL", comdat($private_str), align 64 @dead_global = local_unnamed_addr global i32 42, align 4 @mystr = linkonce_odr unnamed_addr constant [5 x i8] c"main\00", comdat, align 1 +; Private globals will get upgraded to internal linkage. +@private_str = private unnamed_addr constant [8 x i8] c"private\00", align 1 + ; Function Attrs: nounwind uwtable define i32 @main() local_unnamed_addr #0 { entry: %call = tail call i32 @puts(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @mystr, i64 0, i64 0)) + %call2 = tail call i32 @puts(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @private_str, i64 0, i64 0)) ret i32 0 }