Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 71c7313

Browse files
rcvallesamitolvanen
authored andcommittedFeb 8, 2023
Add CFI integer types normalization
This commit adds a new option (i.e., `-fsanitize-cfi-icall-normalize-integers`) for normalizing integer types as vendor extended types for cross-language LLVM CFI/KCFI support with other languages that can't represent and encode C/C++ integer types. Specifically, integer types are encoded as their defined representations (e.g., 8-bit signed integer, 16-bit signed integer, 32-bit signed integer, ...) for compatibility with languages that define explicitly-sized integer types (e.g., i8, i16, i32, ..., in Rust). ``-fsanitize-cfi-icall-normalize-integers`` is compatible with ``-fsanitize-cfi-icall-generalize-pointers``. This helps with providing cross-language CFI support with the Rust compiler and is an alternative solution for the issue described and alternatives proposed in the RFC rust-lang/rfcs#3296. For more information about LLVM CFI/KCFI and cross-language LLVM CFI/KCFI support for the Rust compiler, see the design document in the tracking issue rust-lang/rust#89653. Relands b1e9ab7 with fixes. Reviewed By: pcc, samitolvanen Differential Revision: https://reviews.llvm.org/D139395
1 parent cf73d3f commit 71c7313

13 files changed

+300
-16
lines changed
 

‎clang/docs/ControlFlowIntegrity.rst

+19
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,25 @@ long as the qualifiers for the type they point to match. For example, ``char*``,
236236
``-fsanitize-cfi-icall-generalize-pointers`` is not compatible with
237237
``-fsanitize-cfi-cross-dso``.
238238

239+
.. _cfi-icall-experimental-normalize-integers:
240+
241+
``-fsanitize-cfi-icall-experimental-normalize-integers``
242+
--------------------------------------------------------
243+
244+
This option enables normalizing integer types as vendor extended types for
245+
cross-language LLVM CFI/KCFI support with other languages that can't represent
246+
and encode C/C++ integer types.
247+
248+
Specifically, integer types are encoded as their defined representations (e.g.,
249+
8-bit signed integer, 16-bit signed integer, 32-bit signed integer, ...) for
250+
compatibility with languages that define explicitly-sized integer types (e.g.,
251+
i8, i16, i32, ..., in Rust).
252+
253+
``-fsanitize-cfi-icall-experimental-normalize-integers`` is compatible with
254+
``-fsanitize-cfi-icall-generalize-pointers``.
255+
256+
This option is currently experimental.
257+
239258
.. _cfi-canonical-jump-tables:
240259

241260
``-fsanitize-cfi-canonical-jump-tables``

‎clang/docs/UsersManual.rst

+8
Original file line numberDiff line numberDiff line change
@@ -1992,6 +1992,14 @@ are listed below.
19921992
checked by Control Flow Integrity indirect call checking. See
19931993
:doc:`ControlFlowIntegrity` for more details.
19941994

1995+
.. option:: -fsanitize-cfi-icall-experimental-normalize-integers
1996+
1997+
Normalize integers in return and argument types in function type signatures
1998+
checked by Control Flow Integrity indirect call checking. See
1999+
:doc:`ControlFlowIntegrity` for more details.
2000+
2001+
This option is currently experimental.
2002+
19952003
.. option:: -fstrict-vtable-pointers
19962004

19972005
Enable optimizations based on the strict rules for overwriting polymorphic

‎clang/include/clang/AST/Mangle.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ class MangleContext {
140140
unsigned ManglingNumber,
141141
raw_ostream &) = 0;
142142
virtual void mangleCXXRTTI(QualType T, raw_ostream &) = 0;
143-
virtual void mangleCXXRTTIName(QualType T, raw_ostream &) = 0;
143+
virtual void mangleCXXRTTIName(QualType T, raw_ostream &,
144+
bool NormalizeIntegers = false) = 0;
144145
virtual void mangleStringLiteral(const StringLiteral *SL, raw_ostream &) = 0;
145146
virtual void mangleMSGuidDecl(const MSGuidDecl *GD, raw_ostream&);
146147

@@ -177,7 +178,8 @@ class MangleContext {
177178
/// or type uniquing.
178179
/// TODO: Extend this to internal types by generating names that are unique
179180
/// across translation units so it can be used with LTO.
180-
virtual void mangleTypeName(QualType T, raw_ostream &) = 0;
181+
virtual void mangleTypeName(QualType T, raw_ostream &,
182+
bool NormalizeIntegers = false) = 0;
181183

182184
/// @}
183185
};

