llvm.org GIT mirror llvm / 6bd41df
TableGen: Explicitly forbid self-references to field members Summary: Otherwise, patterns like in the test case produce cryptic error messages about fields being resolved incompletely. Change-Id: I713c0191f00fe140ad698675803ab1f8823dc5bd Reviewers: arsenm, craig.topper, tra, MartinO Subscribers: wdng, llvm-commits Differential Revision: https://reviews.llvm.org/D44476 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327850 91177308-0d34-0410-b5e6-96231b3b80d8 Nicolai Haehnle 1 year, 6 months ago
4 changed file(s) with 20 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
11991199 Init *getBit(unsigned Bit) const override;
12001200
12011201 Init *resolveReferences(Resolver &R) const override;
1202 Init *Fold() const;
1202 Init *Fold(Record *CurRec) const;
12031203
12041204 std::string getAsString() const override {
12051205 return Rec->getAsString() + "." + FieldName->getValue().str();
16831683 Init *FieldInit::resolveReferences(Resolver &R) const {
16841684 Init *NewRec = Rec->resolveReferences(R);
16851685 if (NewRec != Rec)
1686 return FieldInit::get(NewRec, FieldName)->Fold();
1686 return FieldInit::get(NewRec, FieldName)->Fold(R.getCurrentRecord());
16871687 return const_cast(this);
16881688 }
16891689
1690 Init *FieldInit::Fold() const {
1690 Init *FieldInit::Fold(Record *CurRec) const {
16911691 if (DefInit *DI = dyn_cast(Rec)) {
1692 Init *FieldVal = DI->getDef()->getValue(FieldName)->getValue();
1692 Record *Def = DI->getDef();
1693 if (Def == CurRec)
1694 PrintFatalError(CurRec->getLoc(),
1695 Twine("Attempting to access field '") +
1696 FieldName->getAsUnquotedString() + "' of '" +
1697 Rec->getAsString() + "' is a forbidden self-reference");
1698 Init *FieldVal = Def->getValue(FieldName)->getValue();
16931699 if (FieldVal->isComplete())
16941700 return FieldVal;
16951701 }
19421942 Result->getAsString() + "'");
19431943 return nullptr;
19441944 }
1945 Result = FieldInit::get(Result, FieldName)->Fold();
1945 Result = FieldInit::get(Result, FieldName)->Fold(CurRec);
19461946 Lex.Lex(); // eat field name
19471947 break;
19481948 }
0 // RUN: not llvm-tblgen %s 2>&1 | FileCheck %s
1 // XFAIL: vg_leak
2
3 class A {
4 int x = !cast(self).x;
5 }
6
7 // CHECK: error: Attempting to access field 'x' of 'A0' is a forbidden self-reference
8 def A0 : A<"A0">;