Tested x86_64-pc-linux-gnu, applying to trunk.

-- 8< --

In r14-1659 I added a missing error for a Concepts TS feature that we were
failing to diagnose, but this PR requests a way to disable that error for
code written thinking it was valid.  Which seems reasonable, since it
doesn't require any work beyond that and is a plausible extension by itself.

While looking at this, I also noticed we were still not giving the
diagnostic in a few cases, and fixing that affected a few of our old
concepts testcases.

        PR c++/120917

gcc/ChangeLog:

        * doc/invoke.texi: Add -Wno-abbreviated-auto-in-template-arg.

gcc/c-family/ChangeLog:

        * c.opt: Add -Wno-abbreviated-auto-in-template-arg.
        * c.opt.urls: Regenerate.

gcc/cp/ChangeLog:

        * parser.cc (cp_parser_simple_type_specifier): Attach
        auto in targ in parameter to -Wabbreviated-auto-in-template-arg.
        (cp_parser_placeholder_type_specifier): Diagnose constrained auto in
        template arg.

gcc/testsuite/ChangeLog:

        * g++.dg/concepts/auto7a.C: Add diagnostic.
        * g++.dg/concepts/auto7b.C: New test.
        * g++.dg/concepts/auto7c.C: New test.
        * g++.dg/cpp1y/pr85076.C: Expect 'auto' error.
        * g++.dg/concepts/pr67249.C: Likewise.
        * g++.dg/cpp1y/lambda-generic-variadic.C: Likewise.
        * g++.dg/cpp2a/concepts-pr67210.C: Likewise.
        * g++.dg/concepts/pr67249a.C: New test.
        * g++.dg/cpp1y/lambda-generic-variadic-a.C: New test.
        * g++.dg/cpp2a/concepts-pr67210a.C: New test.
---
 gcc/doc/invoke.texi                            | 18 ++++++++++++++++++
 gcc/c-family/c.opt                             |  4 ++++
 gcc/cp/parser.cc                               | 12 +++++++++---
 gcc/testsuite/g++.dg/concepts/auto7a.C         |  1 +
 gcc/testsuite/g++.dg/concepts/auto7b.C         | 10 ++++++++++
 gcc/testsuite/g++.dg/concepts/auto7c.C         | 12 ++++++++++++
 gcc/testsuite/g++.dg/concepts/pr67249.C        |  2 +-
 gcc/testsuite/g++.dg/concepts/pr67249a.C       |  7 +++++++
 .../g++.dg/cpp1y/lambda-generic-variadic-a.C   | 15 +++++++++++++++
 .../g++.dg/cpp1y/lambda-generic-variadic.C     |  4 ++--
 gcc/testsuite/g++.dg/cpp1y/pr85076.C           |  2 +-
 gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C  |  2 +-
 gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C | 11 +++++++++++
 gcc/c-family/c.opt.urls                        |  3 +++
 14 files changed, 95 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/concepts/auto7b.C
 create mode 100644 gcc/testsuite/g++.dg/concepts/auto7c.C
 create mode 100644 gcc/testsuite/g++.dg/concepts/pr67249a.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic-a.C
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 7640e7d8867..74f5ee26042 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -3816,6 +3816,23 @@ Warn when a type with an ABI tag is used in a context 
that does not
 have that ABI tag.  See @ref{C++ Attributes} for more information
 about ABI tags.
 
+@opindex Wabbreviated-auto-in-template-arg
+@opindex Wno-abbreviated-auto-in-template-arg
+@item -Wno-abbreviated-auto-in-template-arg
+Disable the error for an @code{auto} placeholder type used within a
+template argument list to declare a C++20 abbreviated function
+template, e.g.
+
+@smallexample
+void f(S<auto>);
+@end smallexample
+
+This feature was proposed in the Concepts TS, but was not adopted into
+C++20; in the standard, a placeholder in a parameter declaration must
+appear as a decl-specifier.  The error can also be reduced to a
+warning by @option{-fpermissive} or
+@option{-Wno-error=abbreviated-auto-in-template-arg}.
+
 @opindex Wcomma-subscript
 @opindex Wno-comma-subscript
 @item -Wcomma-subscript @r{(C++ and Objective-C++ only)}
@@ -6443,6 +6460,7 @@ only by this flag, but it also downgrades some C and C++ 
diagnostics
 that have their own flag:
 
 @gccoptlist{
+-Wabbreviated-auto-in-template-arg @r{(C++ and Objective-C++ only)}
 -Wdeclaration-missing-parameter-type @r{(C and Objective-C only)}
 -Wimplicit-function-declaration @r{(C and Objective-C only)}
 -Wimplicit-int @r{(C and Objective-C only)}
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 8af466d1ed1..6a55e7118d1 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -397,6 +397,10 @@ Wassign-intercept
 ObjC ObjC++ Var(warn_assign_intercept) Warning
 Warn whenever an Objective-C assignment is being intercepted by the garbage 
collector.
 
+Wabbreviated-auto-in-template-arg
+C++ ObjC++ Warning Var(warn_abbev_auto_targ) Init(1)
+Diagnose a placeholder type in a template argument in a function parameter 
type.
+
 Wbad-function-cast
 C ObjC Var(warn_bad_function_cast) Warning
 Warn about casting functions to incompatible types.
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 44a78324c6e..239e6f9a556 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -21021,9 +21021,6 @@ cp_parser_simple_type_specifier (cp_parser* parser,
                         "only available with "
                         "%<-std=c++14%> or %<-std=gnu++14%>");
            }
-         else if (parser->in_template_argument_list_p)
-           error_at (token->location,
-                    "use of %<auto%> in template argument");
          else if (!flag_concepts)
            pedwarn (token->location, OPT_Wc__20_extensions,
                     "use of %<auto%> in parameter declaration "
@@ -21033,6 +21030,11 @@ cp_parser_simple_type_specifier (cp_parser* parser,
                     "use of %<auto%> in parameter declaration "
                     "only available with "
                     "%<-std=c++14%> or %<-std=gnu++14%>");
+
+         if (parser->in_template_argument_list_p)
+           permerror_opt (token->location,
+                          OPT_Wabbreviated_auto_in_template_arg,
+                          "use of %<auto%> in template argument");
        }
       else
        type = make_auto ();
@@ -21479,6 +21481,10 @@ cp_parser_placeholder_type_specifier (cp_parser 
*parser, location_t loc,
          error_at (loc, "cannot declare a parameter with %<decltype(auto)%>");
          return error_mark_node;
        }
+      if (parser->in_template_argument_list_p)
+       permerror_opt (placeholder->location,
+                      OPT_Wabbreviated_auto_in_template_arg,
+                      "use of %<auto%> in template argument");
       tree parm = build_constrained_parameter (con, proto, args);
       return synthesize_implicit_template_parm (parser, parm);
     }
diff --git a/gcc/testsuite/g++.dg/concepts/auto7a.C 
b/gcc/testsuite/g++.dg/concepts/auto7a.C
index 88868f45d1c..f36038d2fb4 100644
--- a/gcc/testsuite/g++.dg/concepts/auto7a.C
+++ b/gcc/testsuite/g++.dg/concepts/auto7a.C
@@ -2,6 +2,7 @@
 
 template <class T> struct A { };
 void f(A<auto> a) { }          // { dg-error "auto. in template argument" }
