diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-02-03 08:48:19 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-02-03 08:48:19 -0800 |
commit | 305e9d2c7815e90a29bbde1e3a7cd776861f4d7c (patch) | |
tree | 32dedad81f42b67729aef302069fcee11132d215 /gcc/cp | |
parent | 8910f1cd79445bbe2da01f8ccf7c37909349529e (diff) | |
parent | 530203d6e3244c25eda4124f0fa5756ca9a5683e (diff) | |
download | gcc-305e9d2c7815e90a29bbde1e3a7cd776861f4d7c.zip gcc-305e9d2c7815e90a29bbde1e3a7cd776861f4d7c.tar.gz gcc-305e9d2c7815e90a29bbde1e3a7cd776861f4d7c.tar.bz2 |
Merge from trunk revision 530203d6e3244c25eda4124f0fa5756ca9a5683e.
Diffstat (limited to 'gcc/cp')
-rw-r--r-- | gcc/cp/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/cp/parser.c | 13 | ||||
-rw-r--r-- | gcc/cp/pt.c | 16 | ||||
-rw-r--r-- | gcc/cp/tree.c | 3 |
4 files changed, 34 insertions, 5 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index bac41f1..de69476 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2021-02-02 Jason Merrill <jason@redhat.com> + + PR c++/98929 + PR c++/96199 + * error.c (dump_expr): Ignore dummy object. + * pt.c (tsubst_baselink): Handle dependent scope. + 2021-02-01 Patrick Palka <ppalka@redhat.com> PR c++/98295 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index abadaf9..5da8670 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -25026,8 +25026,8 @@ cp_parser_class_specifier_1 (cp_parser* parser) pushed_scope = push_scope (class_type); } - tree spec = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)); - spec = TREE_PURPOSE (spec); + tree def_parse = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (decl)); + def_parse = TREE_PURPOSE (def_parse); /* Make sure that any template parameters are in scope. */ maybe_begin_member_template_processing (decl); @@ -25044,7 +25044,7 @@ cp_parser_class_specifier_1 (cp_parser* parser) parser->local_variables_forbidden_p |= THIS_FORBIDDEN; /* Now we can parse the noexcept-specifier. */ - spec = cp_parser_late_noexcept_specifier (parser, spec); + tree spec = cp_parser_late_noexcept_specifier (parser, def_parse); if (spec == error_mark_node) spec = NULL_TREE; @@ -25052,6 +25052,12 @@ cp_parser_class_specifier_1 (cp_parser* parser) /* Update the fn's type directly -- it might have escaped beyond this decl :( */ fixup_deferred_exception_variants (TREE_TYPE (decl), spec); + /* Update any instantiations we've already created. We must + keep the new noexcept-specifier wrapped in a DEFERRED_NOEXCEPT + so that maybe_instantiate_noexcept can tsubst the NOEXCEPT_EXPR + in the pattern. */ + for (tree i : DEFPARSE_INSTANTIATIONS (def_parse)) + DEFERRED_NOEXCEPT_PATTERN (TREE_PURPOSE (i)) = TREE_PURPOSE (spec); /* Restore the state of local_variables_forbidden_p. */ parser->local_variables_forbidden_p = local_variables_forbidden_p; @@ -26695,6 +26701,7 @@ cp_parser_save_noexcept (cp_parser *parser) /* Save away the noexcept-specifier; we will process it when the class is complete. */ DEFPARSE_TOKENS (expr) = cp_token_cache_new (first, last); + DEFPARSE_INSTANTIATIONS (expr) = nullptr; expr = build_tree_list (expr, NULL_TREE); return expr; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index aa1687a..4781519 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -15189,6 +15189,22 @@ tsubst_exception_specification (tree fntype, /*integral_constant_expression_p=*/true); } new_specs = build_noexcept_spec (new_specs, complain); + /* We've instantiated a template before a noexcept-specifier + contained therein has been parsed. This can happen for + a nested template class: + + struct S { + template<typename> struct B { B() noexcept(...); }; + struct A : B<int> { ... use B() ... }; + }; + + where completing B<int> will trigger instantiating the + noexcept, even though we only parse it at the end of S. */ + if (UNPARSED_NOEXCEPT_SPEC_P (specs)) + { + gcc_checking_assert (defer_ok); + vec_safe_push (DEFPARSE_INSTANTIATIONS (expr), new_specs); + } } else if (specs) { diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 2e5a1f1..e6ced27 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -2738,8 +2738,7 @@ fixup_deferred_exception_variants (tree type, tree raises) tree original = TYPE_RAISES_EXCEPTIONS (type); tree cr = flag_noexcept_type ? canonical_eh_spec (raises) : NULL_TREE; - gcc_checking_assert (TREE_CODE (TREE_PURPOSE (original)) - == DEFERRED_PARSE); + gcc_checking_assert (UNPARSED_NOEXCEPT_SPEC_P (original)); /* Though sucky, this walk will process the canonical variants first. */ |