summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>2017-04-27 13:56:35 +0300
committerDongkyun Son <dongkyun.s@samsung.com>2017-06-08 00:10:25 +0000
commit14e9820ddef8026797810979ba66e32696c058cc (patch)
tree287b7878a8f482313360568e4a833362f5a3992e
parentd0fd3198b9b5e12a93160958427bc17ef0d2fa69 (diff)
downloadlinaro-gcc-14e9820ddef8026797810979ba66e32696c058cc.tar.gz
linaro-gcc-14e9820ddef8026797810979ba66e32696c058cc.tar.bz2
linaro-gcc-14e9820ddef8026797810979ba66e32696c058cc.zip
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. Change-Id: I51b9ba39a48a97a8836976baf5f598ede9ba695a git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@245398 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/decl2.c41
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr79296.C18
2 files changed, 39 insertions, 20 deletions
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index c4a0e854228..a9511dece51 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -2280,11 +2280,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. */
@@ -2296,25 +2291,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
@@ -2357,8 +2355,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)
@@ -2388,7 +2389,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))
@@ -2405,11 +2406,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))
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr79296.C b/gcc/testsuite/g++.dg/cpp0x/pr79296.C
new file mode 100644
index 00000000000..1ee982c71f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr79296.C
@@ -0,0 +1,18 @@
+// { dg-do compile { target c++11 } }
+// { dg-require-effective-target lto }
+// { dg-additional-options "-flto" }
+
+// 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);
+}