+// { dg-message "in parameter declaration" "" { target c++17_down } .-1 }
 int main()
 {
   f(A<int>());
diff --git a/gcc/testsuite/g++.dg/concepts/auto7b.C 
b/gcc/testsuite/g++.dg/concepts/auto7b.C
new file mode 100644
index 00000000000..874192c0385
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/auto7b.C
@@ -0,0 +1,10 @@
+// PR c++/120917
+// { dg-do compile { target c++14 } }
+// { dg-additional-options "-fconcepts -Wno-abbreviated-auto-in-template-arg" }
+
+template <class T> struct A { };
+void f(A<auto> a) { }
+int main()
+{
+  f(A<int>());
+}
diff --git a/gcc/testsuite/g++.dg/concepts/auto7c.C 
b/gcc/testsuite/g++.dg/concepts/auto7c.C
new file mode 100644
index 00000000000..5b16027e2b6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/auto7c.C
@@ -0,0 +1,12 @@
+// { dg-do compile { target c++17 } }
+// { dg-additional-options -fconcepts }
+
+template <class T>
+concept True = true;
+
+template <class T> struct A { };
+void f(A<True auto> a) { } // { dg-error "use of .auto. in template argument" }
+int main()
+{
+  f(A<int>());
+}
diff --git a/gcc/testsuite/g++.dg/concepts/pr67249.C 
b/gcc/testsuite/g++.dg/concepts/pr67249.C
index e0f8d5ade01..e97183d1b21 100644
--- a/gcc/testsuite/g++.dg/concepts/pr67249.C
+++ b/gcc/testsuite/g++.dg/concepts/pr67249.C
@@ -4,4 +4,4 @@
 template<class T> concept C1 = true;
 template<class A, class B> struct Pair {};
 // We used to test "Pair<auto, C1 >".
-void f(Pair<C1 auto, C1 auto>);
+void f(Pair<C1 auto, C1 auto>);        // { dg-error "auto" }
diff --git a/gcc/testsuite/g++.dg/concepts/pr67249a.C 
b/gcc/testsuite/g++.dg/concepts/pr67249a.C
new file mode 100644
index 00000000000..cb5d90ed361
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/pr67249a.C
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++17 } }
+// { dg-options "-fconcepts -Wno-abbreviated-auto-in-template-arg" }
+
+template<class T> concept C1 = true;
+template<class A, class B> struct Pair {};
+// We used to test "Pair<auto, C1 >".
+void f(Pair<C1 auto, C1 auto>);
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic-a.C 
b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic-a.C
new file mode 100644
index 00000000000..557ecb914ec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic-a.C
@@ -0,0 +1,15 @@
+// Basic generic lambda test
+// { dg-do run { target c++14 } }
+// { dg-additional-options -Wno-abbreviated-auto-in-template-arg }
+
+template <typename T, typename U> struct pair {};
+template <typename... T> struct tuple {};
+
+int main()
+{
+  auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); };
+  auto b = [] (auto, pair<pair<auto,auto>,auto>... v) { return sizeof... (v); 
};
+
+  a(1, pair<int, float>());
+  b(2, pair<pair<short,char>, double>(), pair<pair<float,long>, int>());
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C 
b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
index 6d2d250f393..971f58fea0b 100644
--- a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
@@ -6,8 +6,8 @@ template <typename... T> struct tuple {};
 
 int main()
 {
-  auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); };
-  auto b = [] (auto, pair<pair<auto,auto>,auto>... v) { return sizeof... (v); 
};
+  auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); }; // { dg-error 
"auto" }
+  auto b = [] (auto, pair<pair<auto,auto>,auto>... v) { return sizeof... (v); 
}; // { dg-error "auto" }
 
   a(1, pair<int, float>());
   b(2, pair<pair<short,char>, double>(), pair<pair<float,long>, int>());
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr85076.C 
b/gcc/testsuite/g++.dg/cpp1y/pr85076.C
index 6d54dea6c01..b68143b23f9 100644
--- a/gcc/testsuite/g++.dg/cpp1y/pr85076.C
+++ b/gcc/testsuite/g++.dg/cpp1y/pr85076.C
@@ -3,4 +3,4 @@
 
 template<typename> struct A*;  // { dg-error "expected unqualified-id before" }
 
-auto a = [](A<auto>) {};       // { dg-error "is not a template|has incomplete 
type" }
+auto a = [](A<auto>) {};       // { dg-error "is not a template|has incomplete 
type|auto" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C
index a31750eb495..baddc1cd465 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210.C
@@ -7,4 +7,4 @@ concept C = true;
 template <class T>
 struct A {};
 
-void f(A<C<int> auto >) {} 
+void f(A<C<int> auto >) {}     // { dg-error "auto" }
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C 
b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C
new file mode 100644
index 00000000000..1d63a844aa4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-pr67210a.C
@@ -0,0 +1,11 @@
+// PR c++/67210
+// { dg-do compile { target c++20 } }
+// { dg-additional-options -Wno-abbreviated-auto-in-template-arg }
+
+template <class T, class U>
+concept C = true;
+
+template <class T>
+struct A {};
+
+void f(A<C<int> auto >) {} 
diff --git a/gcc/c-family/c.opt.urls b/gcc/c-family/c.opt.urls
index 65d1221c4ad..401e6e74138 100644
--- a/gcc/c-family/c.opt.urls
+++ b/gcc/c-family/c.opt.urls
@@ -139,6 +139,9 @@ UrlSuffix(gcc/Warning-Options.html#index-Warray-parameter)
 Wassign-intercept
 
UrlSuffix(gcc/Objective-C-and-Objective-C_002b_002b-Dialect-Options.html#index-Wassign-intercept)
 
+Wabbreviated-auto-in-template-arg
+UrlSuffix(gcc/C_002b_002b-Dialect-Options.html#index-Wabbreviated-auto-in-template-arg)
+
 Wbad-function-cast
 UrlSuffix(gcc/Warning-Options.html#index-Wbad-function-cast)
 

base-commit: 0c73f2f1f92c135f50dcc2ab76d5e53236262a4e
-- 
2.49.0

Reply via email to