diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d25ce3165bd79..0ebab141b187d 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; diff --git a/clang/test/CodeGen/cfi-icall-generalize.c b/clang/test/CodeGen/cfi-icall-generalize.c index 46d38511ba6b6..5995540ba33fb 100644 --- a/clang/test/CodeGen/cfi-icall-generalize.c +++ b/clang/test/CodeGen/cfi-icall-generalize.c @@ -22,14 +22,14 @@ union Union { // CHECK: define{{.*}} void @uni({{.*}} !type [[TYPE2:![0-9]+]] !type [[TYPE2_GENERALIZED:![0-9]+]] void uni(void (*fn)(union Union), union Union arg1) { - // UNGENERALIZED: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFv5UnionE") - // GENERALIZED: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFv5UnionE.generalized") + // UNGENERALIZED: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFvPcE") + // GENERALIZED: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFvPvE.generalized") fn(arg1); } // CHECK: [[TYPE]] = !{i64 0, !"_ZTSFPPiPKcPS2_E"} // CHECK: [[TYPE_GENERALIZED]] = !{i64 0, !"_ZTSFPvPKvS_E.generalized"} -// CHECK: [[TYPE2]] = !{i64 0, !"_ZTSFvPFv5UnionES_E"} -// CHECK: [[TYPE2_GENERALIZED]] = !{i64 0, !"_ZTSFvPv5UnionE.generalized"} +// CHECK: [[TYPE2]] = !{i64 0, !"_ZTSFvPFv5UnionEPcE"} +// 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 5e457dc97f0a2..9fa6f95e523d7 100644 --- a/clang/test/CodeGen/cfi-icall-normalize2.c +++ b/clang/test/CodeGen/cfi-icall-normalize2.c @@ -32,12 +32,12 @@ union Union { void uni(void (*fn)(union Union), union Union arg1) { // CHECK-LABEL: define{{.*}}uni // CHECK-SAME: {{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}} - // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv5UnionE.normalized") + // CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvPu2i8E.normalized") fn(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, !"_ZTSFvPFv5UnionES_E.normalized"} +// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPFv5UnionEPu2i8E.normalized"} diff --git a/clang/test/CodeGen/kcfi-generalize.c b/clang/test/CodeGen/kcfi-generalize.c index 864cdb8c2e092..5a44d97412af9 100644 --- a/clang/test/CodeGen/kcfi-generalize.c +++ b/clang/test/CodeGen/kcfi-generalize.c @@ -33,8 +33,8 @@ union Union { // CHECK: define{{.*}} void @uni({{.*}} !kcfi_type [[TYPE4:![0-9]+]] void uni(void (*fn)(union Union), union Union arg1) { - // UNGENERALIZED: call {{.*}} [ "kcfi"(i32 -1037059548) ] - // GENERALIZED: call {{.*}} [ "kcfi"(i32 422130955) ] + // UNGENERALIZED: call {{.*}} [ "kcfi"(i32 -587217045) ] + // GENERALIZED: call {{.*}} [ "kcfi"(i32 2139530422) ] fn(arg1); } @@ -44,6 +44,5 @@ void uni(void (*fn)(union Union), union Union arg1) { // UNGENERALIZED: [[TYPE3]] = !{i32 874141567} // GENERALIZED: [[TYPE3]] = !{i32 954385378} -// UNGENERALIZED: [[TYPE4]] = !{i32 981319178} -// GENERALIZED: [[TYPE4]] = !{i32 -1599950473} - +// UNGENERALIZED: [[TYPE4]] = !{i32 -1619636625} +// GENERALIZED: [[TYPE4]] = !{i32 -125078496} diff --git a/clang/test/CodeGen/kcfi-normalize.c b/clang/test/CodeGen/kcfi-normalize.c index 9291ff8529b31..bd87f4af534a1 100644 --- a/clang/test/CodeGen/kcfi-normalize.c +++ b/clang/test/CodeGen/kcfi-normalize.c @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -x c++ -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -o - %s | FileCheck %s --check-prefixes=CHECK,C +// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -x c++ -o - %s | FileCheck %s --check-prefixes=CHECK,CPP #if !__has_feature(kcfi) #error Missing kcfi? #endif @@ -36,7 +36,8 @@ union Union { void uni(void (*fn)(union Union), union Union arg1) { // CHECK-LABEL: define{{.*}}uni // CHECK-SAME: {{.*}}!kcfi_type ![[TYPE4:[0-9]+]] - // CHECK: call void %0(ptr %1) [ "kcfi"(i32 -1430221633) ] + // C: call void %0(ptr %1) [ "kcfi"(i32 1819770848) ] + // CPP: call void %0(ptr %1) [ "kcfi"(i32 -1430221633) ] fn(arg1); } @@ -44,5 +45,5 @@ void uni(void (*fn)(union Union), union Union arg1) { // CHECK: ![[TYPE1]] = !{i32 -1143117868} // CHECK: ![[TYPE2]] = !{i32 -460921415} // CHECK: ![[TYPE3]] = !{i32 -333839615} -// CHECK: ![[TYPE4]] = !{i32 1766237188} - +// C: ![[TYPE4]] = !{i32 -650530463} +// CPP: ![[TYPE4]] = !{i32 1766237188}