aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2024-12-22 01:18:16 +1100
committerNathaniel Shead <nathanieloshead@gmail.com>2024-12-29 11:15:43 +1100
commitce81cd2eac686dc0f1c91ada0000c779add550b0 (patch)
tree29de382344de7f1cc27e887021890447de000fc5 /gcc
parent65c8fd7b017482c6d6bd0c7a7c6e296f016e38d0 (diff)
downloadgcc-ce81cd2eac686dc0f1c91ada0000c779add550b0.zip
gcc-ce81cd2eac686dc0f1c91ada0000c779add550b0.tar.gz
gcc-ce81cd2eac686dc0f1c91ada0000c779add550b0.tar.bz2
c++: Don't treat lambda typedef as lambda declaration [PR106221]
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 <nathanieloshead@gmail.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.cc8
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/lambda-uneval19.C20
2 files changed, 24 insertions, 4 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 7fa2866..0ffa0b5 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 0000000..a9682cc
--- /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>;