‎clang/include/clang/Basic/CodeGenOptions.def

+2
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ CODEGENOPT(SanitizeMinimalRuntime, 1, 0) ///< Use "_minimal" sanitizer runtime f
257257
///< diagnostics.
258258
CODEGENOPT(SanitizeCfiICallGeneralizePointers, 1, 0) ///< Generalize pointer types in
259259
///< CFI icall function signatures
260+
CODEGENOPT(SanitizeCfiICallNormalizeIntegers, 1, 0) ///< Normalize integer types in
261+
///< CFI icall function signatures
260262
CODEGENOPT(SanitizeCfiCanonicalJumpTables, 1, 0) ///< Make jump table symbols canonical
261263
///< instead of creating a local jump table.
262264
CODEGENOPT(SanitizeCoverageType, 2, 0) ///< Type of sanitizer coverage

‎clang/include/clang/Driver/Options.td

+4
Original file line numberDiff line numberDiff line change
@@ -1900,6 +1900,10 @@ def fsanitize_cfi_icall_generalize_pointers : Flag<["-"], "fsanitize-cfi-icall-g
19001900
Group<f_clang_Group>,
19011901
HelpText<"Generalize pointers in CFI indirect call type signature checks">,
19021902
MarshallingInfoFlag<CodeGenOpts<"SanitizeCfiICallGeneralizePointers">>;
1903+
def fsanitize_cfi_icall_normalize_integers : Flag<["-"], "fsanitize-cfi-icall-experimental-normalize-integers">,
1904+
Group<f_clang_Group>,
1905+
HelpText<"Normalize integers in CFI indirect call type signature checks">,
1906+
MarshallingInfoFlag<CodeGenOpts<"SanitizeCfiICallNormalizeIntegers">>;
19031907
defm sanitize_cfi_canonical_jump_tables : BoolOption<"f", "sanitize-cfi-canonical-jump-tables",
19041908
CodeGenOpts<"SanitizeCfiCanonicalJumpTables">, DefaultFalse,
19051909
PosFlag<SetTrue, [], "Make">, NegFlag<SetFalse, [CoreOption, NoXarchOption], "Do not make">,

