[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:07:19 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: lsh4711

<details>
<summary>Changes</summary>

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.

---
Full diff: https://github.com/llvm/llvm-project/pull/235313.diff


3 Files Affected:

- (modified) clang/docs/ReleaseNotes.md (+4) 
- (modified) clang/lib/Sema/SemaChecking.cpp (+8) 
- (modified) clang/test/SemaCXX/builtins.cpp (+7) 


``````````diff
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 {

``````````

</details>


https://github.com/llvm/llvm-project/pull/235313


More information about the cfe-commits mailing list