aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2018-05-21 19:25:50 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2018-05-21 19:25:50 +0000
commit18759120664263a56fa993f5501cbe674383c3ef (patch)
tree11692eed301ed0825ad27370dcef0b4ccf3c2482
parentb3229fe17f103d8f1a36f15ab2734361d660b0c8 (diff)
downloadgcc-18759120664263a56fa993f5501cbe674383c3ef.zip
gcc-18759120664263a56fa993f5501cbe674383c3ef.tar.gz
gcc-18759120664263a56fa993f5501cbe674383c3ef.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/parser.c73
-rw-r--r--gcc/testsuite/ChangeLog13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/cond1.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr84588-1.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr84588-2.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr84588-3.C25
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/decomp16.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/cond6.C16
-rw-r--r--gcc/testsuite/g++.dg/parse/cond7.C12
-rw-r--r--gcc/testsuite/g++.dg/parse/cond8.C10
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/cond.C5
12 files changed, 218 insertions, 15 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 29edd5f..db39e7b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,13 @@
+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.
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c005808..3f62191 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -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++)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9998e63..3a669d7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,16 @@
+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
diff --git a/gcc/testsuite/g++.dg/cpp0x/cond1.C b/gcc/testsuite/g++.dg/cpp0x/cond1.C
new file mode 100644
index 0000000..cdfdd9a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/cond1.C
@@ -0,0 +1,17 @@
+// 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" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr84588-1.C b/gcc/testsuite/g++.dg/cpp1y/pr84588-1.C
new file mode 100644
index 0000000..35f3256
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr84588-1.C
@@ -0,0 +1,25 @@
+// { 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" }
+ ;
+ }) {}
+};
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr84588-2.C b/gcc/testsuite/g++.dg/cpp1y/pr84588-2.C
new file mode 100644
index 0000000..402ac29
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr84588-2.C
@@ -0,0 +1,25 @@
+// { 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" }
+ ;
+ }) {}
+};
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr84588-3.C b/gcc/testsuite/g++.dg/cpp1y/pr84588-3.C
new file mode 100644
index 0000000..477c3e3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr84588-3.C
@@ -0,0 +1,25 @@
+// { 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" }
+ ;
+ }) {}
+};
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp16.C b/gcc/testsuite/g++.dg/cpp1z/decomp16.C
index 7589c80..dad69b8 100644
--- a/gcc/testsuite/g++.dg/cpp1z/decomp16.C
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp16.C
@@ -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" }
;
diff --git a/gcc/testsuite/g++.dg/parse/cond6.C b/gcc/testsuite/g++.dg/parse/cond6.C
new file mode 100644
index 0000000..78d0337
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/cond6.C
@@ -0,0 +1,16 @@
+// 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" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/cond7.C b/gcc/testsuite/g++.dg/parse/cond7.C
new file mode 100644
index 0000000..45befe6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/cond7.C
@@ -0,0 +1,12 @@
+// PR c++/84588
+
+bool (foo()) { return 0; } // declaration
+
+void bar()
+{
+ if (bool (foo())); // expression
+
+ for (;bool (foo());); // expression
+
+ while (bool (foo())); // expression
+}
diff --git a/gcc/testsuite/g++.dg/parse/cond8.C b/gcc/testsuite/g++.dg/parse/cond8.C
new file mode 100644
index 0000000..40ba29d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/cond8.C
@@ -0,0 +1,10 @@
+// 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" }
+}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/cond.C b/gcc/testsuite/g++.old-deja/g++.jason/cond.C
index dfc21dd..f928709 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/cond.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/cond.C
@@ -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" }
;
}