https://github.com/a-tarasyuk updated https://github.com/llvm/llvm-project/pull/113777
>From 2ef4cc6c16d2217053f90fe4c3d2f251a52e0c60 Mon Sep 17 00:00:00 2001 From: Oleksandr T <oleksandr.taras...@outlook.com> Date: Thu, 7 Nov 2024 15:14:05 +0200 Subject: [PATCH] [Clang] skip default argument instantiation for non-defining friend declarations without specialization info to meet [dcl.fct.default]p4 --- clang/docs/ReleaseNotes.rst | 2 ++ clang/lib/Sema/SemaExpr.cpp | 11 +++++++++++ clang/test/CXX/temp/temp.res/p4.cpp | 19 +++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 061a1fed3f7d48..220cfb222c49d4 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -595,6 +595,8 @@ Bug Fixes to C++ Support an implicitly instantiated class template specialization. (#GH51051) - Fixed an assertion failure caused by invalid enum forward declarations. (#GH112208) - Name independent data members were not correctly initialized from default member initializers. (#GH114069) +- Fixed an assertion failure caused by invalid default argument substitutions in non-defining + friend declarations. (#GH113324). Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 49fdb5b5ab43da..df8f025030e2b1 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -6018,6 +6018,17 @@ bool Sema::GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, } else { assert(Param && "can't use default arguments without a known callee"); + // FIXME: We don't track member specialization info for non-defining + // friend declarations, so we will not be able to later find the function + // pattern. As a workaround, don't instantiate the default argument in + // this case. This is correct per wording and only an error recovery + // issue, as per [dcl.fct.default]p4: + // if a friend declaration D specifies a default argument expression, + // that declaration shall be a definition. + if (FDecl->getFriendObjectKind() != Decl::FOK_None && + FDecl->getMemberSpecializationInfo() == nullptr) + return true; + ExprResult ArgExpr = BuildCXXDefaultArgExpr(CallLoc, FDecl, Param); if (ArgExpr.isInvalid()) return true; diff --git a/clang/test/CXX/temp/temp.res/p4.cpp b/clang/test/CXX/temp/temp.res/p4.cpp index f54d8649f5da88..743ffed14d81a8 100644 --- a/clang/test/CXX/temp/temp.res/p4.cpp +++ b/clang/test/CXX/temp/temp.res/p4.cpp @@ -185,3 +185,22 @@ template<typename T> struct S { friend void X::f(T::type); }; } + +namespace GH113324 { +template <typename = int> struct ct { + friend void f1(ct, int = 0); // expected-error {{friend declaration specifying a default argument must be a definition}} + friend void f2(ct a, ct = decltype(a){ }); // expected-error {{friend declaration specifying a default argument must be a definition}} +}; + +template<class T> using alias = int; +template<typename T> struct C { + // FIXME: We miss diagnosing the default argument instantiation failure (forming reference to void) + friend void f3(C, int a = alias<T&>(1)); // expected-error {{friend declaration specifying a default argument must be a definition}} +}; + +void test() { + f1(ct<>{}); + f2(ct<>{}); + f3(C<void>()); +} +} // namespace GH113324 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits