On 10/11/19 6:31 PM, Jason Merrill wrote:
> On 10/10/19 2:06 PM, Bernd Edlinger wrote:
>> On 10/10/19 7:49 PM, Jason Merrill wrote:
>>> On 10/10/19 10:42 AM, Bernd Edlinger wrote:
>>>> Hi,
>>>>
>>>> this fixes a crash when -Wshadow=compatible-local is
>>>> enabled in the testcase g++.dg/parse/crash68.C
>>>
>>> Why does that flag cause this crash?
>>>
>>
>> gcc/cp/name-lookup.c:
>>
>>        if (warn_shadow)
>>          warning_code = OPT_Wshadow;
>>        else if (warn_shadow_local)
>>          warning_code = OPT_Wshadow_local;
>>        else if (warn_shadow_compatible_local
>>                 && (same_type_p (TREE_TYPE (old), TREE_TYPE (decl))
>>                     || (!dependent_type_p (TREE_TYPE (decl))
>>                         && !dependent_type_p (TREE_TYPE (old))
>>                         /* If the new decl uses auto, we don't yet know
>>                            its type (the old type cannot be using auto
>>                            at this point, without also being
>>                            dependent).  This is an indication we're
>>                            (now) doing the shadow checking too
>>                            early.  */
>>                         && !type_uses_auto (TREE_TYPE (decl))
>>                         && can_convert (TREE_TYPE (old), TREE_TYPE (decl),
>>                                         tf_none))))
>>          warning_code = OPT_Wshadow_compatible_local;
>>
>> if -Wshadow=compatible-local is used, the can_convert function crashes
>> in instantiate_class_template_1.
> 
> Right, checking can_convert is problematic here, as it can cause template 
> instantiations that change the semantics of the program.  Or, in this case, 
> crash.
> 

Ah, alright.

I think shadowing one type with another type of the same name is always a no no.
How about always warning (and not asking for can_convert) when either decl is a 
TYPE_DECL?

like this:

Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c        (Revision 276886)
+++ gcc/cp/name-lookup.c        (Arbeitskopie)
@@ -2741,8 +2741,7 @@
          return;
        }
 
-      /* If '-Wshadow=compatible-local' is specified without other
-        -Wshadow= flags, we will warn only when the type of the
+      /* -Wshadow=compatible-local warns only when the type of the
         shadowing variable (DECL) can be converted to that of the
         shadowed parameter (OLD_LOCAL). The reason why we only check
         if DECL's type can be converted to OLD_LOCAL's type (but not the
@@ -2750,29 +2749,29 @@
         parameter, more than often they would use the variable
         thinking (mistakenly) it's still the parameter. It would be
         rare that users would use the variable in the place that
-        expects the parameter but thinking it's a new decl.  */
+        expects the parameter but thinking it's a new decl.
+        If either object is a TYPE_DECL -Wshadow=compatible-local
+        warns regardless of whether one of the types involved
+        is a subclass of the other, since that is never okay.  */
 
       enum opt_code warning_code;
-      if (warn_shadow)
-       warning_code = OPT_Wshadow;
-      else if (warn_shadow_local)
-       warning_code = OPT_Wshadow_local;
-      else if (warn_shadow_compatible_local
-              && (same_type_p (TREE_TYPE (old), TREE_TYPE (decl))
-                  || (!dependent_type_p (TREE_TYPE (decl))
-                      && !dependent_type_p (TREE_TYPE (old))
-                      /* If the new decl uses auto, we don't yet know
-                         its type (the old type cannot be using auto
-                         at this point, without also being
-                         dependent).  This is an indication we're
-                         (now) doing the shadow checking too
-                         early.  */
-                      && !type_uses_auto (TREE_TYPE (decl))
-                      && can_convert (TREE_TYPE (old), TREE_TYPE (decl),
-                                      tf_none))))
+      if (same_type_p (TREE_TYPE (old), TREE_TYPE (decl))
+         || TREE_CODE (decl) == TYPE_DECL
+         || TREE_CODE (old) == TYPE_DECL
+         || (!dependent_type_p (TREE_TYPE (decl))
+             && !dependent_type_p (TREE_TYPE (old))
+             /* If the new decl uses auto, we don't yet know
+                its type (the old type cannot be using auto
+                at this point, without also being
+                dependent).  This is an indication we're
+                (now) doing the shadow checking too
+                early.  */
+             && !type_uses_auto (TREE_TYPE (decl))
+             && can_convert (TREE_TYPE (old), TREE_TYPE (decl),
+                             tf_none)))
        warning_code = OPT_Wshadow_compatible_local;
       else
-       return;
+       warning_code = OPT_Wshadow_local;
 
       const char *msg;
       if (TREE_CODE (old) == PARM_DECL)


Bernd.

Reply via email to