Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -589,7 +589,8 @@ Assert(!GV.isDSOLocal(), "GlobalValue with DLLImport Storage is dso_local!", &GV); - Assert((GV.isDeclaration() && GV.hasExternalLinkage()) || + Assert((GV.isDeclaration() && + (GV.hasExternalLinkage() || GV.hasExternalWeakLinkage())) || GV.hasAvailableExternallyLinkage(), "Global is marked as dllimport, but not external", &GV); } Index: llvm/test/Verifier/weak-dllimport.ll =================================================================== --- /dev/null +++ llvm/test/Verifier/weak-dllimport.ll @@ -0,0 +1,51 @@ +; RUN: opt -verify < %s +; ModuleID = 'wd.cpp' +source_filename = "wd.cpp" +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.11.0" + +@"?var_hook@@3HA" = extern_weak dllimport global i32, align 4 + +; Function Attrs: noinline optnone uwtable +define dso_local zeroext i1 @"?foo@@YA_NPEAHH@Z"(i32* %0, i32 %1) #0 { + %3 = alloca i32, align 4 + %4 = alloca i32*, align 8 + store i32 %1, i32* %3, align 4 + store i32* %0, i32** %4, align 8 + br i1 icmp ne (void (i32)* @func_hook, void (i32)* null), label %5, label %7 + +5: ; preds = %2 + %6 = load i32, i32* %3, align 4 + call void @func_hook(i32 %6) + br label %7 + +7: ; preds = %5, %2 + %8 = load i32*, i32** %4, align 8 + %9 = icmp eq i32* @"?var_hook@@3HA", %8 + ret i1 %9 +} + +declare extern_weak dllimport void @func_hook(i32) #1 + +attributes #0 = { noinline optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="none" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } + +!llvm.module.flags = !{!0, !1} +!llvm.ident = !{!2} + +!0 = !{i32 1, !"wchar_size", i32 2} +!1 = !{i32 7, !"PIC Level", i32 2} +!2 = !{!"clang version 12.0.0 (https://github.com/llvm/llvm-project.git 60db26a66d5346b2feae279f6c928bde48078893)"} + +; Compiled from the following C++ example with --target=x86_64-pc-win32, +; using the non-checking configuration +;__declspec(dllimport) __attribute__(( +; weak)) extern "C" void func_hook(int); +;extern __declspec(dllimport) __attribute__((weak)) int var_hook; +; +;bool foo(int *q, int p) +;{ +; if (func_hook) +; func_hook(p); +; return &var_hook == q; +;}