Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 004f209

Browse files
vitalybukalntue
andauthored
[CodeGen][CFI] Generalize transparent union parameters (llvm#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 <[email protected]>
1 parent 0ca54d7 commit 004f209

File tree

5 files changed

+30
-17
lines changed

5 files changed

+30
-17
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2339,13 +2339,26 @@ llvm::ConstantInt *CodeGenModule::CreateCrossDsoCfiTypeId(llvm::Metadata *MD) {
23392339
return llvm::ConstantInt::get(Int64Ty, llvm::MD5Hash(MDS->getString()));
23402340
}
23412341

2342+
static QualType GeneralizeTransparentUnion(QualType Ty) {
2343+
const RecordType *UT = Ty->getAsUnionType();
2344+
if (!UT)
2345+
return Ty;
2346+
const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
2347+
if (!UD->hasAttr<TransparentUnionAttr>())
2348+
return Ty;
2349+
for (const auto *it : UD->fields()) {
2350+
return it->getType();
2351+
}
2352+
return Ty;
2353+
}
2354+
23422355
// If `GeneralizePointers` is true, generalizes types to a void pointer with the
23432356
// qualifiers of the originally pointed-to type, e.g. 'const char *' and 'char *
23442357
// const *' generalize to 'const void *' while 'char *' and 'const char **'
23452358
// generalize to 'void *'.
23462359
static QualType GeneralizeType(ASTContext &Ctx, QualType Ty,
23472360
bool GeneralizePointers) {
2348-
// TODO: Add other generalizations.
2361+
Ty = GeneralizeTransparentUnion(Ty);
23492362

23502363
if (!GeneralizePointers || !Ty->isPointerType())
23512364
return Ty;

clang/test/CodeGen/cfi-icall-generalize.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,14 @@ union Union {
2222

2323
// CHECK: define{{.*}} void @uni({{.*}} !type [[TYPE2:![0-9]+]] !type [[TYPE2_GENERALIZED:![0-9]+]]
2424
void uni(void (*fn)(union Union), union Union arg1) {
25-
// UNGENERALIZED: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFv5UnionE")
26-
// GENERALIZED: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFv5UnionE.generalized")
25+
// UNGENERALIZED: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFvPcE")
26+
// GENERALIZED: call i1 @llvm.type.test(ptr {{.*}}, metadata !"_ZTSFvPvE.generalized")
2727
fn(arg1);
2828
}
2929

3030
// CHECK: [[TYPE]] = !{i64 0, !"_ZTSFPPiPKcPS2_E"}
3131
// CHECK: [[TYPE_GENERALIZED]] = !{i64 0, !"_ZTSFPvPKvS_E.generalized"}
3232

33-
// CHECK: [[TYPE2]] = !{i64 0, !"_ZTSFvPFv5UnionES_E"}
34-
// CHECK: [[TYPE2_GENERALIZED]] = !{i64 0, !"_ZTSFvPv5UnionE.generalized"}
33+
// CHECK: [[TYPE2]] = !{i64 0, !"_ZTSFvPFv5UnionEPcE"}
34+
// CHECK: [[TYPE2_GENERALIZED]] = !{i64 0, !"_ZTSFvPvS_E.generalized"}
3535

clang/test/CodeGen/cfi-icall-normalize2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ union Union {
3232
void uni(void (*fn)(union Union), union Union arg1) {
3333
// CHECK-LABEL: define{{.*}}uni
3434
// CHECK-SAME: {{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}}
35-
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFv5UnionE.normalized")
35+
// CHECK: call i1 @llvm.type.test({{i8\*|ptr}} {{%f|%0}}, metadata !"_ZTSFvPu2i8E.normalized")
3636
fn(arg1);
3737
}
3838

3939
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFvu3i32ES_E.normalized"}
4040
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFvu3i32S_ES_S_E.normalized"}
4141
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFvu3i32S_S_ES_S_S_E.normalized"}
42-
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPFv5UnionES_E.normalized"}
42+
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvPFv5UnionEPu2i8E.normalized"}
4343

clang/test/CodeGen/kcfi-generalize.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ union Union {
3333

3434
// CHECK: define{{.*}} void @uni({{.*}} !kcfi_type [[TYPE4:![0-9]+]]
3535
void uni(void (*fn)(union Union), union Union arg1) {
36-
// UNGENERALIZED: call {{.*}} [ "kcfi"(i32 -1037059548) ]
37-
// GENERALIZED: call {{.*}} [ "kcfi"(i32 422130955) ]
36+
// UNGENERALIZED: call {{.*}} [ "kcfi"(i32 -587217045) ]
37+
// GENERALIZED: call {{.*}} [ "kcfi"(i32 2139530422) ]
3838
fn(arg1);
3939
}
4040

@@ -44,6 +44,5 @@ void uni(void (*fn)(union Union), union Union arg1) {
4444
// UNGENERALIZED: [[TYPE3]] = !{i32 874141567}
4545
// GENERALIZED: [[TYPE3]] = !{i32 954385378}
4646

47-
// UNGENERALIZED: [[TYPE4]] = !{i32 981319178}
48-
// GENERALIZED: [[TYPE4]] = !{i32 -1599950473}
49-
47+
// UNGENERALIZED: [[TYPE4]] = !{i32 -1619636625}
48+
// GENERALIZED: [[TYPE4]] = !{i32 -125078496}

clang/test/CodeGen/kcfi-normalize.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm -fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers -o - %s | FileCheck %s
2-
// 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
1+
// 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
2+
// 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
33
#if !__has_feature(kcfi)
44
#error Missing kcfi?
55
#endif
@@ -36,13 +36,14 @@ union Union {
3636
void uni(void (*fn)(union Union), union Union arg1) {
3737
// CHECK-LABEL: define{{.*}}uni
3838
// CHECK-SAME: {{.*}}!kcfi_type ![[TYPE4:[0-9]+]]
39-
// CHECK: call void %0(ptr %1) [ "kcfi"(i32 -1430221633) ]
39+
// C: call void %0(ptr %1) [ "kcfi"(i32 1819770848) ]
40+
// CPP: call void %0(ptr %1) [ "kcfi"(i32 -1430221633) ]
4041
fn(arg1);
4142
}
4243

4344
// CHECK: ![[#]] = !{i32 4, !"cfi-normalize-integers", i32 1}
4445
// CHECK: ![[TYPE1]] = !{i32 -1143117868}
4546
// CHECK: ![[TYPE2]] = !{i32 -460921415}
4647
// CHECK: ![[TYPE3]] = !{i32 -333839615}
47-
// CHECK: ![[TYPE4]] = !{i32 1766237188}
48-
48+
// C: ![[TYPE4]] = !{i32 -650530463}
49+
// CPP: ![[TYPE4]] = !{i32 1766237188}

0 commit comments

Comments
 (0)