aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2021-09-30 17:29:18 -0400
committerPatrick Palka <ppalka@redhat.com>2021-09-30 17:29:18 -0400
commitfdf8d5bc5b52bd733037dbeeff442c59f8aa765b (patch)
tree26dff04852cb7edbd68a32f66f496807a003146a /gcc
parentb6bca2e631b54f992c058ca8e445b45e9816690b (diff)
downloadgcc-fdf8d5bc5b52bd733037dbeeff442c59f8aa765b.zip
gcc-fdf8d5bc5b52bd733037dbeeff442c59f8aa765b.tar.gz
gcc-fdf8d5bc5b52bd733037dbeeff442c59f8aa765b.tar.bz2
c++: argument order in a variadic type trait intrinsic
When parsing a variadic type trait intrinsic, we build up the list of trailing arguments in reverse, but we neglect to reverse the list to the true order afterwards. This causes us to confuse the meaning of e.g. __is_xible(x, y, z) vs __is_xible(x, z, y). Note that this bug doesn't affect the library traits because they pass a pack expansion as the single trailing argument to __is_xible, which gets expanded in the correct order by tsubst_tree_list. gcc/cp/ChangeLog: * parser.c (cp_parser_trait_expr): Call nreverse on the reversed list of trailing arguments. gcc/testsuite/ChangeLog: * g++.dg/ext/is_constructible6.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/parser.c1
-rw-r--r--gcc/testsuite/g++.dg/ext/is_constructible6.C10
2 files changed, 11 insertions, 0 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 8430445..04f5a24 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10832,6 +10832,7 @@ cp_parser_trait_expr (cp_parser* parser, enum rid keyword)
return error_mark_node;
type2 = tree_cons (NULL_TREE, elt, type2);
}
+ type2 = nreverse (type2);
}
location_t finish_loc = cp_lexer_peek_token (parser->lexer)->location;
diff --git a/gcc/testsuite/g++.dg/ext/is_constructible6.C b/gcc/testsuite/g++.dg/ext/is_constructible6.C
new file mode 100644
index 0000000..7fce153
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/is_constructible6.C
@@ -0,0 +1,10 @@
+// Verify we respect the order of trailing arguments passed to
+// __is_constructible.
+
+struct A { };
+struct B { };
+struct C { C(A, B); };
+
+extern int n[true];
+extern int n[ __is_constructible(C, A, B)];
+extern int n[!__is_constructible(C, B, A)];