[clang] [clang] Fix crash on __builtin_addressof of an overload set (PR #235313)
via cfe-commits
cfe-commits at lists.llvm.org
Sat Oct 24 09:06:15 PDT 2026
https://github.com/lsh4711 created https://github.com/llvm/llvm-project/pull/235313
Found while developing syscript (https://github.com/ssclang/syscript), a compiler frontend that uses a TypeScript parser and clang.
```cpp
template <typename T> void f(int *) {}
void (*p)(int *) = __builtin_addressof(f<int>);
```
Clang crashes on this (an invalid `cast<OverloadExpr>`).
`BuiltinAddressof` leaves an overload set operand unresolved like `&` does, but nothing resolves it later for the builtin.
This resolves the operand with `CheckPlaceholderExpr`, so it behaves like `std::addressof`.
An unresolvable overload set is now diagnosed instead of crashing.
>From 48ca372508fd09921de76f4757b0d51710d21789 Mon Sep 17 00:00:00 2001
From: lsh4711 <120231876+lsh4711 at users.noreply.github.com>
Date: Sun, 25 Oct 2026 00:55:43 +0900
Subject: [PATCH] [clang] Fix crash on __builtin_addressof of an overload set
__builtin_addressof left an overload set operand unresolved, but unlike
the '&' operator there is no later point that resolves it against a
target type, so the unresolved call reached code that only expects an
OverloadExpr and crashed. Resolve the operand immediately, as for any
other function argument, which matches std::addressof.
---
clang/docs/ReleaseNotes.md | 4 ++++
clang/lib/Sema/SemaChecking.cpp | 8 ++++++++
clang/test/SemaCXX/builtins.cpp | 7 +++++++
3 files changed, 19 insertions(+)
diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md
index 44f30666457f94..98f5369cdde701 100644
--- a/clang/docs/ReleaseNotes.md
+++ b/clang/docs/ReleaseNotes.md
@@ -1121,6 +1121,10 @@ documentation](CIR/index.md) for more information regarding ClangIR's status and
init-captures in default member initializers used during aggregate
initialization. (#GH196469)
+- Fixed a crash when the operand of `__builtin_addressof` is an overload set.
+ A function template specialization such as `f<int>` is now resolved like the
+ argument of `std::addressof`, and an unresolvable overload set is diagnosed.
+
#### Bug Fixes to AST Handling
- Fixed a non-deterministic ordering of unused local typedefs that made
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 675975168e5048..ce0b4628a746be 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -272,6 +272,14 @@ static bool BuiltinAddressof(Sema &S, CallExpr *TheCall) {
return true;
ExprResult Arg(TheCall->getArg(0));
+
+ // Unlike '&', nothing resolves the overload set later, so resolve it now.
+ if (Arg.get()->getType() == S.Context.OverloadTy) {
+ Arg = S.CheckPlaceholderExpr(Arg.get());
+ if (Arg.isInvalid())
+ return true;
+ }
+
QualType ResultType = S.CheckAddressOfOperand(Arg, TheCall->getBeginLoc());
if (ResultType.isNull())
return true;
diff --git a/clang/test/SemaCXX/builtins.cpp b/clang/test/SemaCXX/builtins.cpp
index f99bb87b9cbd40..f6e202f250c649 100644
--- a/clang/test/SemaCXX/builtins.cpp
+++ b/clang/test/SemaCXX/builtins.cpp
@@ -48,6 +48,13 @@ namespace addressof {
int *pbf = __builtin_addressof(u.n); // expected-error {{address of bit-field requested}}
S *ptmp = __builtin_addressof(S{}); // expected-error {{taking the address of a temporary}} expected-warning {{temporary whose address is used as value of local variable 'ptmp' will be destroyed at the end of the full-expression}}
+
+ template <typename T> void tmpl(T) {}
+ static_assert(__builtin_addressof(tmpl<int>) == &tmpl<int>, "");
+
+ void ovl(int); // expected-note {{possible target for call}}
+ void ovl(long); // expected-note {{possible target for call}}
+ void (*povl)(int) = __builtin_addressof(ovl); // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
}
namespace function_start {
More information about the cfe-commits
mailing list