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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
