[clang] [Clang] Fix crash on invalid pointer argument to `__builtin_assume_aligned` (PR #233112)
Akash Manna via cfe-commits
cfe-commits at lists.llvm.org
Sun Oct 18 07:20:13 PDT 2026
https://github.com/akash-manna-sky updated https://github.com/llvm/llvm-project/pull/233112
>From e93d9d13671fc60d0df018035f17b06436805861 Mon Sep 17 00:00:00 2001
From: Akash Manna <akash.manna.mymail at gmail.com>
Date: Sat, 17 Oct 2026 20:24:10 +0530
Subject: [PATCH 1/2] [Clang] Fix crash on invalid pointer argument to
__builtin_assume_aligned
Fixes #194289
`BuiltinAssumeAligned` reads the type of the converted pointer argument without checking that `DefaultFunctionArrayLvalueConversion` succeeded. It fails, after diagnosing, for an overload set that cannot be resolved (here `baz` is typo-corrected to the enclosing template `bar`), a function template, or a function whose address cannot be taken, and the null result was dereferenced. The dependent alignment is not needed; C hits it too.
Return early when the conversion is invalid, as the code did before ecdc5289afec dropped the check together with the `checkBuiltinArgument` call. The error is already reported by the conversion.
LLM tools were used for this contribution.
---
clang/docs/ReleaseNotes.md | 1 +
clang/lib/Sema/SemaChecking.cpp | 2 +
clang/test/Sema/builtin-assume-aligned.c | 8 +++
.../SemaCXX/builtin-assume-aligned-tmpl.cpp | 51 +++++++++++++++++++
clang/test/SemaCXX/builtin-assume-aligned.cpp | 10 ++++
5 files changed, 72 insertions(+)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 3f0c48cf36644d..d6d3b3a4354728 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -756,6 +756,7 @@ features cannot lower the translation-unit ABI level;
types that their evaluation silently mishandled. (#GH216997)
- Fix a crash when using `__builtin_assume_aligned` with dynamic allocations
during constant evaluation. (#GH173767)
+- Fixed a crash on an invalid pointer argument to `__builtin_assume_aligned`. (#GH194289)
- Fixed a crash when constant-evaluating `__builtin_align_up`, `__builtin_align_down`,
or `__builtin_is_aligned` with pointers without an underlying object. Null pointers
are handled as aligned values, while other base-less pointers are rejected during constant
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 51506c62d4e35f..defa0e85fa594f 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -6892,6 +6892,8 @@ bool Sema::BuiltinAssumeAligned(CallExpr *TheCall) {
{
ExprResult FirstArgResult =
DefaultFunctionArrayLvalueConversion(FirstArg);
+ if (FirstArgResult.isInvalid())
+ return true;
if (!FirstArgResult.get()->getType()->isPointerType()) {
Diag(TheCall->getBeginLoc(), diag::err_builtin_assume_aligned_invalid_arg)
<< TheCall->getSourceRange();
diff --git a/clang/test/Sema/builtin-assume-aligned.c b/clang/test/Sema/builtin-assume-aligned.c
index 57378a3426524a..91c24645d11430 100644
--- a/clang/test/Sema/builtin-assume-aligned.c
+++ b/clang/test/Sema/builtin-assume-aligned.c
@@ -92,6 +92,14 @@ int test16(int *b) {
return b[0];
}
+void test17_enable_if(int x) __attribute__((enable_if(x > 0, "")));
+void test17_pass_object_size(void *p __attribute__((pass_object_size(0))));
+int test17(int *a) {
+ a = __builtin_assume_aligned(test17_enable_if, 32); // expected-error {{cannot take address of function 'test17_enable_if'}}
+ a = __builtin_assume_aligned(test17_pass_object_size, 32); // expected-error {{cannot take address of function 'test17_pass_object_size'}}
+ return a[0];
+}
+
void test_void_assume_aligned(void) __attribute__((assume_aligned(32))); // expected-warning {{'assume_aligned' attribute only applies to return values that are pointers}}
int test_int_assume_aligned(void) __attribute__((assume_aligned(16))); // expected-warning {{'assume_aligned' attribute only applies to return values that are pointers}}
void *test_ptr_assume_aligned(void) __attribute__((assume_aligned(64))); // no-warning
diff --git a/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp b/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
index ea1c940b6232ff..f3226d3d5695ca 100644
--- a/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
+++ b/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
@@ -102,3 +102,54 @@ void foo() {
f<int>(0); // expected-note {{in instantiation of function template specialization 'GH26612::f<int>' requested here}}
}
} // namespace GH26612
+
+namespace GH194289 {
+template<int qux>
+void bar() { // expected-note {{'bar' declared here}} expected-note {{possible target for call}}
+ int foo = (int *) __builtin_assume_aligned(baz, qux + 1);
+ // expected-error at -1 {{use of undeclared identifier 'baz'; did you mean 'bar'?}}
+ // expected-error at -2 {{reference to overloaded function could not be resolved}}
+ // expected-error at -3 {{cannot initialize a variable of type 'int'}}
+}
+
+template<int qux>
+void bar2() { // expected-note {{'bar2' declared here}} expected-note {{possible target for call}}
+ (void)__builtin_assume_aligned(baz2, 8);
+ // expected-error at -1 {{use of undeclared identifier 'baz2'; did you mean 'bar2'?}}
+ // expected-error at -2 {{reference to overloaded function could not be resolved}}
+}
+
+void qux_fn(); // expected-note 2 {{'qux_fn' declared here}}
+void typo_to_function() {
+ (void)__builtin_assume_aligned(qux_fm, 8); // expected-error {{use of undeclared identifier 'qux_fm'; did you mean 'qux_fn'?}}
+ (void)__builtin_assume_aligned(no_such_pointer, 8); // expected-error {{use of undeclared identifier 'no_such_pointer'}}
+}
+
+template<int N>
+void typo_to_function_tmpl() {
+ (void)__builtin_assume_aligned(qux_fm, 8); // expected-error {{use of undeclared identifier 'qux_fm'; did you mean 'qux_fn'?}}
+ (void)__builtin_assume_aligned(no_such_pointer, N); // expected-error {{use of undeclared identifier 'no_such_pointer'}}
+}
+
+template<int N> void aligned_to(int *p) { (void)__builtin_assume_aligned(p, N); } // expected-error 3 {{requested alignment is not a power of 2}}
+template<unsigned long long N> void aligned_to_ull(int *p) { (void)__builtin_assume_aligned(p, N); } // expected-warning {{requested alignment must be 4294967296 bytes or smaller}}
+template<typename T> void dep_ptr(T p) { (void)__builtin_assume_aligned(p, 8); } // expected-error {{non-pointer argument to '__builtin_assume_aligned' is not allowed}}
+template<typename T, int N> void dep_both(T p) { (void)__builtin_assume_aligned(p, N); } // expected-error {{requested alignment is not a power of 2}}
+template<int O> void dep_off(int *p) { (void)__builtin_assume_aligned(p, 8, O); }
+template<typename T> void dep_off_ty(int *p, T o) { (void)__builtin_assume_aligned(p, 8, o); } // expected-error {{cannot initialize a parameter of type '__size_t'}}
+
+void instantiate(int *p) {
+ aligned_to<8>(p);
+ aligned_to<7>(p); // expected-note {{in instantiation of function template specialization 'GH194289::aligned_to<7>' requested here}}
+ aligned_to<0>(p); // expected-note {{in instantiation of function template specialization 'GH194289::aligned_to<0>' requested here}}
+ aligned_to<-32>(p); // expected-note {{in instantiation of function template specialization 'GH194289::aligned_to<-32>' requested here}}
+ aligned_to_ull<1ULL << 33>(p); // expected-note {{in instantiation of function template specialization 'GH194289::aligned_to_ull<8589934592ULL>' requested here}}
+ dep_ptr(p);
+ dep_ptr(0); // expected-note {{in instantiation of function template specialization 'GH194289::dep_ptr<int>' requested here}}
+ dep_both<int *, 16>(p);
+ dep_both<int *, 3>(p); // expected-note {{in instantiation of function template specialization 'GH194289::dep_both<int *, 3>' requested here}}
+ dep_off<4>(p);
+ dep_off_ty(p, 4);
+ dep_off_ty(p, p); // expected-note {{in instantiation of function template specialization 'GH194289::dep_off_ty<int *>' requested here}}
+}
+}
diff --git a/clang/test/SemaCXX/builtin-assume-aligned.cpp b/clang/test/SemaCXX/builtin-assume-aligned.cpp
index 1131cbbb329666..0593e85a93441c 100644
--- a/clang/test/SemaCXX/builtin-assume-aligned.cpp
+++ b/clang/test/SemaCXX/builtin-assume-aligned.cpp
@@ -146,3 +146,13 @@ namespace GH173767 {
constexpr int g1 = (delete (G*)__builtin_assume_aligned(new G, alignof(int)), 0);
#endif
} // namespace GH173767
+
+namespace GH194289 {
+void h(int); // expected-note {{possible target for call}}
+void h(double); // expected-note {{possible target for call}}
+template <typename T> void ft(); // expected-note {{possible target for call}}
+void unresolvable_pointer_argument() {
+ (void)__builtin_assume_aligned(h, 8); // expected-error {{reference to overloaded function could not be resolved}}
+ (void)__builtin_assume_aligned(ft, 8); // expected-error {{reference to overloaded function could not be resolved}}
+}
+}
>From d211072b2bc56ce799a46558c541ca5999147b17 Mon Sep 17 00:00:00 2001
From: Akash Manna <akash.manna.mymail at gmail.com>
Date: Sun, 18 Oct 2026 19:49:39 +0530
Subject: [PATCH 2/2] [Clang] Trim the __builtin_assume_aligned tests to the
conversion-failure cases
---
.../SemaCXX/builtin-assume-aligned-tmpl.cpp | 44 +------------------
1 file changed, 1 insertion(+), 43 deletions(-)
diff --git a/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp b/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
index f3226d3d5695ca..24b82136544c27 100644
--- a/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
+++ b/clang/test/SemaCXX/builtin-assume-aligned-tmpl.cpp
@@ -106,50 +106,8 @@ void foo() {
namespace GH194289 {
template<int qux>
void bar() { // expected-note {{'bar' declared here}} expected-note {{possible target for call}}
- int foo = (int *) __builtin_assume_aligned(baz, qux + 1);
+ (void)__builtin_assume_aligned(baz, qux + 1);
// expected-error at -1 {{use of undeclared identifier 'baz'; did you mean 'bar'?}}
// expected-error at -2 {{reference to overloaded function could not be resolved}}
- // expected-error at -3 {{cannot initialize a variable of type 'int'}}
-}
-
-template<int qux>
-void bar2() { // expected-note {{'bar2' declared here}} expected-note {{possible target for call}}
- (void)__builtin_assume_aligned(baz2, 8);
- // expected-error at -1 {{use of undeclared identifier 'baz2'; did you mean 'bar2'?}}
- // expected-error at -2 {{reference to overloaded function could not be resolved}}
-}
-
-void qux_fn(); // expected-note 2 {{'qux_fn' declared here}}
-void typo_to_function() {
- (void)__builtin_assume_aligned(qux_fm, 8); // expected-error {{use of undeclared identifier 'qux_fm'; did you mean 'qux_fn'?}}
- (void)__builtin_assume_aligned(no_such_pointer, 8); // expected-error {{use of undeclared identifier 'no_such_pointer'}}
-}
-
-template<int N>
-void typo_to_function_tmpl() {
- (void)__builtin_assume_aligned(qux_fm, 8); // expected-error {{use of undeclared identifier 'qux_fm'; did you mean 'qux_fn'?}}
- (void)__builtin_assume_aligned(no_such_pointer, N); // expected-error {{use of undeclared identifier 'no_such_pointer'}}
-}
-
-template<int N> void aligned_to(int *p) { (void)__builtin_assume_aligned(p, N); } // expected-error 3 {{requested alignment is not a power of 2}}
-template<unsigned long long N> void aligned_to_ull(int *p) { (void)__builtin_assume_aligned(p, N); } // expected-warning {{requested alignment must be 4294967296 bytes or smaller}}
-template<typename T> void dep_ptr(T p) { (void)__builtin_assume_aligned(p, 8); } // expected-error {{non-pointer argument to '__builtin_assume_aligned' is not allowed}}
-template<typename T, int N> void dep_both(T p) { (void)__builtin_assume_aligned(p, N); } // expected-error {{requested alignment is not a power of 2}}
-template<int O> void dep_off(int *p) { (void)__builtin_assume_aligned(p, 8, O); }
-template<typename T> void dep_off_ty(int *p, T o) { (void)__builtin_assume_aligned(p, 8, o); } // expected-error {{cannot initialize a parameter of type '__size_t'}}
-
-void instantiate(int *p) {
- aligned_to<8>(p);
- aligned_to<7>(p); // expected-note {{in instantiation of function template specialization 'GH194289::aligned_to<7>' requested here}}
- aligned_to<0>(p); // expected-note {{in instantiation of function template specialization 'GH194289::aligned_to<0>' requested here}}
- aligned_to<-32>(p); // expected-note {{in instantiation of function template specialization 'GH194289::aligned_to<-32>' requested here}}
- aligned_to_ull<1ULL << 33>(p); // expected-note {{in instantiation of function template specialization 'GH194289::aligned_to_ull<8589934592ULL>' requested here}}
- dep_ptr(p);
- dep_ptr(0); // expected-note {{in instantiation of function template specialization 'GH194289::dep_ptr<int>' requested here}}
- dep_both<int *, 16>(p);
- dep_both<int *, 3>(p); // expected-note {{in instantiation of function template specialization 'GH194289::dep_both<int *, 3>' requested here}}
- dep_off<4>(p);
- dep_off_ty(p, 4);
- dep_off_ty(p, p); // expected-note {{in instantiation of function template specialization 'GH194289::dep_off_ty<int *>' requested here}}
}
}
More information about the cfe-commits
mailing list