summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
authorRichard Trieu <rtrieu@google.com>2013-07-23 18:01:49 +0000
committerRichard Trieu <rtrieu@google.com>2013-07-23 18:01:49 +0000
commit79b45389c3cd2f1ab0904b636f8451849038cddf (patch)
treed5a8d314e7d002bf2bd9af5c6ab1c9287b7b9459 /clang/test
parent8c4245455ad4ad171387ec8dac33a28fa58da84b (diff)
downloadbcm5719-llvm-79b45389c3cd2f1ab0904b636f8451849038cddf.tar.gz
bcm5719-llvm-79b45389c3cd2f1ab0904b636f8451849038cddf.zip
Add new diagnostic messages when too many arguments are presented to a
function-like macro. Clang will attempt to correct the arguments by detecting braced initializer lists: 1) If possible, suggest parentheses around arguments containing braced lists which will give the proper number of arguments. 2) If a braced list is detected at the start of a macro argument, it cannot be corrected by parentheses. Instead, just point out the location of these braced lists. llvm-svn: 186971
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Preprocessor/macro_fn.c5
-rw-r--r--clang/test/Preprocessor/macro_with_initializer_list.cpp182
2 files changed, 185 insertions, 2 deletions
diff --git a/clang/test/Preprocessor/macro_fn.c b/clang/test/Preprocessor/macro_fn.c
index fcdb90ad57d..f21ef5197d4 100644
--- a/clang/test/Preprocessor/macro_fn.c
+++ b/clang/test/Preprocessor/macro_fn.c
@@ -13,7 +13,8 @@ zero(1, 2, 3); /* expected-error {{too many arguments provided to function-li
one() /* ok */
one(a)
-one(a,) /* expected-error {{too many arguments provided to function-like macro invocation}} */
+one(a,) /* expected-error {{too many arguments provided to function-like macro invocation}} \
+ expected-warning {{empty macro arguments are a C99 feature}}*/
one(a, b) /* expected-error {{too many arguments provided to function-like macro invocation}} */
two() /* expected-error {{too few arguments provided to function-like macro invocation}} */
@@ -25,7 +26,7 @@ two(
, /* expected-warning {{empty macro arguments are a C99 feature}} */
, /* expected-warning {{empty macro arguments are a C99 feature}} \
expected-error {{too many arguments provided to function-like macro invocation}} */
- )
+ ) /* expected-warning {{empty macro arguments are a C99 feature}} */
two(,) /* expected-warning 2 {{empty macro arguments are a C99 feature}} */
diff --git a/clang/test/Preprocessor/macro_with_initializer_list.cpp b/clang/test/Preprocessor/macro_with_initializer_list.cpp
new file mode 100644
index 00000000000..4f5bf6d1db7
--- /dev/null
+++ b/clang/test/Preprocessor/macro_with_initializer_list.cpp
@@ -0,0 +1,182 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+namespace std {
+ template <class X>
+ class initializer_list {
+ public:
+ initializer_list();
+ };
+}
+
+class Foo {
+public:
+ Foo();
+ Foo(std::initializer_list<int>);
+ bool operator==(const Foo);
+ Foo operator+(const Foo);
+};
+
+#define EQ(x,y) (void)(x == y) // expected-note 6{{defined here}}
+void test_EQ() {
+ Foo F;
+ F = Foo{1,2};
+
+ EQ(F,F);
+ EQ(F,Foo());
+ EQ(F,Foo({1,2,3}));
+ EQ(Foo({1,2,3}),F);
+ EQ((Foo{1,2,3}),(Foo{1,2,3}));
+ EQ(F, F + F);
+ EQ(F, Foo({1,2,3}) + Foo({1,2,3}));
+ EQ(F, (Foo{1,2,3} + Foo{1,2,3}));
+
+ EQ(F,Foo{1,2,3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ EQ(Foo{1,2,3},F);
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ EQ(Foo{1,2,3},Foo{1,2,3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+
+ EQ(Foo{1,2,3} + Foo{1,2,3}, F);
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ EQ(F, Foo({1,2,3}) + Foo{1,2,3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ EQ(F, Foo{1,2,3} + Foo{1,2,3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+}
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{33:8-33:8}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{33:18-33:18}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{36:6-36:6}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{36:16-36:16}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{39:6-39:6}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{39:16-39:16}:")"
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{39:17-39:17}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{39:27-39:27}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{43:6-43:6}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{43:29-43:29}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{46:9-46:9}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{46:34-46:34}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{49:9-49:9}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{49:32-49:32}:")"
+
+#define NE(x,y) (void)(x != y) // expected-note 6{{defined here}}
+// Operator != isn't defined. This tests that the corrected macro arguments
+// are used in the macro expansion.
+void test_NE() {
+ Foo F;
+
+ NE(F,F);
+ // expected-error@-1 {{invalid operands}}
+ NE(F,Foo());
+ // expected-error@-1 {{invalid operands}}
+ NE(F,Foo({1,2,3}));
+ // expected-error@-1 {{invalid operands}}
+ NE((Foo{1,2,3}),(Foo{1,2,3}));
+ // expected-error@-1 {{invalid operands}}
+
+ NE(F,Foo{1,2,3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ // expected-error@-3 {{invalid operands}}
+ NE(Foo{1,2,3},F);
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ // expected-error@-3 {{invalid operands}}
+ NE(Foo{1,2,3},Foo{1,2,3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ // expected-error@-3 {{invalid operands}}
+
+ NE(Foo{1,2,3} + Foo{1,2,3}, F);
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ // expected-error@-3 {{invalid operands}}
+ NE(F, Foo({1,2,3}) + Foo{1,2,3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ // expected-error@-3 {{invalid operands}}
+ NE(F, Foo{1,2,3} + Foo{1,2,3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+ // expected-error@-3 {{invalid operands}}
+}
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{89:8-89:8}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{89:18-89:18}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{93:6-93:6}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{93:16-93:16}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{97:6-97:6}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{97:16-97:16}:")"
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{97:17-97:17}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{97:27-97:27}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{102:6-102:6}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{102:29-102:29}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{106:9-106:9}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{106:34-106:34}:")"
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:9-110:9}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{110:32-110:32}:")"
+
+#define INIT(var, init) Foo var = init; // expected-note 3{{defined here}}
+// Can't use an initializer list as a macro argument. The commas in the list
+// will be interpretted as argument separaters and adding parenthesis will
+// make it no longer an initializer list.
+void test() {
+ INIT(a, Foo());
+ INIT(b, Foo({1, 2, 3}));
+ INIT(c, Foo());
+
+ INIT(d, Foo{1, 2, 3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-note@-2 {{parentheses are required}}
+
+ // Can't be fixed by parentheses.
+ INIT(e, {1, 2, 3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-error@-2 {{use of undeclared identifier}}
+ // expected-note@-3 {{cannot use initializer list at the beginning of an macro argument}}
+
+ // Can't be fixed by parentheses.
+ INIT(e, {1, 2, 3} + {1, 2, 3});
+ // expected-error@-1 {{too many arguments provided}}
+ // expected-error@-2 {{use of undeclared identifier}}
+ // expected-note@-3 {{cannot use initializer list at the beginning of an macro argument}}
+}
+
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:11-145:11}:"("
+// CHECK: fix-it:"{{.*}}macro_with_initializer_list.cpp":{145:23-145:23}:")"
+
+#define M(name,a,b,c,d,e,f,g,h,i,j,k,l) \
+ Foo name = a + b + c + d + e + f + g + h + i + j + k + l;
+// expected-note@-2 2{{defined here}}
+void test2() {
+ M(F1, Foo(), Foo(), Foo(), Foo(), Foo(), Foo(),
+ Foo(), Foo(), Foo(), Foo(), Foo(), Foo());
+
+ M(F2, Foo{1,2,3}, Foo{1,2,3}, Foo{1,2,3}, Foo{1,2,3}, Foo{1,2,3}, Foo{1,2,3},
+ Foo{1,2,3}, Foo{1,2,3}, Foo{1,2,3}, Foo{1,2,3}, Foo{1,2,3}, Foo{1,2,3});
+ // expected-error@-2 {{too many arguments provided}}
+ // expected-note@-3 {{parentheses are required}}
+
+ M(F3, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3},
+ {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3}, {1,2,3});
+ // expected-error@-2 {{too many arguments provided}}
+ // expected-error@-3 {{use of undeclared identifier}}
+ // expected-note@-4 {{cannot use initializer list at the beginning of an macro argument}}
+}
OpenPOWER on IntegriCloud