Commit 18759120 by Paolo Carlini Committed by Paolo Carlini

re PR c++/84588 (internal compiler error: Segmentation fault (contains_struct_check()))

/cp
2018-05-21  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/84588
	* parser.c (cp_parser_maybe_commit_to_declaration,
	cp_parser_check_condition_declarator): New.
	(cp_parser_simple_declaration): Use the first above.
	(cp_parser_condition): Use both the above; enforce
	[stmt.stmt]/2 about the declarator not specifying
	a function or an array; improve error-recovery.

/testsuite
2018-05-21  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/84588
	* g++.dg/cpp0x/cond1.C: New.
	* g++.dg/cpp1y/pr84588-1.C: Likewise.
	* g++.dg/cpp1y/pr84588-2.C: Likewise.
	* g++.dg/cpp1y/pr84588-3.C: Likewise.
	* g++.dg/parse/cond6.C: Likewise.
	* g++.dg/parse/cond7.C: Likewise.
	* g++.dg/parse/cond8.C: Likewise.
	* g++.dg/cpp1z/decomp16.C: Update.
	* g++.old-deja/g++.jason/cond.C: Likewise.

From-SVN: r260482
parent b3229fe1
2018-05-21 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/84588
* parser.c (cp_parser_maybe_commit_to_declaration,
cp_parser_check_condition_declarator): New.
(cp_parser_simple_declaration): Use the first above.
(cp_parser_condition): Use both the above; enforce
[stmt.stmt]/2 about the declarator not specifying
a function or an array; improve error-recovery.
2018-05-20 Jason Merrill <jason@redhat.com>
PR libstdc++/85843 - warning in logic_error copy constructor.
......
......@@ -11527,6 +11527,49 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
}
}
/* Helper function for cp_parser_condition and cp_parser_simple_declaration.
If we have seen at least one decl-specifier, and the next token
is not a parenthesis, then we must be looking at a declaration.
(After "int (" we might be looking at a functional cast.) */
static void
cp_parser_maybe_commit_to_declaration (cp_parser* parser,
bool any_specifiers_p)
{
if (any_specifiers_p
&& cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
&& !cp_parser_error_occurred (parser))
cp_parser_commit_to_tentative_parse (parser);
}
/* Helper function for cp_parser_condition. Enforces [stmt.stmt]/2:
The declarator shall not specify a function or an array. Returns
TRUE if the declarator is valid, FALSE otherwise. */
static bool
cp_parser_check_condition_declarator (cp_parser* parser,
cp_declarator *declarator,
location_t loc)
{
if (function_declarator_p (declarator)
|| declarator->kind == cdk_array)
{
if (declarator->kind == cdk_array)
error_at (loc, "condition declares an array");
else
error_at (loc, "condition declares a function");
if (parser->fully_implicit_function_template_p)
abort_fully_implicit_template (parser);
cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
/*or_comma=*/false,
/*consume_paren=*/false);
return false;
}
else
return true;
}
/* Parse a condition.
condition:
......@@ -11563,6 +11606,10 @@ cp_parser_condition (cp_parser* parser)
&declares_class_or_enum);
/* Restore the saved message. */
parser->type_definition_forbidden_message = saved_message;
cp_parser_maybe_commit_to_declaration (parser,
type_specifiers.any_specifiers_p);
/* If all is well, we might be looking at a declaration. */
if (!cp_parser_error_occurred (parser))
{
......@@ -11571,6 +11618,7 @@ cp_parser_condition (cp_parser* parser)
tree attributes;
cp_declarator *declarator;
tree initializer = NULL_TREE;
location_t loc = cp_lexer_peek_token (parser->lexer)->location;
/* Parse the declarator. */
declarator = cp_parser_declarator (parser, CP_PARSER_DECLARATOR_NAMED,
......@@ -11601,6 +11649,9 @@ cp_parser_condition (cp_parser* parser)
bool non_constant_p;
int flags = LOOKUP_ONLYCONVERTING;
if (!cp_parser_check_condition_declarator (parser, declarator, loc))
return error_mark_node;
/* Create the declaration. */
decl = start_decl (declarator, &type_specifiers,
/*initialized_p=*/true,
......@@ -11614,11 +11665,17 @@ cp_parser_condition (cp_parser* parser)
CONSTRUCTOR_IS_DIRECT_INIT (initializer) = 1;
flags = 0;
}
else
else if (cp_lexer_next_token_is (parser->lexer, CPP_EQ))
{
/* Consume the `='. */
cp_parser_require (parser, CPP_EQ, RT_EQ);
initializer = cp_parser_initializer_clause (parser, &non_constant_p);
cp_lexer_consume_token (parser->lexer);
initializer = cp_parser_initializer_clause (parser,
&non_constant_p);
}
else
{
cp_parser_error (parser, "expected initializer");
initializer = error_mark_node;
}
if (BRACE_ENCLOSED_INITIALIZER_P (initializer))
maybe_warn_cpp0x (CPP0X_INITIALIZER_LISTS);
......@@ -12936,14 +12993,8 @@ cp_parser_simple_declaration (cp_parser* parser,
goto done;
}
/* If we have seen at least one decl-specifier, and the next token
is not a parenthesis, then we must be looking at a declaration.
(After "int (" we might be looking at a functional cast.) */
if (decl_specifiers.any_specifiers_p
&& cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_PAREN)
&& cp_lexer_next_token_is_not (parser->lexer, CPP_OPEN_BRACE)
&& !cp_parser_error_occurred (parser))
cp_parser_commit_to_tentative_parse (parser);
cp_parser_maybe_commit_to_declaration (parser,
decl_specifiers.any_specifiers_p);
/* Look for C++17 decomposition declaration. */
for (size_t n = 1; ; n++)
2018-05-21 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/84588
* g++.dg/cpp0x/cond1.C: New.
* g++.dg/cpp1y/pr84588-1.C: Likewise.
* g++.dg/cpp1y/pr84588-2.C: Likewise.
* g++.dg/cpp1y/pr84588-3.C: Likewise.
* g++.dg/parse/cond6.C: Likewise.
* g++.dg/parse/cond7.C: Likewise.
* g++.dg/parse/cond8.C: Likewise.
* g++.dg/cpp1z/decomp16.C: Update.
* g++.old-deja/g++.jason/cond.C: Likewise.
2018-05-21 Steven G. Kargl <kargl@gcc.gnu.org>
ChangeLog for r260480
......
// PR c++/84588
// { dg-do compile { target c++11 } }
void foo()
{
if (int bar() {}); // { dg-error "condition declares a function" }
for (;int bar() {};); // { dg-error "condition declares a function" }
while (int bar() {}); // { dg-error "condition declares a function" }
if (int a[] {}); // { dg-error "condition declares an array" }
for (;int a[] {};); // { dg-error "condition declares an array" }
while (int a[] {}); // { dg-error "condition declares an array" }
}
// { dg-do compile { target c++14 } }
struct a {
void b() {}
void c(void (*) () = [] {
if (a a(int auto) {}) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
struct d {
void e() {}
void f(void (*) () = [] {
for (;d d(int auto) {};) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
struct g {
void h() {}
void i(void (*) () = [] {
while (g g(int auto) {}) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
// { dg-do compile { target c++14 } }
struct a {
void b() {}
void c(void (*) () = [] {
if (a a(int auto)) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
struct d {
void e() {}
void f(void (*) () = [] {
for (;d d(int auto);) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
struct g {
void h() {}
void i(void (*) () = [] {
while (g g(int auto)) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
// { dg-do compile { target c++14 } }
struct a {
void b() {}
void c(void (*) () = [] {
if (a a(int auto)JUNK) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
struct d {
void e() {}
void f(void (*) () = [] {
for (;d d(int auto)JUNK;) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
struct g {
void h() {}
void i(void (*) () = [] {
while (g g(int auto)JUNK) // { dg-error "two or more data types|condition declares a function" }
;
}) {}
};
......@@ -8,7 +8,7 @@ void
foo ()
{
auto [ a, b ] = A ();
for (; auto [ a, b ] = A (); ) // { dg-error "expected" }
for (; auto [ a, b ] = A (); ) // { dg-error "expected|no match" }
;
for (; false; auto [ a, b ] = A ()) // { dg-error "expected" }
;
......
// PR c++/84588
void foo()
{
if (int bar()); // { dg-error "condition declares a function" }
for (;int bar();); // { dg-error "condition declares a function" }
while (int bar()); // { dg-error "condition declares a function" }
if (int a[]); // { dg-error "condition declares an array" }
for (;int a[];); // { dg-error "condition declares an array" }
while (int a[]); // { dg-error "condition declares an array" }
}
// PR c++/84588
bool (foo()) { return 0; } // declaration
void bar()
{
if (bool (foo())); // expression
for (;bool (foo());); // expression
while (bool (foo())); // expression
}
// PR c++/84588
void foo()
{
if (int x); // { dg-error "expected initializer" }
for (;int x;); // { dg-error "expected initializer" }
while (int x); // { dg-error "expected initializer" }
}
......@@ -47,11 +47,10 @@ int main()
if (struct B * foo = new B)
;
if (int f () = 1) // { dg-warning "extern" "extern" }
// { dg-error "is initialized like a variable" "var" { target *-*-* } .-1 }
if (int f () = 1) // { dg-error "declares a function" }
;
if (int a[2] = {1, 2}) // { dg-error "extended init" "" { target { ! c++11 } } }
if (int a[2] = {1, 2}) // { dg-error "declares an array" }
;
}
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