diff mbox

[C++,committed] Fix ICE with -Wshadow=compatible-local (PR c++/81640)

Message ID 20170802073801.GH2123@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Aug. 2, 2017, 7:38 a.m. UTC
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  <jakub@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.


	Jakub

Comments

Jason Merrill Aug. 4, 2017, 4:50 p.m. UTC | #1
On Wed, Aug 2, 2017 at 3:38 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> 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.

It seems that we already ICE if we call it with a non-class type, so
adding an assert would just document that behavior?

Jason
Jakub Jelinek Aug. 4, 2017, 4:58 p.m. UTC | #2
On Fri, Aug 04, 2017 at 12:50:36PM -0400, Jason Merrill wrote:
> On Wed, Aug 2, 2017 at 3:38 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> > 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.
> 
> It seems that we already ICE if we call it with a non-class type, so
> adding an assert would just document that behavior?

CLASSTYPE_METHOD_VEC doesn't exactly check CLASS_TYPE_P if checking,
it just requires that LANG_TYPE_CLASS_CHECK is non-NULL (dunno if there
are any non-CLASS_TYPE_P types that have it non-NULL, or any CLASS_TYPE_P
types that have it NULL).
But yes, for checking builds it would be primarily documentation, for
checking builds likely too, because if TYPE_LANG_SPECIFIC is NULL,
then CLASSTYPE_METHOD_VEC will dereference NULL.

	Jakub
diff mbox

Patch

--- 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> ();
+}