It doesn't make sense to use an 'auto' parameter type outside of an implicit template declaration; conveniently, default_arg_ok_p already tracks whether we are in a suitable context.
As Jakub points out in the PR, this extension really shouldn't be silently accepted, given that it still isn't part of the standard working paper even now, after much of the Concepts TS was merged in. So the second patch makes the pedwarn unconditional, and moves affected testcases into the concepts directory. Tested x86_64-pc-linux-gnu, applying to trunk.
commit 2bfb31f29c5ff65d16d549a8ced8f3312b19513e Author: Jason Merrill <ja...@redhat.com> Date: Tue Mar 13 00:37:40 2018 -0400 PR c++/84798 - ICE with auto in abstract function declarator. * parser.c (cp_parser_parameter_declaration_clause): Check parser->default_arg_ok_p. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index cdc62388973..8e8ebceb0d5 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -21198,7 +21198,10 @@ cp_parser_parameter_declaration_clause (cp_parser* parser) if (!processing_specialization && !processing_template_parmlist - && !processing_explicit_instantiation) + && !processing_explicit_instantiation + /* default_arg_ok_p tracks whether this is a parameter-clause for an + actual function or a random abstract declarator. */ + && parser->default_arg_ok_p) if (!current_function_decl || (current_class_type && LAMBDA_TYPE_P (current_class_type))) parser->auto_is_implicit_function_template_parm_p = true; diff --git a/gcc/testsuite/g++.dg/cpp0x/auto51.C b/gcc/testsuite/g++.dg/cpp0x/auto51.C new file mode 100644 index 00000000000..dfb08336b53 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto51.C @@ -0,0 +1,9 @@ +// PR c++/84798 +// { dg-do compile { target c++11 } } + +template<typename T> +struct S { + static constexpr T value = 0; +}; + +constexpr auto x = S<void(*)(auto)>::value; // { dg-error "auto" } diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60393.C b/gcc/testsuite/g++.dg/cpp1y/pr60393.C index 27fe2b72296..2ae21ed1147 100644 --- a/gcc/testsuite/g++.dg/cpp1y/pr60393.C +++ b/gcc/testsuite/g++.dg/cpp1y/pr60393.C @@ -1,8 +1,7 @@ // PR c++/60393 // { dg-do compile { target c++14 } } -// { dg-options "" } -void (*f)(auto) + 0; // { dg-error "expected" } +void (*f)(auto) + 0; // { dg-error "auto|expected" } struct A {
commit 9da596356fed08bbbaf190ff1d70fdf7e76bd47a Author: Jason Merrill <ja...@redhat.com> Date: Tue Mar 13 09:57:08 2018 -0400 Pedwarn about auto parameter even without -Wpedantic. * parser.c (cp_parser_simple_type_specifier): Pedwarn about auto parameter even without -Wpedantic. diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 8e8ebceb0d5..0a82f415196 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -17049,9 +17049,9 @@ cp_parser_simple_type_specifier (cp_parser* parser, "only available with " "-std=c++14 or -std=gnu++14"); else if (!flag_concepts) - pedwarn (token->location, OPT_Wpedantic, - "ISO C++ forbids use of %<auto%> in parameter " - "declaration"); + pedwarn (token->location, 0, + "use of %<auto%> in parameter declaration " + "only available with -fconcepts"); } else type = make_auto (); diff --git a/gcc/testsuite/g++.dg/cpp1z/abbrev1.C b/gcc/testsuite/g++.dg/concepts/abbrev1.C similarity index 70% rename from gcc/testsuite/g++.dg/cpp1z/abbrev1.C rename to gcc/testsuite/g++.dg/concepts/abbrev1.C +++ b/gcc/testsuite/g++.dg/concepts/abbrev1.C @@ -1,5 +1,6 @@ // PR c++/64969 -// { dg-options "-std=c++17" } +// { dg-do compile { target c++14 } } +// { dg-additional-options "-fconcepts" } auto f1(auto x) { return *x; } decltype(auto) f2(auto x) { return *x; } diff --git a/gcc/testsuite/g++.dg/cpp1z/abbrev2.C b/gcc/testsuite/g++.dg/concepts/abbrev2.C similarity index 79% rename from gcc/testsuite/g++.dg/cpp1z/abbrev2.C rename to gcc/testsuite/g++.dg/concepts/abbrev2.C +++ b/gcc/testsuite/g++.dg/concepts/abbrev2.C @@ -1,6 +1,6 @@ // PR c++/66197 -// { dg-do run } -// { dg-options "-std=c++17" } +// { dg-do run { target c++14 } } +// { dg-additional-options "-fconcepts" } extern "C" void abort(); diff --git a/gcc/testsuite/g++.dg/cpp1y/fn-generic-member-ool.C b/gcc/testsuite/g++.dg/concepts/fn-generic-member-ool.C similarity index 93% rename from gcc/testsuite/g++.dg/cpp1y/fn-generic-member-ool.C rename to gcc/testsuite/g++.dg/concepts/fn-generic-member-ool.C +++ b/gcc/testsuite/g++.dg/concepts/fn-generic-member-ool.C @@ -1,6 +1,6 @@ // Out-of-line generic member function definitions. // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } struct A { void f(auto x); diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58500.C b/gcc/testsuite/g++.dg/concepts/pr58500.C similarity index 69% rename from gcc/testsuite/g++.dg/cpp1y/pr58500.C rename to gcc/testsuite/g++.dg/concepts/pr58500.C +++ b/gcc/testsuite/g++.dg/concepts/pr58500.C @@ -1,6 +1,6 @@ // PR c++/58500 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } struct A {}; diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58534.C b/gcc/testsuite/g++.dg/concepts/pr58534.C similarity index 79% rename from gcc/testsuite/g++.dg/cpp1y/pr58534.C rename to gcc/testsuite/g++.dg/concepts/pr58534.C +++ b/gcc/testsuite/g++.dg/concepts/pr58534.C @@ -1,6 +1,6 @@ // PR c++/58534 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } template<typename> void foo(const auto&) {} diff --git a/gcc/testsuite/g++.dg/concepts/pr58535.C b/gcc/testsuite/g++.dg/concepts/pr58535.C new file mode 100644 index 00000000000..3e212a0ffd7 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/pr58535.C @@ -0,0 +1,7 @@ +// PR c++/58535 +// { dg-do compile { target c++14 } } + +struct A +{ + virtual void foo(auto); // { dg-error "auto|templates" } +}; diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58536.C b/gcc/testsuite/g++.dg/concepts/pr58536.C similarity index 69% rename from gcc/testsuite/g++.dg/cpp1y/pr58536.C rename to gcc/testsuite/g++.dg/concepts/pr58536.C +++ b/gcc/testsuite/g++.dg/concepts/pr58536.C @@ -1,6 +1,6 @@ // PR c++/58536 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } struct A { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58548.C b/gcc/testsuite/g++.dg/concepts/pr58548.C similarity index 69% rename from gcc/testsuite/g++.dg/cpp1y/pr58548.C rename to gcc/testsuite/g++.dg/concepts/pr58548.C +++ b/gcc/testsuite/g++.dg/concepts/pr58548.C @@ -1,6 +1,6 @@ // PR c++/58548 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } void foo(auto) { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58549.C b/gcc/testsuite/g++.dg/concepts/pr58549.C similarity index 67% rename from gcc/testsuite/g++.dg/cpp1y/pr58549.C rename to gcc/testsuite/g++.dg/concepts/pr58549.C +++ b/gcc/testsuite/g++.dg/concepts/pr58549.C @@ -1,6 +1,6 @@ // PR c++/58549 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } void foo(auto) { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60052.C b/gcc/testsuite/g++.dg/concepts/pr60052.C similarity index 77% rename from gcc/testsuite/g++.dg/cpp1y/pr60052.C rename to gcc/testsuite/g++.dg/concepts/pr60052.C +++ b/gcc/testsuite/g++.dg/concepts/pr60052.C @@ -1,6 +1,6 @@ // PR c++/60052 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } struct A { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60053.C b/gcc/testsuite/g++.dg/concepts/pr60053.C similarity index 81% rename from gcc/testsuite/g++.dg/cpp1y/pr60053.C rename to gcc/testsuite/g++.dg/concepts/pr60053.C +++ b/gcc/testsuite/g++.dg/concepts/pr60053.C @@ -1,6 +1,6 @@ // PR c++/60053 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } struct A { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60064.C b/gcc/testsuite/g++.dg/concepts/pr60064.C similarity index 82% rename from gcc/testsuite/g++.dg/cpp1y/pr60064.C rename to gcc/testsuite/g++.dg/concepts/pr60064.C +++ b/gcc/testsuite/g++.dg/concepts/pr60064.C @@ -1,6 +1,6 @@ // PR c++/60064 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } class A { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60065.C b/gcc/testsuite/g++.dg/concepts/pr60065.C similarity index 85% rename from gcc/testsuite/g++.dg/cpp1y/pr60065.C rename to gcc/testsuite/g++.dg/concepts/pr60065.C +++ b/gcc/testsuite/g++.dg/concepts/pr60065.C @@ -1,6 +1,6 @@ // PR c++/60065 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } template <int> void foo(auto... x); template <typename> void foo2(auto... x); diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60377.C b/gcc/testsuite/g++.dg/concepts/pr60377.C similarity index 50% rename from gcc/testsuite/g++.dg/cpp1y/pr60377.C rename to gcc/testsuite/g++.dg/concepts/pr60377.C +++ b/gcc/testsuite/g++.dg/concepts/pr60377.C @@ -1,8 +1,7 @@ // PR c++/60377 // { dg-do compile { target c++14 } } -// { dg-options "" } -void foo(auto, void (f*)()); // { dg-error "expected" } +void foo(auto, void (f*)()); // { dg-error "auto|expected" } struct A { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60390.C b/gcc/testsuite/g++.dg/concepts/pr60390.C similarity index 84% rename from gcc/testsuite/g++.dg/cpp1y/pr60390.C rename to gcc/testsuite/g++.dg/concepts/pr60390.C +++ b/gcc/testsuite/g++.dg/concepts/pr60390.C @@ -1,6 +1,6 @@ // PR c++/60390 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } struct A { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60391.C b/gcc/testsuite/g++.dg/concepts/pr60391.C similarity index 53% rename from gcc/testsuite/g++.dg/cpp1y/pr60391.C rename to gcc/testsuite/g++.dg/concepts/pr60391.C +++ b/gcc/testsuite/g++.dg/concepts/pr60391.C @@ -1,10 +1,9 @@ // PR c++/60391 // { dg-do compile { target c++14 } } -// { dg-options "" } namespace N { - int operator"" _X(auto) {} // { dg-error "invalid" } + int operator"" _X(auto) {} // { dg-error "auto|invalid" } } namespace N {} diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60573.C b/gcc/testsuite/g++.dg/concepts/pr60573.C similarity index 90% rename from gcc/testsuite/g++.dg/cpp1y/pr60573.C rename to gcc/testsuite/g++.dg/concepts/pr60573.C +++ b/gcc/testsuite/g++.dg/concepts/pr60573.C @@ -1,6 +1,6 @@ // PR c++/60573 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } struct A { diff --git a/gcc/testsuite/g++.dg/cpp1y/pr80471.C b/gcc/testsuite/g++.dg/concepts/pr80471.C similarity index 92% rename from gcc/testsuite/g++.dg/cpp1y/pr80471.C rename to gcc/testsuite/g++.dg/concepts/pr80471.C +++ b/gcc/testsuite/g++.dg/concepts/pr80471.C @@ -1,6 +1,6 @@ // PR c++/80471 // { dg-do compile { target c++14 } } -// { dg-options "" } +// { dg-additional-options "-fconcepts" } template <class, class> constexpr bool is_same = false; diff --git a/gcc/testsuite/g++.dg/cpp0x/auto-60626.C b/gcc/testsuite/g++.dg/cpp0x/auto-60626.C new file mode 100644 index 00000000000..35671924ea9 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/auto-60626.C @@ -0,0 +1,6 @@ +// PR c++/60626 +// { dg-do compile { target c++14 } } + +struct A {}; + +void (*A::p)(auto) = 0; // { dg-error "auto|static data member|template" } diff --git a/gcc/testsuite/g++.dg/cpp1y/pr84662.C b/gcc/testsuite/g++.dg/cpp0x/auto-84662.C similarity index 57% rename from gcc/testsuite/g++.dg/cpp1y/pr84662.C rename to gcc/testsuite/g++.dg/cpp0x/auto-84662.C +++ b/gcc/testsuite/g++.dg/cpp0x/auto-84662.C @@ -1,6 +1,5 @@ // PR c++/84662 // { dg-do compile { target c++14 } } -// { dg-options "" } double b; -a (__attribute__((c (0 && int() - ([] {} && b) || auto)))); // { dg-error "expected constructor, destructor, or type conversion before" } +a (__attribute__((c (0 && int() - ([] {} && b) || auto)))); // { dg-error "auto|expected constructor, destructor, or type conversion before" } diff --git a/gcc/testsuite/g++.dg/cpp1y/pr58535.C b/gcc/testsuite/g++.dg/cpp1y/pr58535.C deleted file mode 100644 index b36be8f4a45..00000000000 --- a/gcc/testsuite/g++.dg/cpp1y/pr58535.C +++ /dev/null @@ -1,8 +0,0 @@ -// PR c++/58535 -// { dg-do compile { target c++14 } } -// { dg-options "" } - -struct A -{ - virtual void foo(auto); // { dg-error "templates" } -}; diff --git a/gcc/testsuite/g++.dg/cpp1y/pr60626.C b/gcc/testsuite/g++.dg/cpp1y/pr60626.C deleted file mode 100644 index 311464472da..00000000000 --- a/gcc/testsuite/g++.dg/cpp1y/pr60626.C +++ /dev/null @@ -1,7 +0,0 @@ -// PR c++/60626 -// { dg-do compile { target c++14 } } -// { dg-options "" } - -struct A {}; - -void (*A::p)(auto) = 0; // { dg-error "static data member|template" } diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp3.C b/gcc/testsuite/g++.dg/cpp1z/decomp3.C index 529f3732fd5..1886cdbe90d 100644 --- a/gcc/testsuite/g++.dg/cpp1z/decomp3.C +++ b/gcc/testsuite/g++.dg/cpp1z/decomp3.C @@ -43,7 +43,7 @@ test (A &b, B c) void test2 (auto & [ p ] = bar ()) // { dg-error "'p' was not declared in this scope" } -{ +{ // { dg-warning "auto" "" { target { ! concepts } } .-1 } } int arr[4];