From 9fd377a747375a82912bd81c67b275301489785c Mon Sep 17 00:00:00 2001
From: Jakub Jelinek <jakub@redhat.com>
Date: Wed, 6 Apr 2022 17:53:41 +0200
Subject: [PATCH] c++: Fix up ICE when cplus_decl_attributes is called with
 error_mark_node attributes [PR104668]

cplus_decl_attributes can be called with attributes equal to
error_mark_node, there are some spots in the function that test
it or decl_attributes it calls starts with:
  if (TREE_TYPE (*node) == error_mark_node || attributes == error_mark_node)
    return NULL_TREE;
But the recent PR104245 change broke this when processing_template_decl
is true.

The patch returns early for attributes error_mark_node from
cplus_decl_attributes.

2022-04-06  Jakub Jelinek  <jakub@redhat.com>

	PR c++/104668
	* decl2.cc (splice_template_attributes): Return NULL if *p is
	error_mark_node.
	(cplus_decl_attributes): Return early if attributes is
	error_mark_node.  Don't check that later.

	* g++.dg/cpp0x/pr104668.C: New test.
---
 gcc/cp/decl2.cc                       |  6 +++---
 gcc/testsuite/g++.dg/cpp0x/pr104668.C | 13 +++++++++++++
 2 files changed, 16 insertions(+), 3 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/pr104668.C

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index c53acf4546dd..dc2c924c4728 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -1336,7 +1336,7 @@ splice_template_attributes (tree *attr_p, tree decl)
   tree late_attrs = NULL_TREE;
   tree *q = &late_attrs;
 
-  if (!p)
+  if (!p || *p == error_mark_node)
     return NULL_TREE;
 
   for (; *p; )
@@ -1631,7 +1631,7 @@ void
 cplus_decl_attributes (tree *decl, tree attributes, int flags)
 {
   if (*decl == NULL_TREE || *decl == void_type_node
-      || *decl == error_mark_node)
+      || *decl == error_mark_node || attributes == error_mark_node)
     return;
 
   /* Add implicit "omp declare target" attribute if requested.  */
@@ -1668,7 +1668,7 @@ cplus_decl_attributes (tree *decl, tree attributes, int flags)
 
   cp_check_const_attributes (attributes);
 
-  if ((flag_openmp || flag_openmp_simd) && attributes != error_mark_node)
+  if (flag_openmp || flag_openmp_simd)
     {
       bool diagnosed = false;
       for (tree *pa = &attributes; *pa; )
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr104668.C b/gcc/testsuite/g++.dg/cpp0x/pr104668.C
new file mode 100644
index 000000000000..c3ad33dd40b1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr104668.C
@@ -0,0 +1,13 @@
+// PR c++/104668
+// { dg-do compile { target c++11 } }
+// { dg-excess-errors "" }
+
+template <class... Ts>
+void sink(Ts...);
+template <class... Ts>
+void f(Ts...) {
+  sink([] { struct alignas:Ts) S {}; }...); }
+}
+int main() {
+  f(0);
+}
-- 
GitLab