On Thu, Oct 10, 2019 at 06:06:40PM +0000, 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.
> 
> The problem there is that CLASSTYPE_TI_TEMPLATE (type)
> uses CLASSTYPE_TEMPLATE_INFO (type) but that is NULL.

... because the warning is called from pushtag which ran before building the
template info for 'c':
 9926       // Build template info for the new specialization.
 9927       SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist));

Looks like another indication that the shadow checking is done too early.

> Since other errors may return error_mark_node as well
> and the template is totally erroneous anyway, I figured
> we might get away with that simple fix. 

But it doesn't have to be broken; this valid test crashes with that option too

template<typename>
struct S {
  S () {
    struct c;
      {
        struct c {};
      }
  }
};

S<int> s;

--
Marek Polacek • Red Hat, Inc. • 300 A St, Boston, MA

Reply via email to