Commit b00e9be0 by Alexandre Oliva Committed by Alexandre Oliva

[PR87768] reset location wrapper suppression when reentering top level

Concepts-checking and other kinds of early tsubsting may often take
place while location wrappers are suppressed, e.g. because we've
triggered template instantiation within template parameter lists.

With that, exprs that are usually wrapped by VIEW_CONVERT_EXPRs
location wrappers may end up wrapped by NON_LVALUE_EXPRs that are not
marked as location wrappers.  If such NON_LVALUE_EXPRs tsubsted exprs
undergo another round of tsubsting, say for constraint checking, or
even for another round of specialization, they will be rejected by
tsubst_copy_and_build.

This patch arranges for suppress_location_wrappers to be saved and
reset when pushing to the top level, and restored when popping from
it.


for  gcc/cp/ChangeLog

	PR c++/87768
	* cp-tree.h (saved_scope): Add suppress_location_wrappers.
	* name-lookup.c (do_push_to_top_level): Save and reset it.
	(do_pop_from_top_level): Restore it.

for  gcc/testsuite/ChangeLog

	PR c++/87768
	* g++.dg/concepts/pr87768.C: New.

From-SVN: r268006
parent 33f746e5
2019-01-17 Alexandre Oliva <aoliva@redhat.com> 2019-01-17 Alexandre Oliva <aoliva@redhat.com>
PR c++/87768
* cp-tree.h (saved_scope): Add suppress_location_wrappers.
* name-lookup.c (do_push_to_top_level): Save and reset it.
(do_pop_from_top_level): Restore it.
PR c++/86648 PR c++/86648
* pt.c (make_template_placeholder): Use auto_identifier. * pt.c (make_template_placeholder): Use auto_identifier.
(is_auto): Drop CLASS_PLACEHOLDER_TEMPLATE test. (is_auto): Drop CLASS_PLACEHOLDER_TEMPLATE test.
......
...@@ -1626,6 +1626,7 @@ struct GTY(()) saved_scope { ...@@ -1626,6 +1626,7 @@ struct GTY(()) saved_scope {
int x_processing_template_decl; int x_processing_template_decl;
int x_processing_specialization; int x_processing_specialization;
int suppress_location_wrappers;
BOOL_BITFIELD x_processing_explicit_instantiation : 1; BOOL_BITFIELD x_processing_explicit_instantiation : 1;
BOOL_BITFIELD need_pop_function_context : 1; BOOL_BITFIELD need_pop_function_context : 1;
......
...@@ -7133,6 +7133,7 @@ do_push_to_top_level (void) ...@@ -7133,6 +7133,7 @@ do_push_to_top_level (void)
s->function_decl = current_function_decl; s->function_decl = current_function_decl;
s->unevaluated_operand = cp_unevaluated_operand; s->unevaluated_operand = cp_unevaluated_operand;
s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; s->inhibit_evaluation_warnings = c_inhibit_evaluation_warnings;
s->suppress_location_wrappers = suppress_location_wrappers;
s->x_stmt_tree.stmts_are_full_exprs_p = true; s->x_stmt_tree.stmts_are_full_exprs_p = true;
scope_chain = s; scope_chain = s;
...@@ -7143,6 +7144,7 @@ do_push_to_top_level (void) ...@@ -7143,6 +7144,7 @@ do_push_to_top_level (void)
push_class_stack (); push_class_stack ();
cp_unevaluated_operand = 0; cp_unevaluated_operand = 0;
c_inhibit_evaluation_warnings = 0; c_inhibit_evaluation_warnings = 0;
suppress_location_wrappers = 0;
} }
static void static void
...@@ -7175,6 +7177,7 @@ do_pop_from_top_level (void) ...@@ -7175,6 +7177,7 @@ do_pop_from_top_level (void)
current_function_decl = s->function_decl; current_function_decl = s->function_decl;
cp_unevaluated_operand = s->unevaluated_operand; cp_unevaluated_operand = s->unevaluated_operand;
c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings; c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
suppress_location_wrappers = s->suppress_location_wrappers;
/* Make this saved_scope structure available for reuse by /* Make this saved_scope structure available for reuse by
push_to_top_level. */ push_to_top_level. */
......
2019-01-17 Alexandre Oliva <aoliva@redhat.com> 2019-01-17 Alexandre Oliva <aoliva@redhat.com>
PR c++/87768
* g++.dg/concepts/pr87768.C: New.
PR c++/86648 PR c++/86648
* gcc.dg/cpp1z/pr86648.C: New. * gcc.dg/cpp1z/pr86648.C: New.
......
// { dg-do compile { target c++17 } }
// { dg-options "-fconcepts" }
struct a {};
template <bool> using b = a;
template <typename> struct c;
template <typename d>
requires requires(d e) { e[0]; }
struct c<d> {
static constexpr bool f = [] { return false; }();
};
struct g : b<c<unsigned[]>::f> {};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment