Skip to content
Merged
15 changes: 14 additions & 1 deletion clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<TransparentUnionAttr>())
return Ty;
for (const auto *it : UD->fields()) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was it intentional to use a range based for loop here only to unconditionally return in the body?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The meaning is as intended, I think. Maybe something like if (!UD->fields().empty()) return UD->fields()[0]; would be better style.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, an if statement would signal intent better.

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;
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGen/cfi-icall-generalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"}

4 changes: 2 additions & 2 deletions clang/test/CodeGen/cfi-icall-normalize2.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"}

9 changes: 4 additions & 5 deletions clang/test/CodeGen/kcfi-generalize.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand All @@ -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}
11 changes: 6 additions & 5 deletions clang/test/CodeGen/kcfi-normalize.c
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -36,13 +36,14 @@ 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);
}

// CHECK: ![[#]] = !{i32 4, !"cfi-normalize-integers", i32 1}
// CHECK: ![[TYPE1]] = !{i32 -1143117868}
// CHECK: ![[TYPE2]] = !{i32 -460921415}
// CHECK: ![[TYPE3]] = !{i32 -333839615}
// CHECK: ![[TYPE4]] = !{i32 1766237188}

// C: ![[TYPE4]] = !{i32 -650530463}
// CPP: ![[TYPE4]] = !{i32 1766237188}
Loading