https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121179
--- Comment #1 from GCC Commits <cvs-commit at gcc dot gnu.org> --- The master branch has been updated by Patrick Palka <ppa...@gcc.gnu.org>: https://gcc.gnu.org/g:7590c14b53a762ab30f5026148bd1cb9cf142264 commit r16-2448-g7590c14b53a762ab30f5026148bd1cb9cf142264 Author: Patrick Palka <ppa...@redhat.com> Date: Wed Jul 23 08:38:12 2025 -0400 c++: name lookup for non-dep rewritten != expr [PR121179] Here we're incorrectly rejecting the modules testcase (reduced from a std module example): $ cat 121179_a.C export module foo; enum class E { x }; bool operator==(E, int); export template<class T> void f() { E::x != 0; } $ cat 121179_b.C import foo; template void f<int>(); $ g++ -fmodules 121179_*.C In module foo, imported at 121179_b.C:1: 121179_a.C: In instantiation of âvoid f@foo() [with T = int]â: 121179_b.C:3:9: required from here 121179_a.C:9:8: error: no match for âoperator!=â (operand types are âE@fooâ and âintâ) This is ultimately because our non-dependent rewritten operator expression handling throws away the result of unqualified lookup at template parse time, and so we have to repeat the lookup at instantiation time which fails because the operator== isn't exported. This is a known deficiency, but it's easy enough to narrowly fix this for simple != to == rewrites by making build_min_non_dep_op_overload look through logical negation. PR c++/121179 gcc/cp/ChangeLog: * call.cc (build_new_op): Don't clear *overload for a simple != to == rewrite. * tree.cc (build_min_non_dep_op_overload): Handle TRUTH_NOT_EXPR appearing in a rewritten operator expression. gcc/testsuite/ChangeLog: * g++.dg/lookup/operator-8.C: Strengthen test and remove one XFAIL. Reviewed-by: Jason Merrill <ja...@redhat.com>