[gcc(refs/vendors/ibm/heads/gcc-9-branch)] c++: Avoid ICE with dependent attribute on type.

Peter Bergner bergner@gcc.gnu.org
Fri Sep 4 19:07:13 GMT 2020


https://gcc.gnu.org/g:aa988998be8f85334665a6b049d5d9139408c250

commit aa988998be8f85334665a6b049d5d9139408c250
Author: Jason Merrill <jason@redhat.com>
Date:   Mon Jan 27 05:45:01 2020 -0500

    c++: Avoid ICE with dependent attribute on type.
    
    We previously happened to accept this testcase, but never actually did
    anything useful with the attribute.  The patch for PR86379 stopped using
    TREE_TYPE as USING_DECL_SCOPE, so 'using A::b' no longer had TREE_TYPE set,
    so the language-independent decl_attributes started crashing on it.
    
    GNU attributes are more flexible in their placement than C++11 attributes,
    so if we encounter a dependent GNU attribute that syntactically appertains
    to a type rather than the declaration as a whole, move it to the
    declaration; that's almost certainly what the user meant, anyway.
    
    gcc/cp/ChangeLog
    2020-01-27  Jason Merrill  <jason@redhat.com>
    
            PR c++/90750
            PR c++/79585
            * decl.c (grokdeclarator): Move dependent attribute to decl.
            * decl2.c (splice_template_attributes): No longer static.

Diff:
---
 gcc/cp/ChangeLog                           |  7 +++++++
 gcc/cp/cp-tree.h                           |  1 +
 gcc/cp/decl.c                              |  4 ++++
 gcc/cp/decl2.c                             |  2 +-
 gcc/testsuite/g++.dg/ext/attr-type1.C      | 19 +++++++++++++++++++
 gcc/testsuite/g++.dg/warn/Wunused-var-26.C |  4 ++--
 6 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index f8070a55055..fe53cc0c0bd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2020-04-27  Jason Merrill  <jason@redhat.com>
+
+	PR c++/90750
+	PR c++/79585
+	* decl.c (grokdeclarator): Move dependent attribute to decl.
+	* decl2.c (splice_template_attributes): No longer static.
+
 2020-04-21  Martin Sebor  <msebor@redhat.com>
 	    Jason Merrill  <jason@redhat.com>
 
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0e0efd749bc..1f013c172ce 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6492,6 +6492,7 @@ extern tree grokfield (const cp_declarator *, cp_decl_specifier_seq *,
 		       tree, bool, tree, tree);
 extern tree grokbitfield (const cp_declarator *, cp_decl_specifier_seq *,
 			  tree, tree, tree);
+extern tree splice_template_attributes		(tree *, tree);
 extern bool any_dependent_type_attributes_p	(tree);
 extern tree cp_reconstruct_complex_type		(tree, tree);
 extern bool attributes_naming_typedef_ok	(tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 04d0b38ddf0..79f61dfe064 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11259,9 +11259,13 @@ grokdeclarator (const cp_declarator *declarator,
 	    attr_flags |= (int) ATTR_FLAG_FUNCTION_NEXT;
 	  if (declarator->kind == cdk_array)
 	    attr_flags |= (int) ATTR_FLAG_ARRAY_NEXT;
+	  /* Assume that any attributes that get applied late to templates will
+	     DTRT when applied to the declaration as a whole.  */
+	  tree late_attrs = splice_template_attributes (&attrs, type);
 	  returned_attrs = decl_attributes (&type,
 					    chainon (returned_attrs, attrs),
 					    attr_flags);
+	  returned_attrs = chainon (late_attrs, returned_attrs);
 	}
 
       inner_declarator = declarator->declarator;
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index a46cbce08f4..a15bb3c45cc 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -1208,7 +1208,7 @@ is_late_template_attribute (tree attr, tree decl)
    the declaration itself is dependent, so all attributes should be applied
    at instantiation time.  */
 
-static tree
+tree
 splice_template_attributes (tree *attr_p, tree decl)
 {
   tree *p = attr_p;
diff --git a/gcc/testsuite/g++.dg/ext/attr-type1.C b/gcc/testsuite/g++.dg/ext/attr-type1.C
new file mode 100644
index 00000000000..6e84cccea1f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attr-type1.C
@@ -0,0 +1,19 @@
+// PR c++/90750
+// { dg-do compile { target c++11 } }
+
+template <typename> struct S
+{
+  static const int b = 64;
+};
+
+template <typename a> struct T: S<a>
+{
+  using A = S<a>;
+  using A::b;
+  char* __attribute__((aligned(b))) c;
+};
+
+T<int> t;
+
+#define SA(X) static_assert (X,#X)
+SA (alignof(T<int>) == S<int>::b);
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-26.C b/gcc/testsuite/g++.dg/warn/Wunused-var-26.C
index b3e020b6007..89c53de88a4 100644
--- a/gcc/testsuite/g++.dg/warn/Wunused-var-26.C
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-26.C
@@ -47,10 +47,10 @@ template <class T>
 void f_var_type_unused ()
 {
   // The variable's type is marked unused.
-  T* UNUSED t = new T;   // { dg-bogus "unused variable" "bug 79585" { xfail *-*-* } }
+  T* UNUSED t = new T;   // { dg-bogus "unused variable" "bug 79585" }
 
   typedef T U;
-  U* UNUSED u = new U;   // { dg-bogus "unused variable" "bug 79585" { xfail *-*-* } }
+  U* UNUSED u = new U;   // { dg-bogus "unused variable" "bug 79585" }
 
   typedef T UNUSED U;
   U v = U ();   // { dg-bogus "unused variable" "bug 79585" }


More information about the Gcc-cvs mailing list