https://github.com/localspook updated https://github.com/llvm/llvm-project/pull/153552
>From 63c02556bc65571a84e27debde2e2cfd724a0e9b Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Thu, 14 Aug 2025 00:52:37 -0700 Subject: [PATCH 1/2] [clang][Sema] Diagnose passing function pointer to `__builtin_assume_aligned` --- .../include/clang/Basic/DiagnosticSemaKinds.td | 3 ++- clang/lib/Sema/SemaChecking.cpp | 5 +++-- clang/test/Sema/builtin-assume-aligned.c | 17 +++++++++-------- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 116341f4b66d5..f7f26ed6062b3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12829,7 +12829,8 @@ def err_builtin_launder_invalid_arg : Error< "%select{non-pointer|function pointer|void pointer}0 argument to " "'__builtin_launder' is not allowed">; def err_builtin_assume_aligned_invalid_arg : Error< - "non-pointer argument to '__builtin_assume_aligned' is not allowed">; + "%select{non-pointer|function pointer}0 argument to " + "'__builtin_assume_aligned' is not allowed">; def err_builtin_is_within_lifetime_invalid_arg : Error< "%select{non-|function }0pointer argument to '__builtin_is_within_lifetime' " diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 9ecee18661340..d8ad9f65c1995 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5660,9 +5660,10 @@ bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) { { ExprResult FirstArgResult = DefaultFunctionArrayLvalueConversion(FirstArg); - if (!FirstArgResult.get()->getType()->isPointerType()) { + QualType FirstArgType = FirstArgResult.get()->getType(); + if (!FirstArgType->isObjectPointerType()) { Diag(TheCall->getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg) - << TheCall->getSourceRange(); + << FirstArgType->isFunctionPointerType() << TheCall->getSourceRange(); return true; } TheCall->setArg(0, FirstArgResult.get()); diff --git a/clang/test/Sema/builtin-assume-aligned.c b/clang/test/Sema/builtin-assume-aligned.c index 57378a3426524..c6d1197fe8ab4 100644 --- a/clang/test/Sema/builtin-assume-aligned.c +++ b/clang/test/Sema/builtin-assume-aligned.c @@ -77,18 +77,19 @@ int test14(int *a, int b) { a = (int *)__builtin_assume_aligned(b, 32); // expected-error {{non-pointer argument to '__builtin_assume_aligned' is not allowed}} } -int test15(int *b) { - int arr[3] = {1, 2, 3}; - b = (int *)__builtin_assume_aligned(arr, 32); - return b[0]; +void test15(void (*f)()) { + f = (void (*)())__builtin_assume_aligned(f, 32); // expected-error {{function pointer argument to '__builtin_assume_aligned' is not allowed}} } -int val(int x) { - return x; +void foo(); + +void test16(void (*f)()) { + f = (void (*)())__builtin_assume_aligned(foo, 32); // expected-error {{function pointer argument to '__builtin_assume_aligned' is not allowed}} } -int test16(int *b) { - b = (int *)__builtin_assume_aligned(val, 32); +int test17(int *b) { + int arr[3] = {1, 2, 3}; + b = (int *)__builtin_assume_aligned(arr, 32); return b[0]; } >From 0349a05a726efd80add99067a42acef2cb56b3bc Mon Sep 17 00:00:00 2001 From: Victor Chernyakin <chernyakin.victo...@outlook.com> Date: Thu, 14 Aug 2025 17:05:14 -0700 Subject: [PATCH 2/2] Use `checkBuiltinArgument`, add release notes --- clang/docs/ReleaseNotes.rst | 3 +++ .../include/clang/Basic/DiagnosticSemaKinds.td | 3 --- clang/lib/Sema/SemaChecking.cpp | 18 +++--------------- .../CodeGen/catch-alignment-assumption-array.c | 2 +- ...ion-builtin_assume_aligned-polymorphism.cpp | 2 +- ...in_assume_aligned-three-params-variable.cpp | 2 +- ...ion-builtin_assume_aligned-three-params.cpp | 2 +- ...ption-builtin_assume_aligned-two-params.cpp | 2 +- .../catch-alignment-assumption-ignorelist.c | 2 ++ .../Sema/builtin-assume-aligned-downgrade.c | 9 --------- clang/test/Sema/builtin-assume-aligned.c | 7 ++++--- clang/test/SemaCXX/builtin-assume-aligned.cpp | 13 +++++++++++++ 12 files changed, 30 insertions(+), 35 deletions(-) delete mode 100644 clang/test/Sema/builtin-assume-aligned-downgrade.c diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a8b7a29933945..ec93e4d0629c2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -170,6 +170,9 @@ Bug Fixes to Compiler Builtins ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - Fix an ambiguous reference to the builtin `type_info` (available when using `-fms-compatibility`) with modules. (#GH38400) +- Make the pointer parameter to `__builtin_assume_aligned` undergo conversions + like any normal argument. This means that integer to pointer conversions are now + allowed, and passing function pointers is now diagnosed. Bug Fixes to Attribute Support ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index f7f26ed6062b3..e12f19c819072 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -12828,9 +12828,6 @@ def warn_cast_discards_cfi_unchecked_callee def err_builtin_launder_invalid_arg : Error< "%select{non-pointer|function pointer|void pointer}0 argument to " "'__builtin_launder' is not allowed">; -def err_builtin_assume_aligned_invalid_arg : Error< - "%select{non-pointer|function pointer}0 argument to " - "'__builtin_assume_aligned' is not allowed">; def err_builtin_is_within_lifetime_invalid_arg : Error< "%select{non-|function }0pointer argument to '__builtin_is_within_lifetime' " diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index d8ad9f65c1995..4ba5d978508d7 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -5654,20 +5654,8 @@ bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) { if (checkArgCountRange(TheCall, 2, 3)) return true; - unsigned NumArgs = TheCall->getNumArgs(); - Expr *FirstArg = TheCall->getArg(0); - - { - ExprResult FirstArgResult = - DefaultFunctionArrayLvalueConversion(FirstArg); - QualType FirstArgType = FirstArgResult.get()->getType(); - if (!FirstArgType->isObjectPointerType()) { - Diag(TheCall->getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg) - << FirstArgType->isFunctionPointerType() << TheCall->getSourceRange(); - return true; - } - TheCall->setArg(0, FirstArgResult.get()); - } + if (checkBuiltinArgument(*this, TheCall, 0)) + return true; // The alignment must be a constant integer. Expr *SecondArg = TheCall->getArg(1); @@ -5687,7 +5675,7 @@ bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) { << SecondArg->getSourceRange() << Sema::MaximumAlignment; } - if (NumArgs > 2) { + if (TheCall->getNumArgs() > 2) { Expr *ThirdArg = TheCall->getArg(2); if (convertArgumentToType(*this, ThirdArg, Context.getSizeType())) return true; diff --git a/clang/test/CodeGen/catch-alignment-assumption-array.c b/clang/test/CodeGen/catch-alignment-assumption-array.c index 413068ecde42d..efbb3206a7042 100644 --- a/clang/test/CodeGen/catch-alignment-assumption-array.c +++ b/clang/test/CodeGen/catch-alignment-assumption-array.c @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE -// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'char *'\00" } +// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'const void *'\00" } // CHECK-SANITIZE-ANYRECOVER: @[[ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 30, i32 35 }, {{.*}} @[[CHAR]] } void *caller(void) { diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp index e40c0f3ce95d6..a8afc86ae83cb 100644 --- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp +++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-polymorphism.cpp @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE -// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'B *'\00" } +// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'const void *'\00" } // CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 35 }, {{.*}} @[[CHAR]] } struct A { int n; }; diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp index 01934010a4c08..01562c868714a 100644 --- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp +++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params-variable.cpp @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE -// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'char **'\00" } +// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'const void *'\00" } // CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 35 }, {{.*}} @[[CHAR]] } void *caller(char **x, unsigned long offset) { diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp index 5d5cef116b862..00a23e2d6d87f 100644 --- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp +++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-three-params.cpp @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE -// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'char **'\00" } +// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'const void *'\00" } // CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 35 }, {{.*}} @[[CHAR]] } void *caller(char **x) { diff --git a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp index 3934c41f58618..4fed0d10dd67c 100644 --- a/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp +++ b/clang/test/CodeGen/catch-alignment-assumption-builtin_assume_aligned-two-params.cpp @@ -3,7 +3,7 @@ // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-recover=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-ANYRECOVER,CHECK-SANITIZE-RECOVER // RUN: %clang_cc1 -fsanitize=alignment -fsanitize-trap=alignment -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s -implicit-check-not="call void @__ubsan_handle_alignment_assumption" --check-prefixes=CHECK,CHECK-SANITIZE,CHECK-SANITIZE-TRAP,CHECK-SANITIZE-UNREACHABLE -// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'char **'\00" } +// CHECK-SANITIZE-ANYRECOVER: @[[CHAR:.*]] = {{.*}} c"'const void *'\00" } // CHECK-SANITIZE-ANYRECOVER: @[[LINE_100_ALIGNMENT_ASSUMPTION:.*]] = {{.*}}, i32 100, i32 35 }, {{.*}} @[[CHAR]] } void *caller(char **x) { diff --git a/clang/test/CodeGen/catch-alignment-assumption-ignorelist.c b/clang/test/CodeGen/catch-alignment-assumption-ignorelist.c index 9087c26e98f3d..992f4d8d622df 100644 --- a/clang/test/CodeGen/catch-alignment-assumption-ignorelist.c +++ b/clang/test/CodeGen/catch-alignment-assumption-ignorelist.c @@ -24,11 +24,13 @@ void *dont_ignore_volatile_ptrs(void * volatile x) { // CHECK-LABEL: ignore_volatiles void *ignore_volatiles(volatile void * x) { + // CHECK: call void @__ubsan_handle_alignment_assumption( return __builtin_assume_aligned(x, 1); } // CHECK-LABEL: ignore_array_volatiles void *ignore_array_volatiles() { volatile int arr[] = {1}; + // CHECK: call void @__ubsan_handle_alignment_assumption( return __builtin_assume_aligned(arr, 4); } diff --git a/clang/test/Sema/builtin-assume-aligned-downgrade.c b/clang/test/Sema/builtin-assume-aligned-downgrade.c deleted file mode 100644 index 93631e7364373..0000000000000 --- a/clang/test/Sema/builtin-assume-aligned-downgrade.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-int-conversion -triple x86_64-linux -verify %s - -// Check that the pointer->int conversion error is not downgradable for the -// pointer argument to __builtin_assume_aligned. - -int test(int *a, int b) { - a = (int *)__builtin_assume_aligned(b, 32); // expected-error {{non-pointer argument to '__builtin_assume_aligned' is not allowed}} - int *y = __builtin_assume_aligned(1, 1); // expected-error {{non-pointer argument to '__builtin_assume_aligned' is not allowed}} -} diff --git a/clang/test/Sema/builtin-assume-aligned.c b/clang/test/Sema/builtin-assume-aligned.c index c6d1197fe8ab4..0768d4b47d620 100644 --- a/clang/test/Sema/builtin-assume-aligned.c +++ b/clang/test/Sema/builtin-assume-aligned.c @@ -74,17 +74,18 @@ int test13(int *a) { } int test14(int *a, int b) { - a = (int *)__builtin_assume_aligned(b, 32); // expected-error {{non-pointer argument to '__builtin_assume_aligned' is not allowed}} + a = (int *)__builtin_assume_aligned(b, 32); // expected-error {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const void *'}} + void *y = __builtin_assume_aligned(1, 1); // expected-error {{incompatible integer to pointer conversion passing 'int' to parameter of type 'const void *'}} } void test15(void (*f)()) { - f = (void (*)())__builtin_assume_aligned(f, 32); // expected-error {{function pointer argument to '__builtin_assume_aligned' is not allowed}} + f = (void (*)())__builtin_assume_aligned(f, 32); } void foo(); void test16(void (*f)()) { - f = (void (*)())__builtin_assume_aligned(foo, 32); // expected-error {{function pointer argument to '__builtin_assume_aligned' is not allowed}} + f = (void (*)())__builtin_assume_aligned(foo, 32); } int test17(int *b) { diff --git a/clang/test/SemaCXX/builtin-assume-aligned.cpp b/clang/test/SemaCXX/builtin-assume-aligned.cpp index 48bd8414fc50a..e2f8736a47a91 100644 --- a/clang/test/SemaCXX/builtin-assume-aligned.cpp +++ b/clang/test/SemaCXX/builtin-assume-aligned.cpp @@ -47,3 +47,16 @@ constexpr void *s1 = __builtin_assume_aligned(x, 32); constexpr void *s2 = __builtin_assume_aligned(x, 32, 5); constexpr void *s3 = __builtin_assume_aligned(x, 32, -1); +void (*f)(); +// expected-error@+1 {{cannot initialize a parameter of type 'const void *' with an lvalue of type 'void (*)()'}} +constexpr void * f1 = __builtin_assume_aligned(f, 32); + +void foo(); +// expected-error@+1 {{cannot initialize a parameter of type 'const void *' with an lvalue of type 'void ()'}} +constexpr void * f2 = __builtin_assume_aligned(foo, 32); + +constexpr void * null_ptr1 = __builtin_assume_aligned(0, 32); +constexpr void * null_ptr2 = __builtin_assume_aligned(nullptr, 32); + +// expected-error@+1 {{cannot initialize a parameter of type 'const void *' with an rvalue of type 'int'}} +constexpr void * not_null_ptr = __builtin_assume_aligned(1, 32); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits