https://github.com/igorkudrin updated https://github.com/llvm/llvm-project/pull/197620
>From 8ba8c4ed4b8cd7d8d83815a52604d92c71b84dd7 Mon Sep 17 00:00:00 2001 From: Igor Kudrin <[email protected]> Date: Thu, 7 May 2026 23:36:38 -0700 Subject: [PATCH 1/4] [AArch64] Fix possible miscompilation with `__builtin_arm_gmi` The `@llvm.aarch64.gmi` intrinsic returns a 64-bit value, but `SemaARM::BuiltinARMMemoryTaggingCall()` incorrectly sets the type of the call instruction to `Context.IntTy`. This results in miscompilations when a truncate instruction is required but missing from the generated code. Note that in the `-O0` case below a 64-bit value is stored in a 32-bit stack slot: ``` > cat test.c int test(void* a, unsigned m) { return __builtin_arm_gmi(a, m); } > clang -target aarch64 -march=armv9+memtag -O0 -S -emit-llvm test.c -o - define dso_local i32 @test(ptr noundef %0, i32 noundef %1) #0 { %3 = alloca i32, align 4 ... %9 = call i64 @llvm.aarch64.gmi(ptr %6, i64 %8) store i64 %9, ptr %3, align 4 %10 = load i32, ptr %3, align 4 ret i32 %10 } > clang -target aarch64 -march=armv9+memtag -O3 -S -emit-llvm test.c -o - define dso_local i32 @test(ptr nocapture noundef readnone %0, i32 noundef %1) local_unnamed_addr #0 { ret i32 undef } ``` The patch fixes this by setting the return type to `Context.LongLongTy`. --- clang/lib/Sema/SemaARM.cpp | 2 +- clang/test/CodeGen/arm64-mte.c | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index 7871fd624a467..68728f25f5231 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -94,7 +94,7 @@ bool SemaARM::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, if (!SecArgType->isIntegerType()) return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer) << "second" << SecArgType << Arg1->getSourceRange(); - TheCall->setType(Context.IntTy); + TheCall->setType(Context.LongLongTy); return false; } diff --git a/clang/test/CodeGen/arm64-mte.c b/clang/test/CodeGen/arm64-mte.c index ff6f8de5d4bb4..9e2b3736ac4c0 100644 --- a/clang/test/CodeGen/arm64-mte.c +++ b/clang/test/CodeGen/arm64-mte.c @@ -49,9 +49,18 @@ short *increment_tag2(short *a) { return __arm_mte_increment_tag(a,3); } -// CHECK-LABEL: define{{.*}} i32 @exclude_tag +// CHECK-LABEL: define{{.*}} i32 @exclude_tag1 attribute -unsigned exclude_tag(int *a, unsigned m) { +unsigned exclude_tag1(int *a, unsigned m) { +// CHECK: [[T0:%[0-9]+]] = zext i32 %m to i64 +// CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.gmi(ptr %a, i64 [[T0]]) +// CHECK: trunc i64 [[T2]] to i32 + return __arm_mte_exclude_tag(a, m); +} + +// CHECK-LABEL: define{{.*}} i32 @exclude_tag2 +attribute +int exclude_tag2(int *a, unsigned m) { // CHECK: [[T0:%[0-9]+]] = zext i32 %m to i64 // CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.gmi(ptr %a, i64 [[T0]]) // CHECK: trunc i64 [[T2]] to i32 >From 6a5c7b208b2ffa69ad7fe158079de8e6439202aa Mon Sep 17 00:00:00 2001 From: Igor Kudrin <[email protected]> Date: Wed, 13 May 2026 19:41:39 -0700 Subject: [PATCH 2/4] fixup! Update prototypes, remove explicit 'setType()' --- clang/include/clang/Basic/BuiltinsAArch64.td | 6 +++--- clang/lib/Sema/SemaARM.cpp | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/Basic/BuiltinsAArch64.td b/clang/include/clang/Basic/BuiltinsAArch64.td index 8e5dbb5f4172d..ba30e344911aa 100644 --- a/clang/include/clang/Basic/BuiltinsAArch64.td +++ b/clang/include/clang/Basic/BuiltinsAArch64.td @@ -75,12 +75,12 @@ let Attributes = [NoThrow, Const], Features = "crc" in { // Memory Tagging Extensions (MTE) let Attributes = [CustomTypeChecking], Features = "mte" in { - def irg : AArch64TargetBuiltin<"void * (void *, unsigned int)">; + def irg : AArch64TargetBuiltin<"void * (void *, uint64_t)">; def addg : AArch64TargetBuiltin<"void * (void *, unsigned int)">; - def gmi : AArch64TargetBuiltin<"unsigned int (void *, unsigned int)">; + def gmi : AArch64TargetBuiltin<"uint64_t (void *, uint64_t)">; def ldg : AArch64TargetBuiltin<"void * (void *)">; def stg : AArch64TargetBuiltin<"void (void *)">; - def subp : AArch64TargetBuiltin<"unsigned int (void *, void *)">; + def subp : AArch64TargetBuiltin<"int64_t (void *, void *)">; } // SME state function diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index 68728f25f5231..2599eb04f3c12 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -94,7 +94,6 @@ bool SemaARM::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, if (!SecArgType->isIntegerType()) return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer) << "second" << SecArgType << Arg1->getSourceRange(); - TheCall->setType(Context.LongLongTy); return false; } @@ -176,7 +175,6 @@ bool SemaARM::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, TheCall->setArg(0, ArgExprA.get()); TheCall->setArg(1, ArgExprB.get()); - TheCall->setType(Context.LongLongTy); return false; } assert(false && "Unhandled ARM MTE intrinsic"); >From 048850a92f695cb3a11741533085d2355094f41e Mon Sep 17 00:00:00 2001 From: Igor Kudrin <[email protected]> Date: Wed, 13 May 2026 19:43:37 -0700 Subject: [PATCH 3/4] [Clang][AArch64] Fix crash with large arguments to MTE built-ins The second argument to `__builtin_arm_irg()` and `__builtin_arm_gmi()` is expected to be 64-bit. When a wider type is passed, the compiler still generates a `zext` instruction, leading to a backend error: ``` > cat test.c unsigned test(void* a, unsigned __int128 m) { return __builtin_arm_gmi(a, m); } > clang -target aarch64 -march=armv9+memtag -S test.c fatal error: error in backend: Cannot select: ... i64,ch = load<... zext from i128> ``` This is fixed by replacing `CreateZExt()` with `CreateZExtOrTrunc()`. --- clang/lib/CodeGen/TargetBuiltins/ARM.cpp | 4 ++-- clang/test/CodeGen/arm64-mte.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp index 647c3ff44928a..bccddf36d3cfa 100644 --- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp @@ -4915,7 +4915,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Value *Pointer = EmitScalarExpr(E->getArg(0)); Value *Mask = EmitScalarExpr(E->getArg(1)); - Mask = Builder.CreateZExt(Mask, Int64Ty); + Mask = Builder.CreateZExtOrTrunc(Mask, Int64Ty); return Builder.CreateCall(CGM.getIntrinsic(MTEIntrinsicID), {Pointer, Mask}); } @@ -4931,7 +4931,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, Value *Pointer = EmitScalarExpr(E->getArg(0)); Value *ExcludedMask = EmitScalarExpr(E->getArg(1)); - ExcludedMask = Builder.CreateZExt(ExcludedMask, Int64Ty); + ExcludedMask = Builder.CreateZExtOrTrunc(ExcludedMask, Int64Ty); return Builder.CreateCall( CGM.getIntrinsic(MTEIntrinsicID), {Pointer, ExcludedMask}); } diff --git a/clang/test/CodeGen/arm64-mte.c b/clang/test/CodeGen/arm64-mte.c index 9e2b3736ac4c0..c943ed7c4a0eb 100644 --- a/clang/test/CodeGen/arm64-mte.c +++ b/clang/test/CodeGen/arm64-mte.c @@ -35,6 +35,15 @@ char *create_tag3(char *a, unsigned b) { return __arm_mte_create_random_tag(a,b); } +// CHECK-LABEL: define{{.*}} ptr @create_tag4 +attribute +char *create_tag4(char *a, unsigned __int128 b) { +// CHECK: [[T1:%[0-9]+]] = trunc i128 %b to i64 +// CHECK: [[T2:%[0-9]+]] = tail call ptr @llvm.aarch64.irg(ptr %a, i64 [[T1]]) +// CHECK: ret ptr [[T2:%[0-9]+]] + return __arm_mte_create_random_tag(a,b); +} + // CHECK-LABEL: define{{.*}} ptr @increment_tag1 attribute char *increment_tag1(char *a) { @@ -67,6 +76,15 @@ int exclude_tag2(int *a, unsigned m) { return __arm_mte_exclude_tag(a, m); } +// CHECK-LABEL: define{{.*}} i128 @exclude_tag3 +attribute +unsigned __int128 exclude_tag3(int *a, unsigned __int128 m) { +// CHECK: [[T0:%[0-9]+]] = trunc i128 %m to i64 +// CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.gmi(ptr %a, i64 [[T0]]) +// CHECK: zext i64 [[T2]] to i128 + return __arm_mte_exclude_tag(a, m); +} + // CHECK-LABEL: define{{.*}} ptr @get_tag1 attribute int *get_tag1(int *a) { >From 75256ac94b95276511f214942c60b09cf4cb9dc8 Mon Sep 17 00:00:00 2001 From: Igor Kudrin <[email protected]> Date: Thu, 21 May 2026 20:54:04 -0700 Subject: [PATCH 4/4] fixup! Convert arguments to uint64 in Sema --- .../clang/Basic/DiagnosticSemaKinds.td | 2 -- clang/lib/CodeGen/TargetBuiltins/ARM.cpp | 12 +++++----- clang/lib/Sema/SemaARM.cpp | 22 ++++++++++--------- clang/test/AST/ast-dump-aarch64-mte.c | 10 +++++---- clang/test/CodeGen/arm64-mte.c | 14 ++++++------ clang/test/Sema/builtins-arm64-mte.c | 16 +++++++++++--- 6 files changed, 44 insertions(+), 32 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index dbe6cb2c3a41c..7a09d85f52ef4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -13284,8 +13284,6 @@ def err_memtag_any2arg_pointer : Error< "at least one argument of MTE builtin function must be a pointer (%0, %1 invalid)">; def err_memtag_arg_must_be_pointer : Error< "%0 argument of MTE builtin function must be a pointer (%1 invalid)">; -def err_memtag_arg_must_be_integer : Error< - "%0 argument of MTE builtin function must be an integer type (%1 invalid)">; def warn_dereference_of_noderef_type : Warning< "dereferencing %0; was declared with a 'noderef' type">, InGroup<NoDeref>; diff --git a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp index 9e9b1895bea11..b7c7bc8ebf9a0 100644 --- a/clang/lib/CodeGen/TargetBuiltins/ARM.cpp +++ b/clang/lib/CodeGen/TargetBuiltins/ARM.cpp @@ -4914,8 +4914,8 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, if (MTEIntrinsicID == Intrinsic::aarch64_irg) { Value *Pointer = EmitScalarExpr(E->getArg(0)); Value *Mask = EmitScalarExpr(E->getArg(1)); - - Mask = Builder.CreateZExtOrTrunc(Mask, Int64Ty); + assert(Mask->getType()->getScalarSizeInBits() == 64 && + "SemaARM::BuiltinARMMemoryTaggingCall() enforces this"); return Builder.CreateCall(CGM.getIntrinsic(MTEIntrinsicID), {Pointer, Mask}); } @@ -4930,10 +4930,10 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID, if (MTEIntrinsicID == Intrinsic::aarch64_gmi) { Value *Pointer = EmitScalarExpr(E->getArg(0)); Value *ExcludedMask = EmitScalarExpr(E->getArg(1)); - - ExcludedMask = Builder.CreateZExtOrTrunc(ExcludedMask, Int64Ty); - return Builder.CreateCall( - CGM.getIntrinsic(MTEIntrinsicID), {Pointer, ExcludedMask}); + assert(ExcludedMask->getType()->getScalarSizeInBits() == 64 && + "SemaARM::BuiltinARMMemoryTaggingCall() enforces this"); + return Builder.CreateCall(CGM.getIntrinsic(MTEIntrinsicID), + {Pointer, ExcludedMask}); } // Although it is possible to supply a different return // address (first arg) to this intrinsic, for now we set diff --git a/clang/lib/Sema/SemaARM.cpp b/clang/lib/Sema/SemaARM.cpp index f57c9c8b87cd5..47e4b4f90485a 100644 --- a/clang/lib/Sema/SemaARM.cpp +++ b/clang/lib/Sema/SemaARM.cpp @@ -42,13 +42,14 @@ bool SemaARM::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, << "first" << FirstArgType << Arg0->getSourceRange(); TheCall->setArg(0, FirstArg.get()); - ExprResult SecArg = SemaRef.DefaultLvalueConversion(Arg1); + InitializedEntity Entity = InitializedEntity::InitializeParameter( + Context, Context.getIntTypeForBitwidth(64, /*Signed=*/false), + /*Consumed=*/false); + ExprResult SecArg = + SemaRef.PerformCopyInitialization(Entity, + /*EqualLoc=*/SourceLocation(), Arg1); if (SecArg.isInvalid()) return true; - QualType SecArgType = SecArg.get()->getType(); - if (!SecArgType->isIntegerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer) - << "second" << SecArgType << Arg1->getSourceRange(); TheCall->setArg(1, SecArg.get()); // Derive the return type from the pointer argument. @@ -92,13 +93,14 @@ bool SemaARM::BuiltinARMMemoryTaggingCall(unsigned BuiltinID, << "first" << FirstArgType << Arg0->getSourceRange(); TheCall->setArg(0, FirstArg.get()); - ExprResult SecArg = SemaRef.DefaultLvalueConversion(Arg1); + InitializedEntity Entity = InitializedEntity::InitializeParameter( + Context, Context.getIntTypeForBitwidth(64, /*Signed=*/false), + /*Consumed=*/false); + ExprResult SecArg = + SemaRef.PerformCopyInitialization(Entity, + /*EqualLoc=*/SourceLocation(), Arg1); if (SecArg.isInvalid()) return true; - QualType SecArgType = SecArg.get()->getType(); - if (!SecArgType->isIntegerType()) - return Diag(TheCall->getBeginLoc(), diag::err_memtag_arg_must_be_integer) - << "second" << SecArgType << Arg1->getSourceRange(); TheCall->setArg(1, SecArg.get()); return false; diff --git a/clang/test/AST/ast-dump-aarch64-mte.c b/clang/test/AST/ast-dump-aarch64-mte.c index c5def39676e9a..8e06371cafd77 100644 --- a/clang/test/AST/ast-dump-aarch64-mte.c +++ b/clang/test/AST/ast-dump-aarch64-mte.c @@ -21,8 +21,9 @@ void test() { // CHECK-NEXT: | | | `-DeclRefExpr {{.+}} '<builtin fn type>' Function {{.+}} '__builtin_arm_irg' 'void *(void *, unsigned long)' // CHECK-NEXT: | | |-ImplicitCastExpr {{.+}} 'struct A *' <LValueToRValue> // CHECK-NEXT: | | | `-DeclRefExpr {{.+}} 'struct A *' lvalue Var {{.+}} 'ptr_a' 'struct A *' - // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'unsigned int' <LValueToRValue> - // CHECK-NEXT: | | `-DeclRefExpr {{.+}} 'unsigned int' lvalue Var {{.+}} 'uval' 'unsigned int' + // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'unsigned long' <IntegralCast> + // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'unsigned int' <LValueToRValue> + // CHECK-NEXT: | | `-DeclRefExpr {{.+}} 'unsigned int' lvalue Var {{.+}} 'uval' 'unsigned int' ptr_a = __arm_mte_increment_tag(ptr_a, 5); // CHECK-NEXT: | |-BinaryOperator {{.+}} 'struct A *' '=' @@ -43,8 +44,9 @@ void test() { // CHECK-NEXT: | | | `-DeclRefExpr {{.+}} '<builtin fn type>' Function {{.+}} '__builtin_arm_gmi' 'unsigned long (void *, unsigned long)' // CHECK-NEXT: | | |-ImplicitCastExpr {{.+}} 'struct A *' <LValueToRValue> // CHECK-NEXT: | | | `-DeclRefExpr {{.+}} 'struct A *' lvalue Var {{.+}} 'ptr_a' 'struct A *' - // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'unsigned int' <LValueToRValue> - // CHECK-NEXT: | | `-DeclRefExpr {{.+}} 'unsigned int' lvalue Var {{.+}} 'uval' 'unsigned int' + // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'unsigned long' <IntegralCast> + // CHECK-NEXT: | | `-ImplicitCastExpr {{.+}} 'unsigned int' <LValueToRValue> + // CHECK-NEXT: | | `-DeclRefExpr {{.+}} 'unsigned int' lvalue Var {{.+}} 'uval' 'unsigned int' ptr_a = __arm_mte_get_tag(ptr_a); // CHECK-NEXT: | |-BinaryOperator {{.+}} 'struct A *' '=' diff --git a/clang/test/CodeGen/arm64-mte.c b/clang/test/CodeGen/arm64-mte.c index c943ed7c4a0eb..6a00f12ce3671 100644 --- a/clang/test/CodeGen/arm64-mte.c +++ b/clang/test/CodeGen/arm64-mte.c @@ -13,7 +13,7 @@ // CHECK-LABEL: define{{.*}} ptr @create_tag1 attribute int *create_tag1(int *a, unsigned b) { -// CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64 +// CHECK: [[T1:%[a-z0-9]+]] = zext i32 %b to i64 // CHECK: [[T2:%[0-9]+]] = tail call ptr @llvm.aarch64.irg(ptr %a, i64 [[T1]]) return __arm_mte_create_random_tag(a,b); } @@ -21,7 +21,7 @@ int *create_tag1(int *a, unsigned b) { // CHECK-LABEL: define{{.*}} ptr @create_tag2 attribute short *create_tag2(short *a, unsigned b) { -// CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64 +// CHECK: [[T1:%[a-z0-9]+]] = zext i32 %b to i64 // CHECK: [[T2:%[0-9]+]] = tail call ptr @llvm.aarch64.irg(ptr %a, i64 [[T1]]) return __arm_mte_create_random_tag(a,b); } @@ -29,7 +29,7 @@ short *create_tag2(short *a, unsigned b) { // CHECK-LABEL: define{{.*}} ptr @create_tag3 attribute char *create_tag3(char *a, unsigned b) { -// CHECK: [[T1:%[0-9]+]] = zext i32 %b to i64 +// CHECK: [[T1:%[a-z0-9]+]] = zext i32 %b to i64 // CHECK: [[T2:%[0-9]+]] = tail call ptr @llvm.aarch64.irg(ptr %a, i64 [[T1]]) // CHECK: ret ptr [[T2:%[0-9]+]] return __arm_mte_create_random_tag(a,b); @@ -38,7 +38,7 @@ char *create_tag3(char *a, unsigned b) { // CHECK-LABEL: define{{.*}} ptr @create_tag4 attribute char *create_tag4(char *a, unsigned __int128 b) { -// CHECK: [[T1:%[0-9]+]] = trunc i128 %b to i64 +// CHECK: [[T1:%[a-z0-9]+]] = trunc i128 %b to i64 // CHECK: [[T2:%[0-9]+]] = tail call ptr @llvm.aarch64.irg(ptr %a, i64 [[T1]]) // CHECK: ret ptr [[T2:%[0-9]+]] return __arm_mte_create_random_tag(a,b); @@ -61,7 +61,7 @@ short *increment_tag2(short *a) { // CHECK-LABEL: define{{.*}} i32 @exclude_tag1 attribute unsigned exclude_tag1(int *a, unsigned m) { -// CHECK: [[T0:%[0-9]+]] = zext i32 %m to i64 +// CHECK: [[T0:%[a-z0-9]+]] = zext i32 %m to i64 // CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.gmi(ptr %a, i64 [[T0]]) // CHECK: trunc i64 [[T2]] to i32 return __arm_mte_exclude_tag(a, m); @@ -70,7 +70,7 @@ unsigned exclude_tag1(int *a, unsigned m) { // CHECK-LABEL: define{{.*}} i32 @exclude_tag2 attribute int exclude_tag2(int *a, unsigned m) { -// CHECK: [[T0:%[0-9]+]] = zext i32 %m to i64 +// CHECK: [[T0:%[a-z0-9]+]] = zext i32 %m to i64 // CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.gmi(ptr %a, i64 [[T0]]) // CHECK: trunc i64 [[T2]] to i32 return __arm_mte_exclude_tag(a, m); @@ -79,7 +79,7 @@ int exclude_tag2(int *a, unsigned m) { // CHECK-LABEL: define{{.*}} i128 @exclude_tag3 attribute unsigned __int128 exclude_tag3(int *a, unsigned __int128 m) { -// CHECK: [[T0:%[0-9]+]] = trunc i128 %m to i64 +// CHECK: [[T0:%[a-z0-9]+]] = trunc i128 %m to i64 // CHECK: [[T2:%[0-9]+]] = tail call i64 @llvm.aarch64.gmi(ptr %a, i64 [[T0]]) // CHECK: zext i64 [[T2]] to i128 return __arm_mte_exclude_tag(a, m); diff --git a/clang/test/Sema/builtins-arm64-mte.c b/clang/test/Sema/builtins-arm64-mte.c index 1b0621f3c5e31..252ff88c4fd56 100644 --- a/clang/test/Sema/builtins-arm64-mte.c +++ b/clang/test/Sema/builtins-arm64-mte.c @@ -11,8 +11,13 @@ int *create_tag1(int a, unsigned b) { } int *create_tag2(int *a, unsigned *b) { - // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('unsigned int *' invalid)}} +#ifdef __cplusplus + // expected-error@+1 {{cannot initialize a parameter of type 'unsigned long' with an lvalue of type 'unsigned int *'}} + return __arm_mte_create_random_tag(a,b); +#else + // expected-error@+1 {{incompatible pointer to integer conversion passing 'unsigned int *' to parameter of type 'unsigned long'}} return __arm_mte_create_random_tag(a,b); +#endif } int *create_tag3(const int *a, unsigned b) { @@ -76,8 +81,13 @@ unsigned exclude_tag1(int *ptr, unsigned m) { } unsigned exclude_tag2(int *ptr, int *m) { - // expected-error@+1 {{second argument of MTE builtin function must be an integer type ('int *' invalid)}} +#ifdef __cplusplus + // expected-error@+1 {{cannot initialize a parameter of type 'unsigned long' with an lvalue of type 'int *'}} return __arm_mte_exclude_tag(ptr, m); +#else + // expected-error@+1 {{incompatible pointer to integer conversion passing 'int *' to parameter of type 'unsigned long'}} + return __arm_mte_exclude_tag(ptr, m); +#endif } void get_tag1(void) { @@ -142,4 +152,4 @@ int *create_tag1(int *a, unsigned b) { // expected-error@+1 {{'__builtin_arm_irg' needs target feature mte}} return __arm_mte_create_random_tag(a,b); } -#endif \ No newline at end of file +#endif _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
