diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 4f7734153ac..107ae56e91f 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -2119,12 +2119,6 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, if (Lexer.isNot(AsmToken::EndOfStatement)) return TokError("unexpected token in assignment"); - // Error on assignment to '.'. - if (Name == ".") { - return Error(EqualLoc, ("assignment to pseudo-symbol '.' is unsupported " - "(use '.space' or '.org').)")); - } - // Eat the end of statement marker. Lex(); @@ -2152,11 +2146,15 @@ bool AsmParser::parseAssignment(StringRef Name, bool allow_redef, // Don't count these checks as uses. Sym->setUsed(false); + } else if (Name == ".") { + if (Out.EmitValueToOffset(Value, 0)) { + Error(EqualLoc, "expected absolute expression"); + eatToEndOfStatement(); + } + return false; } else Sym = getContext().GetOrCreateSymbol(Name); - // FIXME: Handle '.'. - // Do the assignment. Out.EmitAssignment(Sym, Value); if (NoDeadStrip) diff --git a/test/MC/AsmParser/dot-symbol-assignment-backwards.s b/test/MC/AsmParser/dot-symbol-assignment-backwards.s new file mode 100644 index 00000000000..2619788203a --- /dev/null +++ b/test/MC/AsmParser/dot-symbol-assignment-backwards.s @@ -0,0 +1,12 @@ +# RUN: not llvm-mc -filetype=obj -triple i386-unknown-unknown %s 2> %t +# RUN: FileCheck -input-file %t %s + +. = 0x10 + .byte 1 + +. = . + 10 + .byte 2 + +# CHECK: LLVM ERROR: invalid .org offset '24' (at offset '28') +. = 0x18 + .byte 3 diff --git a/test/MC/AsmParser/dot-symbol-assignment.s b/test/MC/AsmParser/dot-symbol-assignment.s new file mode 100644 index 00000000000..65651d77485 --- /dev/null +++ b/test/MC/AsmParser/dot-symbol-assignment.s @@ -0,0 +1,31 @@ +# RUN: llvm-mc -triple i386-unknown-unknown %s | FileCheck %s + + .extern start + +# CHECK: .org 1024, 0 +. = 0x400 + lgdt 0x400 + 0x100 + + ljmpl $0x08, $(0x400 + 0x150) + + +# CHECK: .org 1280, 0 +. = 0x400 + 0x100 + .word (3*8)-1 + .quad (0x400 + 0x110) + +# CHECK: .org 1296, 0 +. = 0x400 + 0x110 + .quad 0x0 + .quad 0x0020980000000000 + .quad 0x0000900000000000 + + .code64 + +# CHECK: .org 1360, 0 +. = 0x400 + 0x150 + movabsq $start, %rcx + jmp *%rcx + + +. = 0x300 diff --git a/test/MC/AsmParser/dot-symbol-non-absolute.s b/test/MC/AsmParser/dot-symbol-non-absolute.s new file mode 100644 index 00000000000..7342365fe1b --- /dev/null +++ b/test/MC/AsmParser/dot-symbol-non-absolute.s @@ -0,0 +1,9 @@ +# RUN: not llvm-mc -filetype=obj -triple i386-unknown-unknown %s 2> %t +# RUN: FileCheck -input-file %t %s + + + .extern foo + +# CHECK: error: expected absolute expression +. = foo + 10 + .byte 1 diff --git a/test/MC/AsmParser/dot-symbol.s b/test/MC/AsmParser/dot-symbol.s index 4a38a405324..4bae3231868 100644 --- a/test/MC/AsmParser/dot-symbol.s +++ b/test/MC/AsmParser/dot-symbol.s @@ -1,12 +1,9 @@ # Historically 'as' treats '.' as a reference to the current location in -# arbitrary contects. We don't support this in general. +# arbitrary contexts. We don't support this in general. # RUN: not llvm-mc -triple i386-unknown-unknown %s 2> %t # RUN: FileCheck -input-file %t %s -# CHECK: assignment to pseudo-symbol '.' is unsupported (use '.space' or '.org'). -. = . + 8 - # CHECK: invalid use of pseudo-symbol '.' as a label .: .long 0 diff --git a/test/MC/ELF/dot-symbol-assignment.s b/test/MC/ELF/dot-symbol-assignment.s new file mode 100644 index 00000000000..00fe205082b --- /dev/null +++ b/test/MC/ELF/dot-symbol-assignment.s @@ -0,0 +1,22 @@ +// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | llvm-readobj -sections -section-data | FileCheck %s + +one: + .quad 0xffffffffffffffff + +. = . + 16 +two: + .quad 0xeeeeeeeeeeeeeeee + +. = 0x20 +three: + .quad 0xdddddddddddddddd + +// CHECK: Section { +// CHECK: Name: .text +// CHECK-NEXT: Type: +// CHECK-NEXT: Flags [ +// CHECK: SectionData ( +// CHECK-NEXT: 0000: FFFFFFFF FFFFFFFF 00000000 00000000 +// CHECK-NEXT: 0010: 00000000 00000000 EEEEEEEE EEEEEEEE +// CHECK-NEXT: 0020: DDDDDDDD DDDDDDDD +// CHECK-NEXT: )