PR c++/79296 - ICE mangling localized template instantiation

PR c++/79296 - ICE mangling localized template instantiation
	* decl2.c (determine_visibility): Use template fn context for
	local class instantiations.

	PR c++/79296
	* g++.dg/cpp0x/pr79296.C: New.

From-SVN: r245398
This commit is contained in:
Nathan Sidwell 2017-02-13 17:42:31 +00:00 committed by Nathan Sidwell
parent 7953a24c60
commit b9a161ff70
4 changed files with 50 additions and 20 deletions

View File

@ -1,3 +1,9 @@
2017-02-13 Nathan Sidwell <nathan@acm.org>
PR c++/79296 - ICE mangling localized template instantiation
* decl2.c (determine_visibility): Use template fn context for
local class instantiations.
2017-02-11 Jason Merrill <jason@redhat.com>
PR c++/77659 - ICE with new and C++14 aggregate NSDMI

View File

@ -2225,11 +2225,6 @@ constrain_visibility_for_template (tree decl, tree targs)
void
determine_visibility (tree decl)
{
tree class_type = NULL_TREE;
bool use_template;
bool orig_visibility_specified;
enum symbol_visibility orig_visibility;
/* Remember that all decls get VISIBILITY_DEFAULT when built. */
/* Only relevant for names with external linkage. */
@ -2241,25 +2236,28 @@ determine_visibility (tree decl)
maybe_clone_body. */
gcc_assert (!DECL_CLONED_FUNCTION_P (decl));
orig_visibility_specified = DECL_VISIBILITY_SPECIFIED (decl);
orig_visibility = DECL_VISIBILITY (decl);
bool orig_visibility_specified = DECL_VISIBILITY_SPECIFIED (decl);
enum symbol_visibility orig_visibility = DECL_VISIBILITY (decl);
/* The decl may be a template instantiation, which could influence
visibilty. */
tree template_decl = NULL_TREE;
if (TREE_CODE (decl) == TYPE_DECL)
{
if (CLASS_TYPE_P (TREE_TYPE (decl)))
use_template = CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl));
{
if (CLASSTYPE_USE_TEMPLATE (TREE_TYPE (decl)))
template_decl = decl;
}
else if (TYPE_TEMPLATE_INFO (TREE_TYPE (decl)))
use_template = 1;
else
use_template = 0;
template_decl = decl;
}
else if (DECL_LANG_SPECIFIC (decl))
use_template = DECL_USE_TEMPLATE (decl);
else
use_template = 0;
else if (DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl))
template_decl = decl;
/* If DECL is a member of a class, visibility specifiers on the
class can influence the visibility of the DECL. */
tree class_type = NULL_TREE;
if (DECL_CLASS_SCOPE_P (decl))
class_type = DECL_CONTEXT (decl);
else
@ -2302,8 +2300,11 @@ determine_visibility (tree decl)
}
/* Local classes in templates have CLASSTYPE_USE_TEMPLATE set,
but have no TEMPLATE_INFO, so don't try to check it. */
use_template = 0;
but have no TEMPLATE_INFO. Their containing template
function does, and the local class could be constrained
by that. */
if (template_decl)
template_decl = fn;
}
else if (VAR_P (decl) && DECL_TINFO_P (decl)
&& flag_visibility_ms_compat)
@ -2333,7 +2334,7 @@ determine_visibility (tree decl)
&& !CLASSTYPE_VISIBILITY_SPECIFIED (TREE_TYPE (DECL_NAME (decl))))
targetm.cxx.determine_class_data_visibility (decl);
}
else if (use_template)
else if (template_decl)
/* Template instantiations and specializations get visibility based
on their template unless they override it with an attribute. */;
else if (! DECL_VISIBILITY_SPECIFIED (decl))
@ -2350,11 +2351,11 @@ determine_visibility (tree decl)
}
}
if (use_template)
if (template_decl)
{
/* If the specialization doesn't specify visibility, use the
visibility from the template. */
tree tinfo = get_template_info (decl);
tree tinfo = get_template_info (template_decl);
tree args = TI_ARGS (tinfo);
tree attribs = (TREE_CODE (decl) == TYPE_DECL
? TYPE_ATTRIBUTES (TREE_TYPE (decl))

View File

@ -1,3 +1,8 @@
2017-02-13 Nathan Sidwell <nathan@acm.org>
PR c++/79296
* g++.dg/cpp0x/pr79296.C: New.
2017-02-13 Segher Boessenkool <segher@kernel.crashing.org>
* gcc.dg/tree-ssa/ssa-dom-cse-2.c: Do not xfail powerpc64*-*-*.

View File

@ -0,0 +1,18 @@
// { dg-require-effective-target lto }
// { dg-additional-options "-flto" }
// { dg-do compile { target c++11 } }
// PR 79296 ICE mangling local class of localized instantiation
struct X {
template <typename T> X (T const *) {
struct Z {};
}
};
void Baz ()
{
struct Y { } y;
0, X (&y);
}