|
7 | 7 | //===----------------------------------------------------------------------===// |
8 | 8 |
|
9 | 9 | #include "llvm/MC/MCExpr.h" |
| 10 | +#include "llvm/ADT/ScopeExit.h" |
10 | 11 | #include "llvm/ADT/Statistic.h" |
11 | 12 | #include "llvm/Config/llvm-config.h" |
12 | 13 | #include "llvm/MC/MCAsmBackend.h" |
@@ -497,13 +498,25 @@ bool MCExpr::evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm, |
497 | 498 |
|
498 | 499 | case SymbolRef: { |
499 | 500 | const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this); |
500 | | - const MCSymbol &Sym = SRE->getSymbol(); |
| 501 | + MCSymbol &Sym = const_cast<MCSymbol &>(SRE->getSymbol()); |
501 | 502 | const auto Kind = SRE->getKind(); |
502 | 503 | bool Layout = Asm && Asm->hasLayout(); |
503 | 504 |
|
504 | 505 | // Evaluate recursively if this is a variable. |
| 506 | + if (Sym.isResolving()) { |
| 507 | + if (Asm && Asm->hasFinalLayout()) { |
| 508 | + Asm->getContext().reportError( |
| 509 | + Sym.getVariableValue()->getLoc(), |
| 510 | + "cyclic dependency detected for symbol '" + Sym.getName() + "'"); |
| 511 | + Sym.IsUsed = false; |
| 512 | + Sym.setVariableValue(MCConstantExpr::create(0, Asm->getContext())); |
| 513 | + } |
| 514 | + return false; |
| 515 | + } |
505 | 516 | if (Sym.isVariable() && (Kind == MCSymbolRefExpr::VK_None || Layout) && |
506 | 517 | canExpand(Sym, InSet)) { |
| 518 | + Sym.setIsResolving(true); |
| 519 | + auto _ = make_scope_exit([&] { Sym.setIsResolving(false); }); |
507 | 520 | bool IsMachO = |
508 | 521 | Asm && Asm->getContext().getAsmInfo()->hasSubsectionsViaSymbols(); |
509 | 522 | if (Sym.getVariableValue()->evaluateAsRelocatableImpl(Res, Asm, |
@@ -709,9 +722,16 @@ MCFragment *MCExpr::findAssociatedFragment() const { |
709 | 722 | return MCSymbol::AbsolutePseudoFragment; |
710 | 723 |
|
711 | 724 | case SymbolRef: { |
712 | | - const MCSymbolRefExpr *SRE = cast<MCSymbolRefExpr>(this); |
713 | | - const MCSymbol &Sym = SRE->getSymbol(); |
714 | | - return Sym.getFragment(); |
| 725 | + auto &Sym = |
| 726 | + const_cast<MCSymbol &>(cast<MCSymbolRefExpr>(this)->getSymbol()); |
| 727 | + if (Sym.Fragment) |
| 728 | + return Sym.Fragment; |
| 729 | + if (Sym.isResolving()) |
| 730 | + return MCSymbol::AbsolutePseudoFragment; |
| 731 | + Sym.setIsResolving(true); |
| 732 | + auto *F = Sym.getFragment(); |
| 733 | + Sym.setIsResolving(false); |
| 734 | + return F; |
715 | 735 | } |
716 | 736 |
|
717 | 737 | case Unary: |
|
0 commit comments