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 &lt;typename T&gt; void f(int *) {}
void (*p)(int *) = __builtin_addressof(f&lt;int&gt;);
```

Clang crashes on this (an invalid `cast&lt;OverloadExpr&gt;`).
`BuiltinAddressof` leaves an overload set operand unresolved like `&amp;` 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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to