================ @@ -450,6 +453,116 @@ class StmtComparer { }; } // namespace +static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, + const Attr *Attr1, const Attr *Attr2) { + // Two attributes are structurally equivalent if they are the same kind + // of attribute, spelled with the same spelling kind, and have the same + // arguments. This means that [[noreturn]] and __attribute__((noreturn)) are + // not structurally equivalent, nor are [[nodiscard("foo")]] and + // [[nodiscard("bar")]]. + if (Attr1->getKind() != Attr2->getKind()) + return false; + + if (Attr1->getSyntax() != Attr2->getSyntax()) + return false; + + if (Attr1->getSpellingListIndex() != Attr2->getSpellingListIndex()) + return false; + + auto GetAttrName = [](const Attr *A) { + if (const IdentifierInfo *II = A->getAttrName()) + return II->getName(); + return StringRef{}; + }; + + if (GetAttrName(Attr1) != GetAttrName(Attr2)) + return false; + + // FIXME: check the attribute arguments. Attr does not track the arguments on + // the base class, which makes this awkward. We may want to tablegen a + // comparison function for attributes? In the meantime, we're doing this the + // cheap way by pretty printing the attributes and checking they produce ---------------- AaronBallman wrote:
Please try to engage in the discussion in good faith rather than with snark. The standard says (C23 6.2.7p1) "Two types are compatible types if they are the same." and then gives additional restrictions on what makes two types [in]compatible. At the end of the paragraph it says "Otherwise, the structure, union, or enumerated types are incompatible.". So the default is that two types are never compatible unless they meet a list of explicit criteria. That criteria does not mention attributes. The high-level decision tree is: are the two types the same? If not, do the two types meet these additional explicitly listed requirements? If not, they're not compatible. So either this situation is UB by omission because the standard doesn't say what to do with attributes or two tag types are never compatible in the presence of attributes because they're not listed as an exception to the "same type" general rule. UB by omission seems more reasonable to me as it gives implementations the freedom to decide what is and isn't sufficiently compatible, which is needed anyway for vendor attributes. (And again, the ideal goal here is to eventually let attributes handle this on an attribute-by-attribute basis.) https://github.com/llvm/llvm-project/pull/132939 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits