From 004f209199d53a0c7a00ca7af4446407da4c9fb1 Mon Sep 17 00:00:00 2001 From: Vitaly Buka Date: Fri, 12 Sep 2025 19:18:58 -0700 Subject: [CodeGen][CFI] Generalize transparent union parameters (#158193) According GCC documentation transparent union calling convention is the same as the type of the first member of the union. C++ ignores attribute. Note, it does not generalize args of function pointer args. It's unnecessary with pointer generalization. It will be fixed in followup patch. --------- Co-authored-by: lntue --- clang/lib/CodeGen/CodeGenModule.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'clang/lib/CodeGen/CodeGenModule.cpp') diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d25ce31..0ebab14 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2339,13 +2339,26 @@ llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) { return llvm::ConstantInt::get(Int64Ty, llvm::MD5Hash(MDS->getString())); } +static QualType GeneralizeTransparentUnion(QualType Ty) { + const RecordType *UT = Ty->getAsUnionType(); + if (!UT) + return Ty; + const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf(); + if (!UD->hasAttr()) + return Ty; + for (const auto *it : UD->fields()) { + return it->getType(); + } + return Ty; +} + // If `GeneralizePointers` is true, generalizes types to a void pointer with the // qualifiers of the originally pointed-to type, e.g. 'const char *' and 'char * // const *' generalize to 'const void *' while 'char *' and 'const char **' // generalize to 'void *'. static QualType GeneralizeType(ASTContext &Ctx, QualType Ty, bool GeneralizePointers) { - // TODO: Add other generalizations. + Ty = GeneralizeTransparentUnion(Ty); if (!GeneralizePointers || !Ty->isPointerType()) return Ty; -- cgit v1.1