[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #15 from sandra at gcc dot gnu.org --- See also PR115076. I think the low-level implementation of "declare variant" is all wrong, it needs to be tracked in the lexical scope by each front end instead of attached as a global property of the decl for use by the middle end. Call sites would expand into some sort of variant construct similar to OMP_METADIRECTIVE that contains CALL_EXPRs for all the alternatives that cannot be statically resolved in the front end. In that case we'd have the actual arguments available for overload resolution and template expansion in C++.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #14 from Jason Merrill --- (In reply to Jakub Jelinek from comment #7) > "The function variant is determined by base language standard name lookup > rules ([basic.lookup]) of variant-name using the argument types at the call > site after implementation defined changes have been made according to the > OpenMP context." This is interestingly different from the 5.0 spec, which said "The function variant is determined by base language standard name lookup rules ([basic.lookup]) of variant-func-id with arguments that correspond to the argument types in the base function declaration." 5.0 specifies a lookup like GCC does, based on the parameters of the base function, while 6.0 specifies a lookup based on the actual arguments in the call. That still doesn't specify trying to copy explicit template arguments from base to variant, but that could be a plausible next step. Doing that would require rejecting expl2 in in PR118488, since it isn't a template.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #13 from Jason Merrill --- (In reply to Tobias Burnus from comment #11) > clang++ (since 11.0 and up to main) accepts the attached testcase clang++ also accepts the testcase with static_assert(false) added to the variants, it doesn't seem to be instantiating them. (In reply to Jakub Jelinek from comment #12) > My understanding is that the intent is for the variant function to have > (except for the simd special case which according to the ABI can tweak > stuff) always the same argument types as the base function Yes, both functions have type void(int&&), and omp_declare_variant_finalize_one checks that. The difference is in the template argument (explicitly specified or deduced), not the function type.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #12 from Jakub Jelinek --- My understanding is that the intent is for the variant function to have (except for the simd special case which according to the ABI can tweak stuff) always the same argument types as the base function, so not have int && in one case and int in another or vice versa etc., after all, the replacement can happen during the compilation at any time, not just in the FE, but during early GIMPLE stages or even after IPA in some cases. And at that point there is no FE to deal with remapping int argument to int && or similar. Dunno if OpenMP 6.0 allows dynamic declare variant, even if not, some newer version could have that. And it is much better to just be able to do indirect call through one function pointer in that case, rather than dealing with special cases, for this variant one needs to use such and such thunk etc.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #11 from Tobias Burnus --- Just FYI without directly validity: clang++ (since 11.0 and up to main) accepts the attached testcase (comment 0 / attachment 60417) * * * Cross ref [vaguely related; C++ return-value + templates with OpenMP variant resolving]: - recently fixed: PR118486 (return-type related fix: rejects valid + invalid w/ bogus diagostic), r15-4799-gf011f890818 (fix ref-returning funcs, minor follow up: r15-4801-gf7ae087ef01) - the commit under discussion in comment 5, r15-6707-gdd3f3c71df66ed - Unresolved: PR118530, PR118488, PR112810 (old, non-OpenMP) - OpenMP spec Issue 4446 (generic ideas, but rather vague; private issue)
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #10 from waffl3x --- (OpenMP 6.0 113:1-2) variant substitution The replacement of a call to a base function by a call to a function variant This quote probably supports my claim better than the previous one.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #9 from waffl3x --- (In reply to Jason Merrill from comment #6) > omp_declare_variant_finalize_one works by building a forwarding call to the > variant, i.e. rvalue_int_variant(std::forward(p)). Normal template > argument deduction from T&& vs int&& then deduces int for T, as substituting > int for T produces int&&, which is the desired type. Note that the decltype > checks pass. > > It's not clear to me that this behavior is wrong; the OpenMP standard says > nothing about templates. (OpenMP 6.0, 328:30) For a function variant to be a replacement candidate to be called instead of the base function, I interpret this to mean that the function variant is called instead of the base function, so I would assume deduction should be as if the variant were called directly. But... (In reply to Jakub Jelinek from comment #7) > The OpenMP wording here (taken from 6.0 but I think it hasn't changed much > over the years) is: > > "The function variant is determined by base language standard name lookup > rules ([basic.lookup]) of variant-name using the argument types at the call > site after implementation defined changes have been made according to the > OpenMP context." > > Note, it was a result of your suggestion how to do it (the original proposal > was to mark the function the other way, on variant says that it is a variant > of some base but with overloaded functions and templates that isn't clear > how that would work at all. > > The "implementation defined changes" are just for simd, so in this testcase > it should be really just the argument dependent lookup with the given > argument types. I'm not sure how that would conflict with this stuff, I was initially thinking it might be inconsequential for this bug but thinking about it more I'm not so sure.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #8 from Jason Merrill --- The current GCC behavior seems to match that specification.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 --- Comment #7 from Jakub Jelinek --- The OpenMP wording here (taken from 6.0 but I think it hasn't changed much over the years) is: "The function variant is determined by base language standard name lookup rules ([basic.lookup]) of variant-name using the argument types at the call site after implementation defined changes have been made according to the OpenMP context." Note, it was a result of your suggestion how to do it (the original proposal was to mark the function the other way, on variant says that it is a variant of some base but with overloaded functions and templates that isn't clear how that would work at all. The "implementation defined changes" are just for simd, so in this testcase it should be really just the argument dependent lookup with the given argument types.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 Jason Merrill changed: What|Removed |Added Status|ASSIGNED|WAITING --- Comment #6 from Jason Merrill --- omp_declare_variant_finalize_one works by building a forwarding call to the variant, i.e. rvalue_int_variant(std::forward(p)). Normal template argument deduction from T&& vs int&& then deduces int for T, as substituting int for T produces int&&, which is the desired type. Note that the decltype checks pass. It's not clear to me that this behavior is wrong; the OpenMP standard says nothing about templates.
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 Jason Merrill changed: What|Removed |Added Status|UNCONFIRMED |ASSIGNED Assignee|unassigned at gcc dot gnu.org |jason at gcc dot gnu.org Last reconfirmed||2025-02-11 CC||jason at gcc dot gnu.org Ever confirmed|0 |1
[Bug c++/118791] [15 Regression][OpenMP] declare variant messes up template instantiation with rvalue arguments
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118791 Tobias Burnus changed: What|Removed |Added Summary|declare variant messes up |[15 Regression][OpenMP] |template instantiation with |declare variant messes up |rvalue arguments|template instantiation with ||rvalue arguments Target Milestone|--- |15.0
