[clang] 6bb3a35 - [clang] Improve diagnostics for `__builtin_align` builtins with floating/member pointer operands (#192650)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 17 22:06:11 PDT 2026
Author: 🍌Shawn
Date: 2026-04-18T13:06:06+08:00
New Revision: 6bb3a3563025d55177e5416277c52cb1801ec2c1
URL: https://github.com/llvm/llvm-project/commit/6bb3a3563025d55177e5416277c52cb1801ec2c1
DIFF: https://github.com/llvm/llvm-project/commit/6bb3a3563025d55177e5416277c52cb1801ec2c1.diff
LOG: [clang] Improve diagnostics for `__builtin_align` builtins with floating/member pointer operands (#192650)
Improve diagnostics for `__builtin_align_up`, `__builtin_align_down`,
and `__builtin_is_aligned` when the first operand has an invalid type.
Clang already emits `err_typecheck_expect_scalar_operand` for
unsupported operands, but the message is generic. This patch adds
follow-up notes to clarify three common invalid cases:
* floating point operands (“floating point types are not allowed here”)
* C++ member pointer operands (“member pointers are not allowed here”)
* plain-function-pointer ("function pointers are not allowed here")
Added:
Modified:
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaChecking.cpp
clang/test/Sema/builtin-align.c
clang/test/SemaCXX/builtin-align-cxx.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 1380eb97cdd79..193758221c0a9 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -156,6 +156,12 @@ def err_ice_explicit_conversion : Error<
"integral constant expression requires explicit conversion from %0 to %1">;
def note_ice_conversion_here : Note<
"conversion to %select{integral|enumeration}0 type %1 declared here">;
+def note_alignment_invalid_type : Note<
+ "floating point types are not allowed here">;
+def note_alignment_invalid_member_pointer : Note<
+ "member pointers are not allowed here">;
+def note_alignment_invalid_function_pointer : Note<
+ "function pointers are not allowed here">;
def err_ice_ambiguous_conversion : Error<
"ambiguous conversion from type %0 to an integral or unscoped "
"enumeration type">;
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 3f6e44b45a0a4..7caae4e66f5b7 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -336,10 +336,15 @@ static bool BuiltinAlignment(Sema &S, CallExpr *TheCall, unsigned ID) {
}
if ((!SrcTy->isPointerType() && !IsValidIntegerType(SrcTy)) ||
SrcTy->isFunctionPointerType()) {
- // FIXME: this is not quite the right error message since we don't allow
- // floating point types, or member pointers.
S.Diag(Source->getExprLoc(), diag::err_typecheck_expect_scalar_operand)
<< SrcTy;
+ if (SrcTy->isFloatingType())
+ S.Diag(Source->getExprLoc(), diag::note_alignment_invalid_type);
+ else if (SrcTy->isMemberPointerType())
+ S.Diag(Source->getExprLoc(), diag::note_alignment_invalid_member_pointer);
+ else if (SrcTy->isFunctionPointerType())
+ S.Diag(Source->getExprLoc(),
+ diag::note_alignment_invalid_function_pointer);
return true;
}
diff --git a/clang/test/Sema/builtin-align.c b/clang/test/Sema/builtin-align.c
index bf9a89234fea5..c33ad8d1ad0ef 100644
--- a/clang/test/Sema/builtin-align.c
+++ b/clang/test/Sema/builtin-align.c
@@ -25,6 +25,10 @@ void test_parameter_types(char *ptr, size_t size) {
(void)ALIGN_BUILTIN((int)e, 2); // but with a cast it is fine
(void)ALIGN_BUILTIN((int)b, 2); // but with a cast it is fine
+ // Floating point types are not allowed:
+ (void)ALIGN_BUILTIN(1.0, 4); // expected-error {{operand of type 'double' where arithmetic or pointer type is required}} expected-note {{floating point types are not allowed here}}
+ (void)ALIGN_BUILTIN(1.0f, 4); // expected-error {{operand of type 'float' where arithmetic or pointer type is required}} expected-note {{floating point types are not allowed here}}
+
// The second parameter must be an integer type (but not enum or _Bool):
(void)ALIGN_BUILTIN(ptr, size);
(void)ALIGN_BUILTIN(ptr, ptr); // expected-error {{used type 'char *' where integer is required}}
@@ -129,5 +133,5 @@ char *test_array_and_fnptr(void) {
(void)(ALIGN_BUILTIN(buf, 16));
// But not on functions and function pointers:
(void)(ALIGN_BUILTIN(test_array_and_fnptr, 16)); // expected-error{{operand of type 'char *(void)' where arithmetic or pointer type is required}}
- (void)(ALIGN_BUILTIN(&test_array_and_fnptr, 16)); // expected-error{{operand of type 'char *(*)(void)' where arithmetic or pointer type is required}}
+ (void)(ALIGN_BUILTIN(&test_array_and_fnptr, 16)); // expected-error{{operand of type 'char *(*)(void)' where arithmetic or pointer type is required}} expected-note{{function pointers are not allowed here}}
}
diff --git a/clang/test/SemaCXX/builtin-align-cxx.cpp b/clang/test/SemaCXX/builtin-align-cxx.cpp
index 806bb660e0042..213a285e23eb2 100644
--- a/clang/test/SemaCXX/builtin-align-cxx.cpp
+++ b/clang/test/SemaCXX/builtin-align-cxx.cpp
@@ -85,9 +85,9 @@ class MemPtr {
virtual void vfunc();
};
void test_member_ptr() {
- __builtin_align_up(&MemPtr::data, 64); // expected-error{{operand of type 'int MemPtr::*' where arithmetic or pointer type is required}}
- __builtin_align_down(&MemPtr::func, 64); // expected-error{{operand of type 'void (MemPtr::*)()' where arithmetic or pointer type is required}}
- __builtin_is_aligned(&MemPtr::vfunc, 64); // expected-error{{operand of type 'void (MemPtr::*)()' where arithmetic or pointer type is required}}
+ __builtin_align_up(&MemPtr::data, 64); // expected-error{{operand of type 'int MemPtr::*' where arithmetic or pointer type is required}} expected-note{{member pointers are not allowed here}}
+ __builtin_align_down(&MemPtr::func, 64); // expected-error{{operand of type 'void (MemPtr::*)()' where arithmetic or pointer type is required}} expected-note{{member pointers are not allowed here}}
+ __builtin_is_aligned(&MemPtr::vfunc, 64); // expected-error{{operand of type 'void (MemPtr::*)()' where arithmetic or pointer type is required}} expected-note{{member pointers are not allowed here}}
}
void test_references(Foo &i) {
More information about the cfe-commits
mailing list