Hi!

The r250440 change removed two spots that ensured that for
!CLASS_TYPE_P (type) it returned -1 (from the idx routines that
are gone now) and eventually NULL from the non-idx ones.
I've bootstrapped/regtested a change with various assertions that
showed that except for this testcase and spot in build_user_type_conversion_1
other spots invoked during bootstrap/regtest have only CLASS_TYPE_P types
in lookup_fnfields_slot and lookup_fnfields_slot_nolazy, and obviously
for MAYBE_CLASS_TYPE_P (totype) && !CLASS_TYPE_P (totype) it used to return
NULL all the time.

I've bootstrapped/regtested the following patch last night and committed
after preapproval from Nathan, though of course a question is if
lookup_fnfields_slot/lookup_fnfields_slot_nolazy shouldn't have
if (!CLASS_TYPE_P (type)) return NULL_TREE; or
gcc_assert (!CLASS_TYPE_P (type));
readded to the beginning of those functions.

2017-08-02  Jakub Jelinek  <ja...@redhat.com>

        PR c++/81640
        * call.c (build_user_type_conversion_1): Only call
        lookup_fnfields_slot if totype is CLASS_TYPE_P.

        * g++.dg/warn/Wshadow-compatible-local-2.C: New test.

--- gcc/cp/call.c.jj    2017-07-24 10:58:10.000000000 +0200
+++ gcc/cp/call.c       2017-08-01 22:40:37.134412941 +0200
@@ -3735,7 +3735,7 @@ build_user_type_conversion_1 (tree totyp
   gcc_assert (!MAYBE_CLASS_TYPE_P (fromtype) || !MAYBE_CLASS_TYPE_P (totype)
              || !DERIVED_FROM_P (totype, fromtype));
 
-  if (MAYBE_CLASS_TYPE_P (totype))
+  if (CLASS_TYPE_P (totype))
     /* Use lookup_fnfields_slot instead of lookup_fnfields to avoid
        creating a garbage BASELINK; constructors can't be inherited.  */
     ctors = lookup_fnfields_slot (totype, complete_ctor_identifier);
--- gcc/testsuite/g++.dg/warn/Wshadow-compatible-local-2.C.jj   2017-08-01 
22:44:41.250901144 +0200
+++ gcc/testsuite/g++.dg/warn/Wshadow-compatible-local-2.C      2017-08-01 
22:44:08.000000000 +0200
@@ -0,0 +1,21 @@
+// PR c++/81640
+// { dg-do compile }
+// { dg-options "-Wshadow=compatible-local" }
+
+struct A {};
+struct B { operator bool () const { return true; } };
+
+template <typename T>
+void
+foo ()
+{
+  T d, e;
+  if (e)
+    A d;
+}
+
+void
+bar ()
+{
+  foo <B> ();
+}

        Jakub

Reply via email to