tahonermann marked 2 inline comments as done. tahonermann added inline comments.
================ Comment at: clang/lib/Sema/SemaTemplate.cpp:10110-10111 + // propagated to the new node prior to instantiation. + if (PrevDecl && PrevDecl->hasAttr<MSInheritanceAttr>()) { + Specialization->addAttr(PrevDecl->getAttr<MSInheritanceAttr>()); + Consumer.AssignInheritanceModel(Specialization); ---------------- rnk wrote: > `hasAttr()` is O(n) in the attribute list size, so I would recommend this > pattern: > ``` > if (PrevDecl) { > if (const auto *A = PrevDecl->getAttr<MSInheritanceAttr>()) { > Specialization->addAttr(A); > ... > ``` Sounds good, I'll make that change. ================ Comment at: clang/lib/Sema/SemaTemplate.cpp:10112 + Specialization->addAttr(PrevDecl->getAttr<MSInheritanceAttr>()); + Consumer.AssignInheritanceModel(Specialization); + } ---------------- rnk wrote: > tahonermann wrote: > > erichkeane wrote: > > > tahonermann wrote: > > > > I am concerned that moving the call to > > > > `Consumer.AssignInheritanceModel()` to immediately after the creation > > > > of the node, but before it is populated might be problematic. > > > > Previously, this call was still made before the node was completely > > > > constructed (e.g., before `setTemplateSpecializationKind()` is called > > > > for it). It is difficult to tell if any consumers might be dependent on > > > > more of the definition being present. > > > SO I think we still need to do this off of the definition, right? Else > > > if `PrevDecl` ends up being a declaration (followed later by a definition > > > that has the attribute), we'll end up missing it? Typically attributes > > > are 'added' by later decls, so only the 'latest one' (though attributes > > > can't be added after definition IIRC) has 'them all'. > > This handles the situation where a new node is created for either an > > explicit template instantiation declaration or definition; that matches > > prior behavior. The goal is to ensure each node, regardless of the reason > > for its creation, inherits the attribute from the previous declaration; > > that ensures that any explicitly declared attributes are checked for > > consistency (see `Sema::mergeMSInheritanceAttr()`). > > > > Note that an explicit class template specialization is not allowed to > > follow an explicit template instantiation declaration or definition. > > https://godbolt.org/z/cbvaac717. > I think it is safe to call `AssignInheritanceModel` earlier. We mostly just > use it to invalidate some clang AST -> LLVM IR type translation cache. Great, thank you for confirming that. ================ Comment at: clang/test/CodeGenCXX/microsoft-abi-member-pointers.cpp:958 +extern template class a<int>; +template class a<int>; +} ---------------- rnk wrote: > My expectation here is that we assign the unknown inheritance model to > `a<int>`, is that right? Can you add a static_assert to that effect, or add > some CHECK lines for the structure, maybe make an alloca of type `void > (a<int>::*var)()` and check for the allocated type (it should be a struct > with a pointer with lots of i32s)? Yes, when a pointer to member is formed for an incomplete class, in the absence of a `#pragma pointers_to_members` directive, use of inheritance keywords like `__single_inheritance`, or use of the `/vmb` or `/vmg` options (or equivalents), the "full_generality" / "virtual_inheritance" model is selected. I did verify that manually. I can add a `static_assert` so long as it follows the explicit template instantiation definition. If it is placed earlier, then code related to obtaining a complete type is run and that ends up avoiding the assertion failure. See https://godbolt.org/z/qzTTfdfY1. This might indicate there is a bug elsewhere; I find it surprising that the early `static_assert` has that effect. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D158869/new/ https://reviews.llvm.org/D158869 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits