diff options
author | Nathan Sidwell <nathan@acm.org> | 2017-01-23 20:19:07 +0000 |
---|---|---|
committer | Nathan Sidwell <nathan@gcc.gnu.org> | 2017-01-23 20:19:07 +0000 |
commit | e6b8075ccec830041e8c85fc50d9eee6364263f7 (patch) | |
tree | 6d185076c63ade495449e9ba441bf6257db63d2c /gcc | |
parent | 15b8fd499dd07627a78253ab722cc9049d86d68a (diff) | |
download | gcc-e6b8075ccec830041e8c85fc50d9eee6364263f7.zip gcc-e6b8075ccec830041e8c85fc50d9eee6364263f7.tar.gz gcc-e6b8075ccec830041e8c85fc50d9eee6364263f7.tar.bz2 |
PR c++/71406 - ICE with scope-ref'd template id exprs
PR c++/71406 - ICE with scope-ref'd template id exprs
PR c++/77508
* typeck.c (finish_class_member_access_expr): Break up SCOPE_REF
before breaking up TEMPLATE_ID_EXPR.
PR c++/71406
PR c++/77508
* g++.dg/template/pr71406.C: New.
From-SVN: r244832
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 35 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/pr71406.C | 28 |
4 files changed, 59 insertions, 17 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d1ad2eb..c56c840 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2017-01-23 Nathan Sidwell <nathan@acm.org> + + PR c++/71406 - ICE with scope-ref'd template id exprs + PR c++/77508 + * typeck.c (finish_class_member_access_expr): Break up SCOPE_REF + before breaking up TEMPLATE_ID_EXPR. + 2017-01-20 Nathan Sidwell <nathan@acm.org> PR c++/78495 - wrong code inherited ctor and invisi-ref parm diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 579c580..f677b48 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2730,19 +2730,9 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, { bool is_template_id = false; tree template_args = NULL_TREE; - tree scope; + tree scope = NULL_TREE; - if (TREE_CODE (name) == TEMPLATE_ID_EXPR) - { - is_template_id = true; - template_args = TREE_OPERAND (name, 1); - name = TREE_OPERAND (name, 0); - - if (TREE_CODE (name) == OVERLOAD) - name = DECL_NAME (get_first_fn (name)); - else if (DECL_P (name)) - name = DECL_NAME (name); - } + access_path = object_type; if (TREE_CODE (name) == SCOPE_REF) { @@ -2761,9 +2751,25 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, scope, name, object_type); return error_mark_node; } + } + + if (TREE_CODE (name) == TEMPLATE_ID_EXPR) + { + is_template_id = true; + template_args = TREE_OPERAND (name, 1); + name = TREE_OPERAND (name, 0); + + if (TREE_CODE (name) == OVERLOAD) + name = DECL_NAME (get_first_fn (name)); + else if (DECL_P (name)) + name = DECL_NAME (name); + } + if (scope) + { if (TREE_CODE (scope) == ENUMERAL_TYPE) { + gcc_assert (!is_template_id); /* Looking up a member enumerator (c++/56793). */ if (!TYPE_CLASS_SCOPE_P (scope) || !DERIVED_FROM_P (TYPE_CONTEXT (scope), object_type)) @@ -2812,11 +2818,6 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p, return error_mark_node; } } - else - { - scope = NULL_TREE; - access_path = object_type; - } if (TREE_CODE (name) == BIT_NOT_EXPR) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 10c34cc..f3ac5e5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-01-23 Nathan Sidwell <nathan@acm.org> + + PR c++/71406 + PR c++/77508 + * g++.dg/template/pr71406.C: New. + 2017-01-23 Thomas Koenig <tkoenig@netcologne.de> * gfortran.dg/integer_exponentiation_7.f90: New test. diff --git a/gcc/testsuite/g++.dg/template/pr71406.C b/gcc/testsuite/g++.dg/template/pr71406.C new file mode 100644 index 0000000..3629d7a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr71406.C @@ -0,0 +1,28 @@ +// { dg-do compile } +// PR c++/71406 ICE with X::template Name + +template < typename T > +struct C : T +{ + void foo () { this->C::template bar <>; } +}; + +template < typename T > +struct A +{ + template < void (T::*Fn) () > void f () {} +}; + +template < typename T > struct B : A < B < T > > +{ + void g () + { + this->B::template f < &B < T >::g > (); + } +}; + +void Foo () +{ + B < int > b; + b.g (); +} |