diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 8065165b308da..459206a62cc94 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2352,6 +2352,9 @@ static QualType GeneralizeTransparentUnion(QualType Ty) { return Ty; } +static QualType GeneralizeFunctionType(ASTContext &Ctx, QualType Ty, + bool GeneralizePointers); + // Generalize pointer 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 @@ -2360,12 +2363,19 @@ static QualType GeneralizeType(ASTContext &Ctx, QualType Ty, bool GeneralizePointers) { Ty = GeneralizeTransparentUnion(Ty); - if (!GeneralizePointers || !Ty->isPointerType()) + if (!Ty->isPointerType()) + return Ty; + + QualType PTy = Ty->getPointeeType(); + if (PTy->getAs() || PTy->getAs()) + Ty = Ctx.getPointerType( + GeneralizeFunctionType(Ctx, PTy, GeneralizePointers)); + + if (!GeneralizePointers) return Ty; return Ctx.getPointerType( - QualType(Ctx.VoidTy) - .withCVRQualifiers(Ty->getPointeeType().getCVRQualifiers())); + QualType(Ctx.VoidTy).withCVRQualifiers(PTy.getCVRQualifiers())); } // Apply type generalization to a FunctionType's return and argument types diff --git a/clang/test/CodeGen/cfi-icall-generalize.c b/clang/test/CodeGen/cfi-icall-generalize.c index 5995540ba33fb..7c2a027f46d2f 100644 --- a/clang/test/CodeGen/cfi-icall-generalize.c +++ b/clang/test/CodeGen/cfi-icall-generalize.c @@ -30,6 +30,6 @@ void uni(void (*fn)(union Union), union Union arg1) { // CHECK: [[TYPE]] = !{i64 0, !"_ZTSFPPiPKcPS2_E"} // CHECK: [[TYPE_GENERALIZED]] = !{i64 0, !"_ZTSFPvPKvS_E.generalized"} -// CHECK: [[TYPE2]] = !{i64 0, !"_ZTSFvPFv5UnionEPcE"} +// CHECK: [[TYPE2]] = !{i64 0, !"_ZTSFvPFvPcES_E"} // CHECK: [[TYPE2_GENERALIZED]] = !{i64 0, !"_ZTSFvPvS_E.generalized"} diff --git a/clang/test/CodeGen/cfi-icall-normalize2.c b/clang/test/CodeGen/cfi-icall-normalize2.c index 9fa6f95e523d7..c60d1f0a12431 100644 --- a/clang/test/CodeGen/cfi-icall-normalize2.c +++ b/clang/test/CodeGen/cfi-icall-normalize2.c @@ -39,5 +39,5 @@ void uni(void (*fn)(union Union), union Union arg1) { // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFvu3i32ES_E.normalized"} // CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"} // CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"} -// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPFv5UnionEPu2i8E.normalized"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPFvPu2i8ES0_E.normalized"} diff --git a/clang/test/CodeGen/kcfi-generalize.c b/clang/test/CodeGen/kcfi-generalize.c index 5a44d97412af9..6ac762ccc25c3 100644 --- a/clang/test/CodeGen/kcfi-generalize.c +++ b/clang/test/CodeGen/kcfi-generalize.c @@ -44,5 +44,5 @@ void uni(void (*fn)(union Union), union Union arg1) { // UNGENERALIZED: [[TYPE3]] = !{i32 874141567} // GENERALIZED: [[TYPE3]] = !{i32 954385378} -// UNGENERALIZED: [[TYPE4]] = !{i32 -1619636625} +// UNGENERALIZED: [[TYPE4]] = !{i32 -1954865805} // GENERALIZED: [[TYPE4]] = !{i32 -125078496} diff --git a/clang/test/CodeGen/kcfi-normalize.c b/clang/test/CodeGen/kcfi-normalize.c index bd87f4af534a1..954734c6f3552 100644 --- a/clang/test/CodeGen/kcfi-normalize.c +++ b/clang/test/CodeGen/kcfi-normalize.c @@ -45,5 +45,5 @@ void uni(void (*fn)(union Union), union Union arg1) { // CHECK: ![[TYPE1]] = !{i32 -1143117868} // CHECK: ![[TYPE2]] = !{i32 -460921415} // CHECK: ![[TYPE3]] = !{i32 -333839615} -// C: ![[TYPE4]] = !{i32 -650530463} +// C: ![[TYPE4]] = !{i32 1186327125} // CPP: ![[TYPE4]] = !{i32 1766237188}