‎clang/include/clang/Driver/SanitizerArgs.h

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ class SanitizerArgs {
3737
bool MsanParamRetval = true;
3838
bool CfiCrossDso = false;
3939
bool CfiICallGeneralizePointers = false;
40+
bool CfiICallNormalizeIntegers = false;
4041
bool CfiCanonicalJumpTables = false;
4142
int AsanFieldPadding = 0;
4243
bool SharedRuntime = false;

‎clang/lib/AST/ItaniumMangle.cpp

+97-7
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,10 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
109109
void mangleCXXCtorVTable(const CXXRecordDecl *RD, int64_t Offset,
110110
const CXXRecordDecl *Type, raw_ostream &) override;
111111
void mangleCXXRTTI(QualType T, raw_ostream &) override;
112-
void mangleCXXRTTIName(QualType T, raw_ostream &) override;
113-
void mangleTypeName(QualType T, raw_ostream &) override;
112+
void mangleCXXRTTIName(QualType T, raw_ostream &,
113+
bool NormalizeIntegers) override;
114+
void mangleTypeName(QualType T, raw_ostream &,
115+
bool NormalizeIntegers) override;
114116

115117
void mangleCXXCtorComdat(const CXXConstructorDecl *D, raw_ostream &) override;
116118
void mangleCXXDtorComdat(const CXXDestructorDecl *D, raw_ostream &) override;
@@ -215,6 +217,10 @@ class ItaniumMangleContextImpl : public ItaniumMangleContext {
215217
class CXXNameMangler {
216218
ItaniumMangleContextImpl &Context;
217219
raw_ostream &Out;
220+
/// Normalize integer types for cross-language CFI support with other
221+
/// languages that can't represent and encode C/C++ integer types.
222+
bool NormalizeIntegers = false;
223+
218224
bool NullOut = false;
219225
/// In the "DisableDerivedAbiTags" mode derived ABI tags are not calculated.
220226
/// This mode is used when mangler creates another mangler recursively to
@@ -413,6 +419,10 @@ class CXXNameMangler {
413419
: Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type),
414420
AbiTagsRoot(AbiTags) {}
415421

422+
CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_,
423+
bool NormalizeIntegers_)
424+
: Context(C), Out(Out_), NormalizeIntegers(NormalizeIntegers_),
425+
NullOut(false), Structor(nullptr), AbiTagsRoot(AbiTags) {}
416426
CXXNameMangler(CXXNameMangler &Outer, raw_ostream &Out_)
417427
: Context(Outer.Context), Out(Out_), Structor(Outer.Structor),
418428
StructorType(Outer.StructorType), SeqID(Outer.SeqID),
@@ -2937,6 +2947,85 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
29372947
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
29382948
// ::= u <source-name> # vendor extended type
29392949
std::string type_name;
2950+
// Normalize integer types as vendor extended types:
2951+
// u<length>i<type size>
2952+
// u<length>u<type size>
2953+
if (NormalizeIntegers && T->isInteger()) {
2954+
if (T->isSignedInteger()) {
2955+
switch (getASTContext().getTypeSize(T)) {
2956+
case 8:
2957+
// Pick a representative for each integer size in the substitution
2958+
// dictionary. (Its actual defined size is not relevant.)
2959+
if (mangleSubstitution(BuiltinType::SChar))
2960+
break;
2961+
Out << "u2i8";
2962+
addSubstitution(BuiltinType::SChar);
2963+
break;
2964+
case 16:
2965+
if (mangleSubstitution(BuiltinType::Short))
2966+
break;
2967+
Out << "u3i16";
2968+
addSubstitution(BuiltinType::Short);
2969+
break;
2970+
case 32:
2971+
if (mangleSubstitution(BuiltinType::Int))
2972+
break;
2973+
Out << "u3i32";
2974+
addSubstitution(BuiltinType::Int);
2975+
break;
2976+
case 64:
2977+
if (mangleSubstitution(BuiltinType::Long))
2978+
break;
2979+
Out << "u3i64";
2980+
addSubstitution(BuiltinType::Long);
2981+
break;
2982+
case 128:
2983+
if (mangleSubstitution(BuiltinType::Int128))
2984+
break;
2985+
Out << "u4i128";
2986+
addSubstitution(BuiltinType::Int128);
2987+
break;
2988+
default:
2989+
llvm_unreachable("Unknown integer size for normalization");
2990+
}
2991+
} else {
2992+
switch (getASTContext().getTypeSize(T)) {
2993+
case 8:
2994+
if (mangleSubstitution(BuiltinType::UChar))
2995+
break;
2996+
Out << "u2u8";
2997+
addSubstitution(BuiltinType::UChar);
2998+
break;
2999+
case 16:
3000+
if (mangleSubstitution(BuiltinType::UShort))
3001+
break;
3002+
Out << "u3u16";
3003+
addSubstitution(BuiltinType::UShort);
3004+
break;
3005+
case 32:
3006+
if (mangleSubstitution(BuiltinType::UInt))
3007+
break;
3008+
Out << "u3u32";
3009+
addSubstitution(BuiltinType::UInt);
3010+
break;
3011+
case 64:
3012+
if (mangleSubstitution(BuiltinType::ULong))
3013+
break;
3014+
Out << "u3u64";
3015+
addSubstitution(BuiltinType::ULong);
3016+
break;
3017+
case 128:
3018+
if (mangleSubstitution(BuiltinType::UInt128))
3019+
break;
3020+
Out << "u4u128";
3021+
addSubstitution(BuiltinType::UInt128);
3022+
break;
3023+
default:
3024+
llvm_unreachable("Unknown integer size for normalization");
3025+
}
3026+
}
3027+
return;
3028+
}
29403029
switch (T->getKind()) {
29413030
case BuiltinType::Void:
29423031
Out << 'v';
@@ -6523,16 +6612,17 @@ void ItaniumMangleContextImpl::mangleCXXRTTI(QualType Ty, raw_ostream &Out) {
65236612
Mangler.mangleType(Ty);
65246613
}
65256614

6526-
void ItaniumMangleContextImpl::mangleCXXRTTIName(QualType Ty,
6527-
raw_ostream &Out) {
6615+
void ItaniumMangleContextImpl::mangleCXXRTTIName(
6616+
QualType Ty, raw_ostream &Out, bool NormalizeIntegers = false) {
65286617
// <special-name> ::= TS <type> # typeinfo name (null terminated byte string)
6529-
CXXNameMangler Mangler(*this, Out);
6618+
CXXNameMangler Mangler(*this, Out, NormalizeIntegers);
65306619
Mangler.getStream() << "_ZTS";
65316620
Mangler.mangleType(Ty);
65326621
}
65336622

6534-
void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out) {
6535-
mangleCXXRTTIName(Ty, Out);
6623+
void ItaniumMangleContextImpl::mangleTypeName(QualType Ty, raw_ostream &Out,
6624+
bool NormalizeIntegers = false) {
6625+
mangleCXXRTTIName(Ty, Out, NormalizeIntegers);
65366626
}
65376627

65386628
void ItaniumMangleContextImpl::mangleStringLiteral(const StringLiteral *, raw_ostream &) {

‎clang/lib/AST/MicrosoftMangle.cpp

+8-5
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
180180
int32_t VBPtrOffset, uint32_t VBIndex,
181181
raw_ostream &Out) override;
182182
void mangleCXXRTTI(QualType T, raw_ostream &Out) override;
183-
void mangleCXXRTTIName(QualType T, raw_ostream &Out) override;
183+
void mangleCXXRTTIName(QualType T, raw_ostream &Out,
184+
bool NormalizeIntegers) override;
184185
void mangleCXXRTTIBaseClassDescriptor(const CXXRecordDecl *Derived,
185186
uint32_t NVOffset, int32_t VBPtrOffset,
186187
uint32_t VBTableOffset, uint32_t Flags,
@@ -193,7 +194,8 @@ class MicrosoftMangleContextImpl : public MicrosoftMangleContext {
193194
mangleCXXRTTICompleteObjectLocator(const CXXRecordDecl *Derived,
194195
ArrayRef<const CXXRecordDecl *> BasePath,
195196
raw_ostream &Out) override;
196-
void mangleTypeName(QualType T, raw_ostream &) override;
197+
void mangleTypeName(QualType T, raw_ostream &,
198+
bool NormalizeIntegers) override;
197199
void mangleReferenceTemporary(const VarDecl *, unsigned ManglingNumber,
198200
raw_ostream &) override;
199201
void mangleStaticGuardVariable(const VarDecl *D, raw_ostream &Out) override;
@@ -3586,8 +3588,8 @@ void MicrosoftMangleContextImpl::mangleCXXRTTI(QualType T, raw_ostream &Out) {
35863588
Mangler.getStream() << "@8";
35873589
}
35883590

3589-
void MicrosoftMangleContextImpl::mangleCXXRTTIName(QualType T,
3590-
raw_ostream &Out) {
3591+
void MicrosoftMangleContextImpl::mangleCXXRTTIName(
3592+
QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
35913593
MicrosoftCXXNameMangler Mangler(*this, Out);
35923594
Mangler.getStream() << '.';
35933595
Mangler.mangleType(T, SourceRange(), MicrosoftCXXNameMangler::QMM_Result);
@@ -3754,7 +3756,8 @@ void MicrosoftMangleContextImpl::mangleSEHFinallyBlock(
37543756
Mangler.mangleName(EnclosingDecl);
37553757
}
37563758

3757-
void MicrosoftMangleContextImpl::mangleTypeName(QualType T, raw_ostream &Out) {
3759+
void MicrosoftMangleContextImpl::mangleTypeName(
3760+
QualType T, raw_ostream &Out, bool NormalizeIntegers = false) {
37583761
// This is just a made up unique string for the purposes of tbaa. undname
37593762
// does *not* know how to demangle it.
37603763
MicrosoftCXXNameMangler Mangler(*this, Out);

‎clang/lib/CodeGen/CodeGenModule.cpp

+11-2
Original file line numberDiff line numberDiff line change
@@ -1731,7 +1731,11 @@ llvm::ConstantInt *CodeGenModule::CreateKCFITypeId(QualType T) {
17311731

17321732
std::string OutName;
17331733
llvm::raw_string_ostream Out(OutName);
1734-
getCXXABI().getMangleContext().mangleTypeName(T, Out);
1734+
getCXXABI().getMangleContext().mangleTypeName(
1735+
T, Out, getCodeGenOpts().SanitizeCfiICallNormalizeIntegers);
1736+
1737+
if (getCodeGenOpts().SanitizeCfiICallNormalizeIntegers)
1738+
Out << ".normalized";
17351739

17361740
return llvm::ConstantInt::get(Int32Ty,
17371741
static_cast<uint32_t>(llvm::xxHash64(OutName)));
@@ -6949,7 +6953,12 @@ CodeGenModule::CreateMetadataIdentifierImpl(QualType T, MetadataTypeMap &Map,
69496953
if (isExternallyVisible(T->getLinkage())) {
69506954
std::string OutName;
69516955
llvm::raw_string_ostream Out(OutName);
6952-
getCXXABI().getMangleContext().mangleTypeName(T, Out);
6956+
getCXXABI().getMangleContext().mangleTypeName(
6957+
T, Out, getCodeGenOpts().SanitizeCfiICallNormalizeIntegers);
6958+
6959+
if (getCodeGenOpts().SanitizeCfiICallNormalizeIntegers)
6960+
Out << ".normalized";
6961+
69536962
Out << Suffix;
69546963

69556964
InternalId = llvm::MDString::get(getLLVMContext(), Out.str());

‎clang/lib/Driver/SanitizerArgs.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,9 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
713713
CfiICallGeneralizePointers =
714714
Args.hasArg(options::OPT_fsanitize_cfi_icall_generalize_pointers);
715715

716+
CfiICallNormalizeIntegers =
717+
Args.hasArg(options::OPT_fsanitize_cfi_icall_normalize_integers);
718+
716719
if (CfiCrossDso && CfiICallGeneralizePointers && DiagnoseErrors)
717720
D.Diag(diag::err_drv_argument_not_allowed_with)
718721
<< "-fsanitize-cfi-cross-dso"
@@ -1217,6 +1220,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
12171220
if (CfiICallGeneralizePointers)
12181221
CmdArgs.push_back("-fsanitize-cfi-icall-generalize-pointers");
12191222

1223+
if (CfiICallNormalizeIntegers)
1224+
CmdArgs.push_back("-fsanitize-cfi-icall-experimental-normalize-integers");
1225+
12201226
if (CfiCanonicalJumpTables)
12211227
CmdArgs.push_back("-fsanitize-cfi-canonical-jump-tables");
12221228

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fsanitize-cfi-icall-experimental-normalize-integers -emit-llvm -o - %s | FileCheck %s
2+
3+
// Test that integer types are normalized for cross-language CFI support with
4+
// other languages that can't represent and encode C/C++ integer types.
5+
6+
void foo0(char arg) { }
7+
// CHECK: define{{.*}}foo0{{.*}}!type ![[TYPE0:[0-9]+]] !type !{{[0-9]+}}
8+
void foo1(char arg1, signed char arg2) { }
9+
// CHECK: define{{.*}}foo1{{.*}}!type ![[TYPE1:[0-9]+]] !type !{{[0-9]+}}
10+
void foo2(char arg1, signed char arg2, signed char arg3) { }
11+
// CHECK: define{{.*}}foo2{{.*}}!type ![[TYPE2:[0-9]+]] !type !{{[0-9]+}}
12+
void foo3(int arg) { }
13+
// CHECK: define{{.*}}foo3{{.*}}!type ![[TYPE3:[0-9]+]] !type !{{[0-9]+}}
14+
void foo4(int arg1, int arg2) { }
15+
// CHECK: define{{.*}}foo4{{.*}}!type ![[TYPE4:[0-9]+]] !type !{{[0-9]+}}
16+
void foo5(int arg1, int arg2, int arg3) { }
17+
// CHECK: define{{.*}}foo5{{.*}}!type ![[TYPE5:[0-9]+]] !type !{{[0-9]+}}
18+
void foo6(long arg) { }
19+
// CHECK: define{{.*}}foo6{{.*}}!type ![[TYPE6:[0-9]+]] !type !{{[0-9]+}}
20+
void foo7(long arg1, long long arg2) { }
21+
// CHECK: define{{.*}}foo7{{.*}}!type ![[TYPE7:[0-9]+]] !type !{{[0-9]+}}
22+
void foo8(long arg1, long long arg2, long long arg3) { }
23+
// CHECK: define{{.*}}foo8{{.*}}!type ![[TYPE8:[0-9]+]] !type !{{[0-9]+}}
24+
void foo9(short arg) { }
25+
// CHECK: define{{.*}}foo9{{.*}}!type ![[TYPE9:[0-9]+]] !type !{{[0-9]+}}
26+
void foo10(short arg1, short arg2) { }
27+
// CHECK: define{{.*}}foo10{{.*}}!type ![[TYPE10:[0-9]+]] !type !{{[0-9]+}}
28+
void foo11(short arg1, short arg2, short arg3) { }
29+
// CHECK: define{{.*}}foo11{{.*}}!type ![[TYPE11:[0-9]+]] !type !{{[0-9]+}}
30+
void foo12(unsigned char arg) { }
31+
// CHECK: define{{.*}}foo12{{.*}}!type ![[TYPE12:[0-9]+]] !type !{{[0-9]+}}
32+
void foo13(unsigned char arg1, unsigned char arg2) { }
33+
// CHECK: define{{.*}}foo13{{.*}}!type ![[TYPE13:[0-9]+]] !type !{{[0-9]+}}
34+
void foo14(unsigned char arg1, unsigned char arg2, unsigned char arg3) { }
35+
// CHECK: define{{.*}}foo14{{.*}}!type ![[TYPE14:[0-9]+]] !type !{{[0-9]+}}
36+
void foo15(unsigned int arg) { }
37+
// CHECK: define{{.*}}foo15{{.*}}!type ![[TYPE15:[0-9]+]] !type !{{[0-9]+}}
38+
void foo16(unsigned int arg1, unsigned int arg2) { }
39+
// CHECK: define{{.*}}foo16{{.*}}!type ![[TYPE16:[0-9]+]] !type !{{[0-9]+}}
40+
void foo17(unsigned int arg1, unsigned int arg2, unsigned int arg3) { }
41+
// CHECK: define{{.*}}foo17{{.*}}!type ![[TYPE17:[0-9]+]] !type !{{[0-9]+}}
42+
void foo18(unsigned long arg) { }
43+
// CHECK: define{{.*}}foo18{{.*}}!type ![[TYPE18:[0-9]+]] !type !{{[0-9]+}}
44+
void foo19(unsigned long arg1, unsigned long long arg2) { }
45+
// CHECK: define{{.*}}foo19{{.*}}!type ![[TYPE19:[0-9]+]] !type !{{[0-9]+}}
46+
void foo20(unsigned long arg1, unsigned long long arg2, unsigned long long arg3) { }
47+
// CHECK: define{{.*}}foo20{{.*}}!type ![[TYPE20:[0-9]+]] !type !{{[0-9]+}}
48+
void foo21(unsigned short arg) { }
49+
// CHECK: define{{.*}}foo21{{.*}}!type ![[TYPE21:[0-9]+]] !type !{{[0-9]+}}
50+
void foo22(unsigned short arg1, unsigned short arg2) { }
51+
// CHECK: define{{.*}}foo22{{.*}}!type ![[TYPE22:[0-9]+]] !type !{{[0-9]+}}
52+
void foo23(unsigned short arg1, unsigned short arg2, unsigned short arg3) { }
53+
// CHECK: define{{.*}}foo23{{.*}}!type ![[TYPE23:[0-9]+]] !type !{{[0-9]+}}
54+
55+
// CHECK: ![[TYPE0]] = !{i64 0, !"_ZTSFvu2i8E.normalized"}
56+
// CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu2i8S_E.normalized"}
57+
// CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu2i8S_S_E.normalized"}
58+
// CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3i32E.normalized"}
59+
// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3i32S_E.normalized"}
60+
// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3i32S_S_E.normalized"}
61+
// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3i64E.normalized"}
62+
// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3i64S_E.normalized"}
63+
// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3i64S_S_E.normalized"}
64+
// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3i16E.normalized"}
65+
// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3i16S_E.normalized"}
66+
// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3i16S_S_E.normalized"}
67+
// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu2u8E.normalized"}
68+
// CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvu2u8S_E.normalized"}
69+
// CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFvu2u8S_S_E.normalized"}
70+
// CHECK: ![[TYPE15]] = !{i64 0, !"_ZTSFvu3u32E.normalized"}
71+
// CHECK: ![[TYPE16]] = !{i64 0, !"_ZTSFvu3u32S_E.normalized"}
72+
// CHECK: ![[TYPE17]] = !{i64 0, !"_ZTSFvu3u32S_S_E.normalized"}
73+
// CHECK: ![[TYPE18]] = !{i64 0, !"_ZTSFvu3u64E.normalized"}
74+
// CHECK: ![[TYPE19]] = !{i64 0, !"_ZTSFvu3u64S_E.normalized"}
75+
// CHECK: ![[TYPE20]] = !{i64 0, !"_ZTSFvu3u64S_S_E.normalized"}
76+
// CHECK: ![[TYPE21]] = !{i64 0, !"_ZTSFvu3u16E.normalized"}
77+
// CHECK: ![[TYPE22]] = !{i64 0, !"_ZTSFvu3u16S_E.normalized"}
78+
// CHECK: ![[TYPE23]] = !{i64 0, !"_ZTSFvu3u16S_S_E.normalized"}
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Failed to load comments.