diff mbox

[C++] Fix handling of C++11 attributes (PR c++/67767)

Message ID 20160218171956.GS3017@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Feb. 18, 2016, 5:19 p.m. UTC
Hi!

While this likely isn't a regression, it looks severe enough that IMHO we
should fix this even in stage4 - apparently cp_parser_std_attribute_spec_seq
can drop some of the attributes on the floor, by blindly assuming that
there is just a single attribute inside of [[ ]], but there could be many,
and the list is already in the right order (chained and nreversed at the
end).  So, we need to chainon the sequences, but either that would be
quadratic, or we'd need to nreverse each chain again, then chainon and then
nreverse again.  So IMHO remembering instead also the last chain element
and chaining that way is cleanest and cheapest.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-02-18  Jakub Jelinek  <jakub@redhat.com>

	PR c++/67767
	* parser.c (cp_parser_std_attribute_spec_seq): Don't assume
	attr_spec is always single element chain, chain all the attributes
	properly together in the right order.

	* g++.dg/cpp0x/pr67767.C: New test.


	Jakub

Comments

Jason Merrill Feb. 19, 2016, 3:43 p.m. UTC | #1
OK.

Jason
diff mbox

Patch

--- gcc/cp/parser.c.jj	2016-02-17 23:26:00.000000000 +0100
+++ gcc/cp/parser.c	2016-02-18 09:48:52.896766040 +0100
@@ -24104,7 +24104,8 @@  cp_parser_std_attribute_spec (cp_parser
 static tree
 cp_parser_std_attribute_spec_seq (cp_parser *parser)
 {
-  tree attr_specs = NULL;
+  tree attr_specs = NULL_TREE;
+  tree attr_last = NULL_TREE;
 
   while (true)
     {
@@ -24114,11 +24115,13 @@  cp_parser_std_attribute_spec_seq (cp_par
       if (attr_spec == error_mark_node)
 	return error_mark_node;
 
-      TREE_CHAIN (attr_spec) = attr_specs;
-      attr_specs = attr_spec;
+      if (attr_last)
+	TREE_CHAIN (attr_last) = attr_spec;
+      else
+	attr_specs = attr_last = attr_spec;
+      attr_last = tree_last (attr_last);
     }
 
-  attr_specs = nreverse (attr_specs);
   return attr_specs;
 }
 
--- gcc/testsuite/g++.dg/cpp0x/pr67767.C.jj	2016-02-18 09:53:12.808187281 +0100
+++ gcc/testsuite/g++.dg/cpp0x/pr67767.C	2016-02-18 09:53:39.311822349 +0100
@@ -0,0 +1,10 @@ 
+// PR c++/67767
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wsuggest-attribute=noreturn" }
+
+void foo [[gnu::cold, gnu::noreturn]] ();
+
+void foo ()	// { dg-bogus "function might be candidate for attribute" }
+{
+  throw 1;
+}