On 12/21/24 7:11 PM, Nathaniel Shead wrote:
Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

OK.

-- >8 --

I noticed that in a couple of places we sometimes treat any TYPE_DECL of
lambda type as defining a lambda, which isn't always true since C++20:
in `using T = decltype([]{})`, T is not a lambda-declaration.

        PR c++/106221
        PR c++/110680

gcc/cp/ChangeLog:

        * pt.cc (check_default_tmpl_args): Check this is actually a
        lambda declaration and not just a typedef.
        (push_template_decl): Likewise.

gcc/testsuite/ChangeLog:

        * g++.dg/cpp2a/lambda-uneval19.C: New test.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
  gcc/cp/pt.cc                                 |  8 ++++----
  gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C | 20 ++++++++++++++++++++
  2 files changed, 24 insertions(+), 4 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 7fa286698ef..0ffa0b53e26 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -5637,8 +5637,7 @@ check_default_tmpl_args (tree decl, tree parms, bool 
is_primary,
         local scope.  */
      return true;
- if ((TREE_CODE (decl) == TYPE_DECL
-       && TREE_TYPE (decl)
+  if ((DECL_IMPLICIT_TYPEDEF_P (decl)
         && LAMBDA_TYPE_P (TREE_TYPE (decl)))
        || (TREE_CODE (decl) == FUNCTION_DECL
          && LAMBDA_FUNCTION_P (decl)))
@@ -5924,7 +5923,7 @@ push_template_decl (tree decl, bool is_friend)
           template <typename T> friend void A<T>::f();
         is not primary.  */
      ;
-  else if (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (TREE_TYPE (decl)))
+  else if (DECL_IMPLICIT_TYPEDEF_P (decl) && LAMBDA_TYPE_P (TREE_TYPE (decl)))
      /* Lambdas are not primary.  */
      ;
    else
@@ -6077,7 +6076,8 @@ push_template_decl (tree decl, bool is_friend)
    else if (!ctx
           || TREE_CODE (ctx) == FUNCTION_DECL
           || (CLASS_TYPE_P (ctx) && TYPE_BEING_DEFINED (ctx))
-          || (TREE_CODE (decl) == TYPE_DECL && LAMBDA_TYPE_P (TREE_TYPE 
(decl)))
+          || (DECL_IMPLICIT_TYPEDEF_P (decl)
+              && LAMBDA_TYPE_P (TREE_TYPE (decl)))
           || (is_friend && !(DECL_LANG_SPECIFIC (decl)
                              && DECL_TEMPLATE_INFO (decl))))
      {
diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C 
b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C
new file mode 100644
index 00000000000..a9682cce6e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C
@@ -0,0 +1,20 @@
+// { dg-do compile { target c++20 } }
+
+// PR c++/106221
+using T = decltype([](){});
+
+template<typename Opts>
+using foo = T;
+
+using bar = foo<int>;
+
+// PR c++/110680
+template <auto X = []{}>
+struct S {
+  auto f() { return X; }
+};
+
+template <class T>
+using C = decltype(S().f());
+
+using D = C<int>;

Reply via email to