diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp index 4bcb541156bd2..6eed8e1d2b671 100644 --- a/clang/lib/CodeGen/CodeGenTBAA.cpp +++ b/clang/lib/CodeGen/CodeGenTBAA.cpp @@ -246,7 +246,22 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) { // Be conservative if the type isn't a RecordType. We are specifically // required to do this for member pointers until we implement the // similar-types rule. - if (!Ty->isRecordType()) + const auto *RT = Ty->getAs(); + if (!RT) + return AnyPtr; + + // For unnamed structs or unions C's compatible types rule applies. Two + // compatible types in different compilation units can have different + // mangled names, meaning the metadata emitted below would incorrectly + // mark them as no-alias. Use AnyPtr for such types in both C and C++, as + // C and C++ types may be visible when doing LTO. + // + // Note that using AnyPtr is overly conservative. We could summarize the + // members of the type, as per the C compatibility rule in the future. + // This also covers anonymous structs and unions, which have a different + // compatibility rule, but it doesn't matter because you can never have a + // pointer to an anonymous struct or union. + if (!RT->getDecl()->getDeclName()) return AnyPtr; // For non-builtin types use the mangled name of the canonical type. diff --git a/clang/test/CodeGen/tbaa-pointers.c b/clang/test/CodeGen/tbaa-pointers.c index 9417a0e2f09e8..068459f4dce11 100644 --- a/clang/test/CodeGen/tbaa-pointers.c +++ b/clang/test/CodeGen/tbaa-pointers.c @@ -190,8 +190,6 @@ typedef struct { int i1; } TypedefS; -// FIXME: The !tbaa tag for unnamed structs doesn't account for compatible -// types in C. void unamed_struct_typedef(TypedefS *ptr) { // COMMON-LABEL: define void @unamed_struct_typedef( // COMMON-SAME: ptr noundef [[PTRA:%.+]]) @@ -238,5 +236,4 @@ void unamed_struct_typedef(TypedefS *ptr) { // DEFAULT: [[S2_TY]] = !{!"S2", [[ANY_POINTER]], i64 0} // COMMON: [[INT_TAG]] = !{[[INT_TY:!.+]], [[INT_TY]], i64 0} // COMMON: [[INT_TY]] = !{!"int", [[CHAR]], i64 0} -// ENABLED: [[P1TYPEDEF]] = !{[[P1TYPEDEF_TY:!.+]], [[P1TYPEDEF_TY]], i64 0} -// ENABLED: [[P1TYPEDEF_TY]] = !{!"p1 _ZTS8TypedefS", [[ANY_POINTER]], i64 0} +// ENABLED: [[P1TYPEDEF]] = !{[[ANY_POINTER]], [[ANY_POINTER]], i64 0}