diff options
author | nathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4> | 2017-04-27 13:56:35 +0300 |
---|---|---|
committer | Dongkyun Son <dongkyun.s@samsung.com> | 2017-06-08 00:10:25 +0000 |
commit | 14e9820ddef8026797810979ba66e32696c058cc (patch) | |
tree | 287b7878a8f482313360568e4a833362f5a3992e | |
parent | d0fd3198b9b5e12a93160958427bc17ef0d2fa69 (diff) | |
download | linaro-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.c | 41 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/pr79296.C | 18 |
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); +} |