diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64AsmBackend.cpp @@ -160,8 +160,11 @@ return AdrImmBits(Value & 0x1fffffULL); case AArch64::fixup_aarch64_pcrel_adrp_imm21: assert(!IsResolved); - if (TheTriple.isOSBinFormatCOFF()) + if (TheTriple.isOSBinFormatCOFF()) { + if (!isInt<21>(SignedValue)) + Ctx.reportError(Fixup.getLoc(), "fixup value out of range"); return AdrImmBits(Value & 0x1fffffULL); + } return AdrImmBits((Value & 0x1fffff000ULL) >> 12); case AArch64::fixup_aarch64_ldr_pcrel_imm19: case AArch64::fixup_aarch64_pcrel_branch19: diff --git a/llvm/test/MC/AArch64/fixup-out-of-range.s b/llvm/test/MC/AArch64/fixup-out-of-range.s --- a/llvm/test/MC/AArch64/fixup-out-of-range.s +++ b/llvm/test/MC/AArch64/fixup-out-of-range.s @@ -1,5 +1,5 @@ // RUN: not llvm-mc -triple aarch64--none-eabi -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s -// RUN: not llvm-mc -triple aarch64-windows -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s +// RUN: not llvm-mc -triple aarch64-windows -filetype obj < %s -o /dev/null 2>&1 | FileCheck %s -check-prefixes=CHECK,CHECK-WIN // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range adr x0, distant @@ -70,6 +70,8 @@ // CHECK: :[[@LINE+1]]:{{[0-9]+}}: error: relocation for a thread-local variable points to an absolute symbol movz x0, #:tprel_g0:value1 +// CHECK-WIN: :[[@LINE+1]]:{{[0-9]+}}: error: fixup value out of range + adrp x0, external+0x1000000 .byte 0 unaligned: