diff options
Diffstat (limited to 'test/Preprocessor')
114 files changed, 1549 insertions, 0 deletions
diff --git a/test/Preprocessor/_Pragma-dependency.c b/test/Preprocessor/_Pragma-dependency.c new file mode 100644 index 0000000..da1d87f --- /dev/null +++ b/test/Preprocessor/_Pragma-dependency.c @@ -0,0 +1,7 @@ +// RUN: clang-cc %s -E 2>&1 | grep 'DO_PRAGMA (STR' && +// RUN: clang-cc %s -E 2>&1 | grep '7:3' + +#define DO_PRAGMA _Pragma +#define STR "GCC dependency \"parse.y\"") + // Test that this line is printed by caret diagnostics. + DO_PRAGMA (STR diff --git a/test/Preprocessor/_Pragma-location.c b/test/Preprocessor/_Pragma-location.c new file mode 100644 index 0000000..61cadfb --- /dev/null +++ b/test/Preprocessor/_Pragma-location.c @@ -0,0 +1,4 @@ +// RUN: clang-cc %s -E | not grep 'scratch space' + +#define push _Pragma ("pack(push)") +push diff --git a/test/Preprocessor/_Pragma-physloc.c b/test/Preprocessor/_Pragma-physloc.c new file mode 100644 index 0000000..8737949 --- /dev/null +++ b/test/Preprocessor/_Pragma-physloc.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -E | grep '#pragma x y z' && +// RUN: clang-cc %s -E | grep '#pragma a b c' + +_Pragma("x y z") +_Pragma("a b c") + diff --git a/test/Preprocessor/_Pragma-syshdr2.c b/test/Preprocessor/_Pragma-syshdr2.c new file mode 100644 index 0000000..de7f2d3 --- /dev/null +++ b/test/Preprocessor/_Pragma-syshdr2.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -E %s 2>&1 | grep 'file not found' + +#define DO_PRAGMA _Pragma +DO_PRAGMA ("GCC dependency \"blahblabh\"") + diff --git a/test/Preprocessor/_Pragma.c b/test/Preprocessor/_Pragma.c new file mode 100644 index 0000000..9c0c97d --- /dev/null +++ b/test/Preprocessor/_Pragma.c @@ -0,0 +1,10 @@ +// RUN: clang-cc %s -verify -Wall + +_Pragma ("GCC system_header") // expected-warning {{system_header ignored in main file}} + +// rdar://6880630 +_Pragma("#define macro") // expected-warning {{unknown pragma ignored}} + +#ifdef macro +#error #define invalid +#endif diff --git a/test/Preprocessor/assembler-with-cpp.c b/test/Preprocessor/assembler-with-cpp.c new file mode 100644 index 0000000..2e84ed1 --- /dev/null +++ b/test/Preprocessor/assembler-with-cpp.c @@ -0,0 +1,77 @@ +// RUN: clang-cc -x assembler-with-cpp -fdollars-in-identifiers=0 -E %s > %t && + +#ifndef __ASSEMBLER__ +#error "__ASSEMBLER__ not defined" +#endif + + +// Invalid token pasting is ok. +// RUN: grep '1: X .' %t && +#define A X ## . +1: A + +// Line markers are not linemarkers in .S files, they are passed through. +// RUN: grep '# 321' %t && +# 321 + +// Unknown directives are passed through. +// RUN: grep '# B C' %t && +# B C + +// Unknown directives are expanded. +// RUN: grep '# BAR42' %t && +#define D(x) BAR ## x +# D(42) + +// Unmatched quotes are permitted. +// RUN: grep "2: '" %t && +// RUN: grep '3: "' %t && +2: ' +3: " + +// (balance quotes to keep editors happy): "' + +// Empty char literals are ok. +// RUN: grep "4: ''" %t && +4: '' + + +// Portions of invalid pasting should still expand as macros. +// rdar://6709206 +// RUN: grep "5: expanded (" %t && +#define M4 expanded +#define M5() M4 ## ( + +5: M5() + +// rdar://6804322 +// RUN: grep -F "6: blarg $foo" %t && +#define FOO(name) name ## $foo +6: FOO(blarg) + +// RUN: clang-cc -x assembler-with-cpp -fdollars-in-identifiers=1 -E %s > %t && +// RUN: grep -F "7: blarg$foo" %t && +#define FOO(name) name ## $foo +7: FOO(blarg) + + +// +#define T6() T6 #nostring +#define T7(x) T7 #x +8: T6() +9: T7(foo) +// RUN: grep '8: T6 #nostring' %t && +// RUN: grep '9: T7 "foo"' %t && + +// Concatenation with period doesn't leave a space +// RUN: grep -F '10: .T8' %t && +#define T8(A,B) A ## B +10: T8(.,T8) + + +// This should not crash. +// RUN: grep '11: #0' %t && +#define T11(a) #0 +11: T11(b) + +// RUN: true diff --git a/test/Preprocessor/builtin_line.c b/test/Preprocessor/builtin_line.c new file mode 100644 index 0000000..db01e47 --- /dev/null +++ b/test/Preprocessor/builtin_line.c @@ -0,0 +1,13 @@ +// RUN: clang-cc %s -E | grep "^ 4" && +#define FOO __LINE__ + + FOO + +// PR3579 - This should expand to the __LINE__ of the ')' not of the X. +// RUN: clang-cc %s -E | grep "^A 13" + +#define X() __LINE__ + +A X( + +) diff --git a/test/Preprocessor/c90.c b/test/Preprocessor/c90.c new file mode 100644 index 0000000..ed63d1b --- /dev/null +++ b/test/Preprocessor/c90.c @@ -0,0 +1,10 @@ +/* RUN: clang-cc %s -std=c89 -Eonly -verify -pedantic-errors + */ + +/* PR3919 */ + +#define foo`bar /* expected-error {{whitespace required after macro name}} */ +#define foo2!bar /* expected-warning {{whitespace recommended after macro name}} */ + +#define foo3$bar /* expected-error {{'$' in identifier}} */ + diff --git a/test/Preprocessor/c99-6_10_3_3_p4.c b/test/Preprocessor/c99-6_10_3_3_p4.c new file mode 100644 index 0000000..8966054 --- /dev/null +++ b/test/Preprocessor/c99-6_10_3_3_p4.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -E %s | grep -F 'char p[] = "x ## y";' +#define hash_hash # ## # +#define mkstr(a) # a +#define in_between(a) mkstr(a) +#define join(c, d) in_between(c hash_hash d) +char p[] = join(x, y); diff --git a/test/Preprocessor/c99-6_10_3_4_p5.c b/test/Preprocessor/c99-6_10_3_4_p5.c new file mode 100644 index 0000000..22bdf82 --- /dev/null +++ b/test/Preprocessor/c99-6_10_3_4_p5.c @@ -0,0 +1,29 @@ +// Example from C99 6.10.3.4p5 + +// RUN: clang-cc -E %s | grep -F 'f(2 * (y+1)) + f(2 * (f(2 * (z[0])))) % f(2 * (0)) + t(1);' && +// RUN: clang-cc -E %s | grep -F 'f(2 * (2 +(3,4)-0,1)) | f(2 * (~ 5)) & f(2 * (0,1))^m(0,1);' && +// RUN: clang-cc -E %s | grep -F 'int i[] = { 1, 23, 4, 5, };' && +// RUN: clang-cc -E %s | grep -F 'char c[2][6] = { "hello", "" };' + + +#define x 3 +#define f(a) f(x * (a)) +#undef x +#define x 2 +#define g f +#define z z[0] +#define h g(~ +#define m(a) a(w) +#define w 0,1 +#define t(a) a +#define p() int +#define q(x) x +#define r(x,y) x ## y +#define str(x) # x + f(y+1) + f(f(z)) % t(t(g)(0) + t)(1); + g(x+(3,4)-w) | h 5) & m +(f)^m(m); +p() i[q()] = { q(1), r(2,3), r(4,), r(,5), r(,) }; +char c[2][6] = { str(hello), str() }; + + diff --git a/test/Preprocessor/c99-6_10_3_4_p6.c b/test/Preprocessor/c99-6_10_3_4_p6.c new file mode 100644 index 0000000..c48d2ef --- /dev/null +++ b/test/Preprocessor/c99-6_10_3_4_p6.c @@ -0,0 +1,24 @@ +// Example from C99 6.10.3.4p6 + +// RUN: clang-cc -E %s | grep -F 'printf("x" "1" "= %d, x" "2" "= s" x1, x2);' && +// RUN: clang-cc -E %s | grep 'fputs("strncmp(\\"abc\\\\0d\\" \\"abc\\", .\\\\4.) == 0" ": @\\n", s);' && +// RUN: clang-cc -E %s | grep -F 'include "vers2.h"' && +// RUN: clang-cc -E %s | grep -F '"hello";' && +// RUN: clang-cc -E %s | grep -F '"hello" ", world"' + +#define str(s) # s +#define xstr(s) str(s) +#define debug(s, t) printf("x" # s "= %d, x" # t "= s" \ + x ## s, x ## t) +#define INCFILE(n) vers ## n +#define glue(a, b) a ## b +#define xglue(a, b) glue(a, b) +#define HIGHLOW "hello" +#define LOW LOW ", world" +debug(1, 2); +fputs(str(strncmp("abc\0d" "abc", '\4') // this goes away + == 0) str(: @\n), s); +include xstr(INCFILE(2).h) +glue(HIGH, LOW); +xglue(HIGH, LOW) + diff --git a/test/Preprocessor/c99-6_10_3_4_p7.c b/test/Preprocessor/c99-6_10_3_4_p7.c new file mode 100644 index 0000000..a53df82 --- /dev/null +++ b/test/Preprocessor/c99-6_10_3_4_p7.c @@ -0,0 +1,9 @@ +// Example from C99 6.10.3.4p7 + +// RUN: clang-cc -E %s | grep -F 'int j[] = { 123, 45, 67, 89,' && +// RUN: clang-cc -E %s | grep -F '10, 11, 12, };' + +#define t(x,y,z) x ## y ## z +int j[] = { t(1,2,3), t(,4,5), t(6,,7), t(8,9,), +t(10,,), t(,11,), t(,,12), t(,,) }; + diff --git a/test/Preprocessor/c99-6_10_3_4_p9.c b/test/Preprocessor/c99-6_10_3_4_p9.c new file mode 100644 index 0000000..39c3454 --- /dev/null +++ b/test/Preprocessor/c99-6_10_3_4_p9.c @@ -0,0 +1,16 @@ +// Example from C99 6.10.3.4p9 + +// RUN: clang-cc -E %s | grep -F 'fprintf(stderr, "Flag");' && +// RUN: clang-cc -E %s | grep -F 'fprintf(stderr, "X = %d\n", x);' && +// RUN: clang-cc -E %s | grep -F 'puts("The first, second, and third items.");' && +// RUN: clang-cc -E %s | grep -F '((x>y)?puts("x>y"): printf("x is %d but y is %d", x, y));' + +#define debug(...) fprintf(stderr, __VA_ARGS__) +#define showlist(...) puts(#__VA_ARGS__) +#define report(test, ...) ((test)?puts(#test):\ + printf(__VA_ARGS__)) +debug("Flag"); +debug("X = %d\n", x); +showlist(The first, second, and third items.); +report(x>y, "x is %d but y is %d", x, y); + diff --git a/test/Preprocessor/clang_headers.c b/test/Preprocessor/clang_headers.c new file mode 100644 index 0000000..1cb3319 --- /dev/null +++ b/test/Preprocessor/clang_headers.c @@ -0,0 +1,3 @@ +// RUN: clang-cc -E %s + +#include <limits.h> diff --git a/test/Preprocessor/comment_save.c b/test/Preprocessor/comment_save.c new file mode 100644 index 0000000..30b0434 --- /dev/null +++ b/test/Preprocessor/comment_save.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -E -C %s | grep '^// foo$' && +// RUN: clang-cc -E -C %s | grep -F '^/* bar */$' + +// foo +/* bar */ + + diff --git a/test/Preprocessor/comment_save_if.c b/test/Preprocessor/comment_save_if.c new file mode 100644 index 0000000..c08b2d7 --- /dev/null +++ b/test/Preprocessor/comment_save_if.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -E -CC -pedantic 2>&1 | grep -v '^/' | not grep warning + +#if 1 /*bar */ + +#endif /*foo*/ + diff --git a/test/Preprocessor/comment_save_macro.c b/test/Preprocessor/comment_save_macro.c new file mode 100644 index 0000000..66b59d1 --- /dev/null +++ b/test/Preprocessor/comment_save_macro.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -E -C %s | grep '^boo bork bar // zot$' && +// RUN: clang-cc -E -CC %s | grep -F '^boo bork /* blah*/ bar // zot$' && +// RUN: clang-cc -E %s | grep '^boo bork bar$' + + +#define FOO bork // blah +boo FOO bar // zot + diff --git a/test/Preprocessor/cxx_and.cpp b/test/Preprocessor/cxx_and.cpp new file mode 100644 index 0000000..971b7bc --- /dev/null +++ b/test/Preprocessor/cxx_and.cpp @@ -0,0 +1,17 @@ +// RUN: clang-cc -DA -DB -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DA -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -DB -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -E %s | grep 'int a = 927 == 927' +#if defined(A) and defined(B) +#define X 37 +#else +#define X 927 +#endif + +#if defined(A) && defined(B) +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/test/Preprocessor/cxx_bitand.cpp b/test/Preprocessor/cxx_bitand.cpp new file mode 100644 index 0000000..8d7fe67 --- /dev/null +++ b/test/Preprocessor/cxx_bitand.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -DA=1 -DB=2 -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -DA=1 -DB=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -E %s | grep 'int a = 927 == 927' +#if A bitand B +#define X 37 +#else +#define X 927 +#endif + +#if A & B +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/test/Preprocessor/cxx_bitor.cpp b/test/Preprocessor/cxx_bitor.cpp new file mode 100644 index 0000000..7645c7e --- /dev/null +++ b/test/Preprocessor/cxx_bitor.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -DA=1 -DB=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DA=0 -DB=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DA=1 -DB=0 -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DA=0 -DB=0 -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -E %s | grep 'int a = 927 == 927' +#if A bitor B +#define X 37 +#else +#define X 927 +#endif + +#if A | B +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/test/Preprocessor/cxx_compl.cpp b/test/Preprocessor/cxx_compl.cpp new file mode 100644 index 0000000..f1cc6d2 --- /dev/null +++ b/test/Preprocessor/cxx_compl.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -DA=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DA=0 -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -E %s | grep 'int a = 927 == 927' +#if compl 0 bitand A +#define X 37 +#else +#define X 927 +#endif + +#if ~0 & A +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/test/Preprocessor/cxx_not.cpp b/test/Preprocessor/cxx_not.cpp new file mode 100644 index 0000000..dd31901 --- /dev/null +++ b/test/Preprocessor/cxx_not.cpp @@ -0,0 +1,15 @@ +// RUN: clang-cc -DA=1 -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -E %s | grep 'int a = 37 == 37' +#if not defined(A) +#define X 37 +#else +#define X 927 +#endif + +#if ! defined(A) +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/test/Preprocessor/cxx_not_eq.cpp b/test/Preprocessor/cxx_not_eq.cpp new file mode 100644 index 0000000..4940f3b --- /dev/null +++ b/test/Preprocessor/cxx_not_eq.cpp @@ -0,0 +1,16 @@ +// RUN: clang-cc -DA=1 -DB=1 -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -DA=1 -DB=2 -E %s | grep 'int a = 37 == 37' +#if A not_eq B +#define X 37 +#else +#define X 927 +#endif + +#if A != B +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/test/Preprocessor/cxx_oper_keyword.cpp b/test/Preprocessor/cxx_oper_keyword.cpp new file mode 100644 index 0000000..faae687 --- /dev/null +++ b/test/Preprocessor/cxx_oper_keyword.cpp @@ -0,0 +1,7 @@ +// RUN: not clang-cc %s -E && +// RUN: clang-cc %s -E -fno-operator-names + +// Not valid in C++ unless -fno-operator-names is passed. +#define and foo + + diff --git a/test/Preprocessor/cxx_oper_spelling.cpp b/test/Preprocessor/cxx_oper_spelling.cpp new file mode 100644 index 0000000..85f0426 --- /dev/null +++ b/test/Preprocessor/cxx_oper_spelling.cpp @@ -0,0 +1,11 @@ +// RUN: clang-cc -E %s | grep 'a: "and"' + +#define X(A) #A + +// C++'03 2.5p2: "In all respects of the language, each alternative +// token behaves the same, respectively, as its primary token, +// except for its spelling" +// +// This should be spelled as 'and', not '&&' +a: X(and) + diff --git a/test/Preprocessor/cxx_or.cpp b/test/Preprocessor/cxx_or.cpp new file mode 100644 index 0000000..133f285 --- /dev/null +++ b/test/Preprocessor/cxx_or.cpp @@ -0,0 +1,17 @@ +// RUN: clang-cc -DA -DB -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DA -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DB -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -E %s | grep 'int a = 927 == 927' +#if defined(A) or defined(B) +#define X 37 +#else +#define X 927 +#endif + +#if defined(A) || defined(B) +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/test/Preprocessor/cxx_true.cpp b/test/Preprocessor/cxx_true.cpp new file mode 100644 index 0000000..e35c54d --- /dev/null +++ b/test/Preprocessor/cxx_true.cpp @@ -0,0 +1,13 @@ +/* RUN: clang-cc -E %s -x=c++ | grep block_1 && + RUN: clang-cc -E %s -x=c++ | not grep block_2 && + RUN: clang-cc -E %s -x=c | not grep block +*/ + +#if true +block_1 +#endif + +#if false +block_2 +#endif + diff --git a/test/Preprocessor/cxx_xor.cpp b/test/Preprocessor/cxx_xor.cpp new file mode 100644 index 0000000..a38c3c5 --- /dev/null +++ b/test/Preprocessor/cxx_xor.cpp @@ -0,0 +1,18 @@ +// RUN: clang-cc -DA=1 -DB=1 -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -DA=0 -DB=1 -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DA=1 -DB=0 -E %s | grep 'int a = 37 == 37' && +// RUN: clang-cc -DA=0 -DB=0 -E %s | grep 'int a = 927 == 927' && +// RUN: clang-cc -E %s | grep 'int a = 927 == 927' +#if A xor B +#define X 37 +#else +#define X 927 +#endif + +#if A ^ B +#define Y 37 +#else +#define Y 927 +#endif + +int a = X == Y; diff --git a/test/Preprocessor/dependencies-and-pp.c b/test/Preprocessor/dependencies-and-pp.c new file mode 100644 index 0000000..1dc4d02 --- /dev/null +++ b/test/Preprocessor/dependencies-and-pp.c @@ -0,0 +1,5 @@ +// RUN: clang -E -o %t.1 %s && +// RUN: clang -E -MD -MF %t.d -MT foo -o %t.2 %s && +// RUN: diff %t.1 %t.2 && +// RUN: grep "foo:" %t.d && +// RUN: grep "dependencies-and-pp.c" %t.d diff --git a/test/Preprocessor/disabled-cond-diags.c b/test/Preprocessor/disabled-cond-diags.c new file mode 100644 index 0000000..eb7632f --- /dev/null +++ b/test/Preprocessor/disabled-cond-diags.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -E %s 2>&1 | not grep "warning\|error" + +#if 0 + +// Shouldn't get warnings here. +??( ??) + +// Should not get an error here. +` ` ` ` +#endif diff --git a/test/Preprocessor/dump-macros-spacing.c b/test/Preprocessor/dump-macros-spacing.c new file mode 100644 index 0000000..335e37c --- /dev/null +++ b/test/Preprocessor/dump-macros-spacing.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -E -dD < %s | grep stdin | grep -v define +#define A A +/* 1 + * 2 + * 3 + * 4 + * 5 + * 6 + * 7 + * 8 + */ +#define B B + diff --git a/test/Preprocessor/dump-options.c b/test/Preprocessor/dump-options.c new file mode 100644 index 0000000..6910e1a --- /dev/null +++ b/test/Preprocessor/dump-options.c @@ -0,0 +1,3 @@ +// RUN: clang %s -E -dD | grep __INTMAX_MAX__ && +// RUN: clang %s -E -dM | grep __INTMAX_MAX__ + diff --git a/test/Preprocessor/dump_macros.c b/test/Preprocessor/dump_macros.c new file mode 100644 index 0000000..d3e06b2 --- /dev/null +++ b/test/Preprocessor/dump_macros.c @@ -0,0 +1,31 @@ +// RUN: clang-cc -E -dM %s -o %t && + +// Space even without expansion tokens +// RUN: grep "#define A(x) " %t && +#define A(x) + +// Space before expansion list. +// RUN: grep "#define B(x,y) x y" %t && +#define B(x,y)x y + +// No space in expansion list. +// RUN: grep "#define C(x,y) x y" %t && +#define C(x, y) x y + +// No paste avoidance. +// RUN: grep "#define X() .." %t && +#define X() .. + +// Simple test. +// RUN: grep "#define Y ." %t && +// RUN: grep "#define Z X()Y" %t && +#define Y . +#define Z X()Y + +// gcc prints macros at end of translation unit, so last one wins. +// RUN: grep "#define foo 2" %t && +// RUN: not grep "#define foo 1" %t +#define foo 1 +#undef foo +#define foo 2 + diff --git a/test/Preprocessor/dumptokens_phyloc.c b/test/Preprocessor/dumptokens_phyloc.c new file mode 100644 index 0000000..c0e78c9 --- /dev/null +++ b/test/Preprocessor/dumptokens_phyloc.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -dump-tokens %s 2>&1 | grep "Spelling=.*dumptokens_phyloc.c:3:20" + +#define TESTPHYLOC 10 + +TESTPHYLOC diff --git a/test/Preprocessor/expr_comma.c b/test/Preprocessor/expr_comma.c new file mode 100644 index 0000000..0a24bac --- /dev/null +++ b/test/Preprocessor/expr_comma.c @@ -0,0 +1,10 @@ +// Comma is not allowed in C89 +// RUN: not clang-cc -E %s -std=c89 -pedantic-errors && + +// Comma is allowed if unevaluated in C99 +// RUN: clang-cc -E %s -std=c99 -pedantic-errors + +// PR2279 + +#if 0? 1,2:3 +#endif diff --git a/test/Preprocessor/expr_invalid_tok.c b/test/Preprocessor/expr_invalid_tok.c new file mode 100644 index 0000000..5e750a4 --- /dev/null +++ b/test/Preprocessor/expr_invalid_tok.c @@ -0,0 +1,15 @@ +// RUN: not clang-cc -E %s 2>&1 | grep 'invalid token at start of a preprocessor expression' && +// RUN: not clang-cc -E %s 2>&1 | grep 'token is not a valid binary operator in a preprocessor subexpression' && +// RUN: not clang-cc -E %s 2>&1 | grep ':14: error: expected end of line in preprocessor expression' +// PR2220 + +#if 1 * * 2 +#endif + +#if 4 [ 2 +#endif + + +// PR2284 - The constant-expr production does not including comma. +#if 1 ? 2 : 0, 1 +#endif diff --git a/test/Preprocessor/expr_liveness.c b/test/Preprocessor/expr_liveness.c new file mode 100644 index 0000000..3d1e25e --- /dev/null +++ b/test/Preprocessor/expr_liveness.c @@ -0,0 +1,52 @@ +/* RUN: clang-cc -E %s -DNO_ERRORS -Werror -Wundef && + RUN: not clang-cc -E %s + */ + +#ifdef NO_ERRORS +/* None of these divisions by zero are in live parts of the expression, do not + emit any diagnostics. */ + +#define MACRO_0 0 +#define MACRO_1 1 + +#if MACRO_0 && 10 / MACRO_0 +foo +#endif + +#if MACRO_1 || 10 / MACRO_0 +bar +#endif + +#if 0 ? 124/0 : 42 +#endif + +// PR2279 +#if 0 ? 1/0: 2 +#else +#error +#endif + +// PR2279 +#if 1 ? 2 ? 3 : 4 : 5 +#endif + +// PR2284 +#if 1 ? 0: 1 ? 1/0: 1/0 +#endif + +#else + + +/* The 1/0 is live, it should error out. */ +#if 0 && 1 ? 4 : 1 / 0 +baz +#endif + + +#endif + +// rdar://6505352 +// -Wundef should not warn about use of undefined identifier if not live. +#if (!defined(XXX) || XXX > 42) +#endif + diff --git a/test/Preprocessor/expr_multichar.c b/test/Preprocessor/expr_multichar.c new file mode 100644 index 0000000..4df8f3d --- /dev/null +++ b/test/Preprocessor/expr_multichar.c @@ -0,0 +1,5 @@ +// RUN: clang-cc < %s -E -verify -triple i686-pc-linux-gnu + +#if (('1234' >> 24) != '1') +#error Bad multichar constant calculation! +#endif diff --git a/test/Preprocessor/expr_usual_conversions.c b/test/Preprocessor/expr_usual_conversions.c new file mode 100644 index 0000000..47aca7b --- /dev/null +++ b/test/Preprocessor/expr_usual_conversions.c @@ -0,0 +1,13 @@ +// RUN: clang-cc %s -E 2>&1 | grep warning | wc -l | grep 2 + +#define INTMAX_MIN (-9223372036854775807LL -1) + +#if (-42 + 0U) / -2 +foo +#endif + +// Shifts don't want the usual conversions: PR2279 +#if (2 << 1U) - 30 >= 0 +#error +#endif + diff --git a/test/Preprocessor/extension-warning.c b/test/Preprocessor/extension-warning.c new file mode 100644 index 0000000..7b5095f --- /dev/null +++ b/test/Preprocessor/extension-warning.c @@ -0,0 +1,18 @@ +// RUN: clang-cc -fsyntax-only -verify -pedantic %s + +// The preprocessor shouldn't warn about extensions within macro bodies that +// aren't expanded. +#define TY typeof +#define TY1 typeof(1) + +// But we should warn here +TY1 x; // expected-warning {{extension}} +TY(1) x; // FIXME: And we should warn here + +// Note: this warning intentionally doesn't trigger on keywords like +// __attribute; the standard allows implementation-defined extensions +// prefixed with "__". +// Current list of keywords this can trigger on: +// inline, restrict, asm, typeof, _asm + +void whatever() {} diff --git a/test/Preprocessor/file_to_include.h b/test/Preprocessor/file_to_include.h new file mode 100644 index 0000000..97728ab --- /dev/null +++ b/test/Preprocessor/file_to_include.h @@ -0,0 +1,3 @@ + +#warning file successfully included + diff --git a/test/Preprocessor/function_macro_file.c b/test/Preprocessor/function_macro_file.c new file mode 100644 index 0000000..6a266dd --- /dev/null +++ b/test/Preprocessor/function_macro_file.c @@ -0,0 +1,5 @@ +/* RUN: clang-cc -E -P %s | grep f + */ + +#include "function_macro_file.h" +() diff --git a/test/Preprocessor/function_macro_file.h b/test/Preprocessor/function_macro_file.h new file mode 100644 index 0000000..43d1199 --- /dev/null +++ b/test/Preprocessor/function_macro_file.h @@ -0,0 +1,3 @@ + +#define f() x +f diff --git a/test/Preprocessor/hash_line.c b/test/Preprocessor/hash_line.c new file mode 100644 index 0000000..7ed65d1 --- /dev/null +++ b/test/Preprocessor/hash_line.c @@ -0,0 +1,8 @@ +// The 1 and # should not go on the same line. +// RUN: clang-cc %s -E | not grep "1 #" && +// RUN: clang-cc %s -E | grep '^1$' && +// RUN: clang-cc %s -E | grep '^ #$' +1 +#define EMPTY +EMPTY # + diff --git a/test/Preprocessor/hash_space.c b/test/Preprocessor/hash_space.c new file mode 100644 index 0000000..e7dbd3b --- /dev/null +++ b/test/Preprocessor/hash_space.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -E | grep " #" + +// Should put a space before the # so that -fpreprocessed mode doesn't +// macro expand this again. +#define HASH # +HASH define foo bar diff --git a/test/Preprocessor/header_lookup1.c b/test/Preprocessor/header_lookup1.c new file mode 100644 index 0000000..df58a6e --- /dev/null +++ b/test/Preprocessor/header_lookup1.c @@ -0,0 +1,2 @@ +// RUN: clang-cc -I /usr/include %s -E | grep 'stdio.h.*3.*4' +#include <stdio.h> diff --git a/test/Preprocessor/if_warning.c b/test/Preprocessor/if_warning.c new file mode 100644 index 0000000..5567513 --- /dev/null +++ b/test/Preprocessor/if_warning.c @@ -0,0 +1,21 @@ +// RUN: clang-cc %s -Eonly -Werror=undef -verify && +// RUN: clang-cc %s -Eonly -Werror-undef -verify + +extern int x; + +#if foo // expected-error {{'foo' is not defined, evaluates to 0}} +#endif + +#ifdef foo +#endif + +#if defined(foo) +#endif + + +// PR3938 +#if 0 +#ifdef D +#else 1 // Should not warn due to C99 6.10p4 +#endif +#endif diff --git a/test/Preprocessor/ifdef-recover.c b/test/Preprocessor/ifdef-recover.c new file mode 100644 index 0000000..3fffcc0 --- /dev/null +++ b/test/Preprocessor/ifdef-recover.c @@ -0,0 +1,15 @@ +/* RUN: clang-cc -E %s 2>&1 >/dev/null | grep error: | count 3 + */ + +#ifdef + +#endif + +/* End of function-like macro invocation in #ifdef */ +/* PR1936 */ +#define f(x) x +#if f(2 +#endif + +int x; + diff --git a/test/Preprocessor/import_self.c b/test/Preprocessor/import_self.c new file mode 100644 index 0000000..2cabe3d --- /dev/null +++ b/test/Preprocessor/import_self.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -E -I. %s | grep BODY_OF_FILE | wc -l | grep 1 + +// This #import should have no effect, as we're importing the current file. +#import <import_self.c> + +BODY_OF_FILE + diff --git a/test/Preprocessor/include-directive1.c b/test/Preprocessor/include-directive1.c new file mode 100644 index 0000000..66f70fb --- /dev/null +++ b/test/Preprocessor/include-directive1.c @@ -0,0 +1,14 @@ +// RUN: clang-cc -E %s -fno-caret-diagnostics 2>&1 >/dev/null | grep 'file successfully included' | count 3 + +// XX expands to nothing. +#define XX + +// expand macros to get to file to include +#define FILE "file_to_include.h" +#include XX FILE + +#include FILE + +// normal include +#include "file_to_include.h" + diff --git a/test/Preprocessor/include-directive2.c b/test/Preprocessor/include-directive2.c new file mode 100644 index 0000000..1239982 --- /dev/null +++ b/test/Preprocessor/include-directive2.c @@ -0,0 +1,17 @@ +// RUN: clang-cc -Eonly -verify %s +# define HEADER <float.h> + +# include HEADER + +#include <limits.h> NON_EMPTY // expected-warning {{extra tokens at end of #include directive}} + +// PR3916: these are ok. +#define EMPTY +#include <limits.h> EMPTY +#include HEADER EMPTY + +// PR3916 +#define FN limits.h> +#include <FN + +#include <> // expected-error {{empty filename}} diff --git a/test/Preprocessor/include-directive3.c b/test/Preprocessor/include-directive3.c new file mode 100644 index 0000000..e5b7a94 --- /dev/null +++ b/test/Preprocessor/include-directive3.c @@ -0,0 +1,3 @@ +// RUN: clang-cc -include %S/file_to_include.h -E %s -fno-caret-diagnostics 2>&1 >/dev/null | grep 'file successfully included' | count 1 +// PR3464 + diff --git a/test/Preprocessor/include-macros.c b/test/Preprocessor/include-macros.c new file mode 100644 index 0000000..d64ee5e --- /dev/null +++ b/test/Preprocessor/include-macros.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -E -Dtest=FOO -imacros %S/pr2086.h %s | grep 'HERE: test' + +// This should not be expanded into FOO because pr2086.h undefs 'test'. +HERE: test diff --git a/test/Preprocessor/include-pth.c b/test/Preprocessor/include-pth.c new file mode 100644 index 0000000..2afc66a --- /dev/null +++ b/test/Preprocessor/include-pth.c @@ -0,0 +1,3 @@ +// RUN: clang-cc -emit-pth %s -o %t && +// RUN: clang-cc -include-pth %t %s -E | grep 'file_to_include' | count 2 +#include "file_to_include.h" diff --git a/test/Preprocessor/indent_macro.c b/test/Preprocessor/indent_macro.c new file mode 100644 index 0000000..f6b411e --- /dev/null +++ b/test/Preprocessor/indent_macro.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -E %s | grep '^ zzap$' + +// zzap is on a new line, should be indented. +#define BLAH zzap + BLAH + diff --git a/test/Preprocessor/line-directive.c b/test/Preprocessor/line-directive.c new file mode 100644 index 0000000..ed9a6c4 --- /dev/null +++ b/test/Preprocessor/line-directive.c @@ -0,0 +1,92 @@ +// RUN: clang-cc -fsyntax-only -verify -pedantic %s && +// RUN: clang-cc -E %s 2>&1 | grep 'blonk.c:92:2: error: #error ABC' && +// RUN: clang-cc -E %s 2>&1 | grep 'blonk.c:93:2: error: #error DEF' + +#line 'a' // expected-error {{#line directive requires a positive integer argument}} +#line 0 // expected-error {{#line directive requires a positive integer argument}} +#line 00 // expected-error {{#line directive requires a positive integer argument}} +#line 2147483648 // expected-warning {{C requires #line number to be less than 2147483648, allowed as extension}} +#line 42 // ok +#line 42 'a' // expected-error {{invalid filename for #line directive}} +#line 42 "foo/bar/baz.h" // ok + + +// #line directives expand macros. +#define A 42 "foo" +#line A + +# 42 +# 42 "foo" +# 42 "foo" 2 // expected-error {{invalid line marker flag '2': cannot pop empty include stack}} +# 42 "foo" 1 3 // enter +# 42 "foo" 2 3 // exit +# 42 "foo" 2 3 4 // expected-error {{invalid line marker flag '2': cannot pop empty include stack}} +# 42 "foo" 3 4 + +# 'a' // expected-error {{invalid preprocessing directive}} +# 42 'f' // expected-error {{invalid filename for line marker directive}} +# 42 1 3 // expected-error {{invalid filename for line marker directive}} +# 42 "foo" 3 1 // expected-error {{invalid flag line marker directive}} +# 42 "foo" 42 // expected-error {{invalid flag line marker directive}} +# 42 "foo" 1 2 // expected-error {{invalid flag line marker directive}} + + +// These are checked by the RUN line. +#line 92 "blonk.c" +#error ABC // expected-error {{#error ABC}} +#error DEF // expected-error {{#error DEF}} + + +// Verify that linemarker diddling of the system header flag works. + +# 192 "glomp.h" // not a system header. +typedef int x; // expected-note {{previous definition is here}} +typedef int x; // expected-error {{redefinition of typedef 'x' is invalid in C}} + +# 192 "glomp.h" 3 // System header. +typedef int y; // ok +typedef int y; // ok + +typedef int q; // q is in system header. + +#line 42 "blonk.h" // doesn't change system headerness. + +typedef int z; // ok +typedef int z; // ok + +# 97 // doesn't change system headerness. + +typedef int z1; // ok +typedef int z1; // ok + +# 42 "blonk.h" // DOES change system headerness. + +typedef int w; // expected-note {{previous definition is here}} +typedef int w; // expected-error {{redefinition of typedef 'w' is invalid in C}} + +typedef int q; // original definition in system header, should not diagnose. + +// This should not produce an "extra tokens at end of #line directive" warning, +// because #line is allowed to contain expanded tokens. +#define EMPTY() +#line 2 "foo.c" EMPTY( ) +#line 2 "foo.c" NONEMPTY( ) // expected-warning{{extra tokens at end of #line directive}} + +// PR3940 +#line 0xf // expected-error {{#line directive requires a simple digit sequence}} +#line 42U // expected-error {{#line directive requires a simple digit sequence}} + + +// Line markers are digit strings interpreted as decimal numbers, this is +// 10, not 8. +#line 010 // expected-warning {{#line directive interprets number as decimal, not octal}} +extern int array[__LINE__ == 10 ? 1:-1]; + +/* PR3917 */ +#line 41 +extern char array2[\ +_\ +_LINE__ == 42 ? 1: -1]; /* line marker is location of first _ */ + + + diff --git a/test/Preprocessor/macro-multiline.c b/test/Preprocessor/macro-multiline.c new file mode 100644 index 0000000..eb15668 --- /dev/null +++ b/test/Preprocessor/macro-multiline.c @@ -0,0 +1,8 @@ +// RUN: clang -E %s "-DX=A +// RUN: THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT" > %t && +// RUN: grep "GOOD: A" %t && +// RUN: not grep THIS_SHOULD_NOT_EXIST_IN_THE_OUTPUT %t +// rdar://6762183 + +GOOD: X + diff --git a/test/Preprocessor/macro_arg_keyword.c b/test/Preprocessor/macro_arg_keyword.c new file mode 100644 index 0000000..92b1ae5 --- /dev/null +++ b/test/Preprocessor/macro_arg_keyword.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -E %s | grep xxx-xxx + +#define foo(return) return-return + +foo(xxx) + diff --git a/test/Preprocessor/macro_disable.c b/test/Preprocessor/macro_disable.c new file mode 100644 index 0000000..ff861d2 --- /dev/null +++ b/test/Preprocessor/macro_disable.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -E %s | grep 'a: 2 + M_0(3)(4)(5);' && +// RUN: clang-cc -E %s | grep 'b: 4 + 4 + 3 + 2 + 1 + M_0(3)(2)(1);' + +#define M_0(x) M_ ## x +#define M_1(x) x + M_0(0) +#define M_2(x) x + M_1(1) +#define M_3(x) x + M_2(2) +#define M_4(x) x + M_3(3) +#define M_5(x) x + M_4(4) + +a: M_0(1)(2)(3)(4)(5); +b: M_0(5)(4)(3)(2)(1); + diff --git a/test/Preprocessor/macro_disable2.c b/test/Preprocessor/macro_disable2.c new file mode 100644 index 0000000..286539e --- /dev/null +++ b/test/Preprocessor/macro_disable2.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -E %s | grep 'A B C A B A C A B C A' + +#define A A B C +#define B B C A +#define C C A B + +A + diff --git a/test/Preprocessor/macro_disable3.c b/test/Preprocessor/macro_disable3.c new file mode 100644 index 0000000..011de3b --- /dev/null +++ b/test/Preprocessor/macro_disable3.c @@ -0,0 +1,8 @@ +// RUN: clang-cc %s -E | grep -F 'f(2 * (f(2 * (z[0]))));' +// Check for C99 6.10.3.4p2. + +#define f(a) f(x * (a)) +#define x 2 +#define z z[0] +f(f(z)); + diff --git a/test/Preprocessor/macro_disable4.c b/test/Preprocessor/macro_disable4.c new file mode 100644 index 0000000..b652b98 --- /dev/null +++ b/test/Preprocessor/macro_disable4.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -P -E %s | grep 'int f(void)' +// PR1820 + +#define f(x) h(x +#define h(x) x(void) +extern int f(f)); diff --git a/test/Preprocessor/macro_expand.c b/test/Preprocessor/macro_expand.c new file mode 100644 index 0000000..74b3922 --- /dev/null +++ b/test/Preprocessor/macro_expand.c @@ -0,0 +1,19 @@ +// RUN: clang-cc -E %s | grep '^A: Y$' && +// RUN: clang-cc -E %s | grep '^B: f()$' && +// RUN: clang-cc -E %s | grep '^C: for()$' + +#define X() Y +#define Y() X + +A: X()()() + +// PR3927 +#define f(x) h(x +#define for(x) h(x +#define h(x) x() +B: f(f)) +C: for(for)) + +// rdar://6880648 +#define f(x,y...) y +f() diff --git a/test/Preprocessor/macro_expandloc.c b/test/Preprocessor/macro_expandloc.c new file mode 100644 index 0000000..ce1efd2 --- /dev/null +++ b/test/Preprocessor/macro_expandloc.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -E 2>&1 | grep '#include' +#define FOO 1 + +// The error message should be on the #include line, not the 1. +#include FOO + diff --git a/test/Preprocessor/macro_expandloc2.c b/test/Preprocessor/macro_expandloc2.c new file mode 100644 index 0000000..9adf3fd --- /dev/null +++ b/test/Preprocessor/macro_expandloc2.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -E 2>&1 | grep '#include' +#define FOO BAR + +// The error message should be on the #include line, not the 1. +#include FOO + diff --git a/test/Preprocessor/macro_fn.c b/test/Preprocessor/macro_fn.c new file mode 100644 index 0000000..5c55c0c --- /dev/null +++ b/test/Preprocessor/macro_fn.c @@ -0,0 +1,46 @@ +/* RUN: clang-cc %s -Eonly -std=c89 -pedantic -verify +*/ +/* PR3937 */ +#define zero() 0 +#define one(x) 0 +#define two(x, y) 0 +#define zero_dot(...) 0 /* expected-warning {{variadic macros were introduced in C99}} */ +#define one_dot(x, ...) 0 /* expected-warning {{variadic macros were introduced in C99}} */ + +zero() +zero(1); /* expected-error {{too many arguments provided to function-like macro invocation}} */ +zero(1, 2, 3); /* expected-error {{too many arguments provided to function-like macro invocation}} */ + +one() /* ok */ +one(a) +one(a,) /* expected-error {{too many arguments provided to function-like macro invocation}} */ +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}} */ +two(a) /* expected-error {{too few arguments provided to function-like macro invocation}} */ +two(a,b) +two(a, ) /* expected-warning {{empty macro arguments were standardized in C99}} */ +two(a,b,c) /* expected-error {{too many arguments provided to function-like macro invocation}} */ +two( + , /* expected-warning {{empty macro arguments were standardized in C99}} */ + , /* expected-warning {{empty macro arguments were standardized in C99}} \ + expected-error {{too many arguments provided to function-like macro invocation}} */ + ) +two(,) /* expected-warning 2 {{empty macro arguments were standardized in C99}} */ + + + +/* PR4006 & rdar://6807000 */ +#define e(...) __VA_ARGS__ /* expected-warning {{variadic macros were introduced in C99}} */ +e(x) +e() + +zero_dot() +one_dot(x) /* empty ... argument: expected-warning {{varargs argument missing, but tolerated as an extension}} */ +one_dot() /* empty first argument, elided ...: expected-warning {{varargs argument missing, but tolerated as an extension}} */ + + +/* rdar://6816766 - Crash with function-like macro test at end of directive. */ +#define E() (i == 0) +#if E +#endif diff --git a/test/Preprocessor/macro_fn_comma_swallow.c b/test/Preprocessor/macro_fn_comma_swallow.c new file mode 100644 index 0000000..e985138 --- /dev/null +++ b/test/Preprocessor/macro_fn_comma_swallow.c @@ -0,0 +1,21 @@ +// Test the GNU comma swallowing extension. +// RUN: clang-cc %s -E | grep 'foo{A, }' && +// RUN: clang-cc %s -E | grep 'fo2{A,}' && +// RUN: clang-cc %s -E | grep '{foo}' + +#define X(Y) foo{A, Y} +X() + +#define X2(Y) fo2{A,##Y} +X2() + +// should eat the comma. +#define X3(b, ...) {b, ## __VA_ARGS__} +X3(foo) + + + +// RUN: clang-cc %s -E | grep 'AA BB' +// PR3880 +#define X4(...) AA , ## __VA_ARGS__ BB +X4() diff --git a/test/Preprocessor/macro_fn_disable_expand.c b/test/Preprocessor/macro_fn_disable_expand.c new file mode 100644 index 0000000..d99c018 --- /dev/null +++ b/test/Preprocessor/macro_fn_disable_expand.c @@ -0,0 +1,11 @@ +// RUN: clang-cc %s -E | grep 'bar foo (2)' && +// RUN: clang-cc %s -E | grep 'm(ABCD)' + +#define foo(x) bar x +foo(foo) (2) + + +#define m(a) a(w) +#define w ABCD +m(m) // m(ABCD) + diff --git a/test/Preprocessor/macro_fn_lparen_scan.c b/test/Preprocessor/macro_fn_lparen_scan.c new file mode 100644 index 0000000..1056fd8 --- /dev/null +++ b/test/Preprocessor/macro_fn_lparen_scan.c @@ -0,0 +1,27 @@ +// RUN: clang-cc -E %s | grep 'noexp: foo y' && +// RUN: clang-cc -E %s | grep 'expand: abc' && +// RUN: clang-cc -E %s | grep 'noexp2: foo nonexp' && +// RUN: clang-cc -E %s | grep 'expand2: abc' + +#define A foo +#define foo() abc +#define X A y + +// This should not expand to abc, because the foo macro isn't followed by (. +noexp: X + + +// This should expand to abc. +#undef X +#define X A () +expand: X + + +// This should be 'foo nonexp' +noexp2: A nonexp + +// This should expand +expand2: A ( +) + + diff --git a/test/Preprocessor/macro_fn_lparen_scan2.c b/test/Preprocessor/macro_fn_lparen_scan2.c new file mode 100644 index 0000000..fb64bef --- /dev/null +++ b/test/Preprocessor/macro_fn_lparen_scan2.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -E %s | grep 'FUNC (3 +1);' + +#define F(a) a +#define FUNC(a) (a+1) + +F(FUNC) FUNC (3); /* final token sequence is FUNC(3+1) */ + diff --git a/test/Preprocessor/macro_fn_placemarker.c b/test/Preprocessor/macro_fn_placemarker.c new file mode 100644 index 0000000..ff688ce --- /dev/null +++ b/test/Preprocessor/macro_fn_placemarker.c @@ -0,0 +1,5 @@ +// RUN: clang-cc %s -E | grep 'foo(A, )' + +#define X(Y) foo(A, Y) +X() + diff --git a/test/Preprocessor/macro_fn_preexpand.c b/test/Preprocessor/macro_fn_preexpand.c new file mode 100644 index 0000000..a392263 --- /dev/null +++ b/test/Preprocessor/macro_fn_preexpand.c @@ -0,0 +1,12 @@ +// RUN: clang-cc %s -E | grep 'pre: 1 1 X' && +// RUN: clang-cc %s -E | grep 'nopre: 1A(X)' + +/* Preexpansion of argument. */ +#define A(X) 1 X +pre: A(A(X)) + +/* The ## operator disables preexpansion. */ +#undef A +#define A(X) 1 ## X +nopre: A(A(X)) + diff --git a/test/Preprocessor/macro_fn_varargs_iso.c b/test/Preprocessor/macro_fn_varargs_iso.c new file mode 100644 index 0000000..78ad212 --- /dev/null +++ b/test/Preprocessor/macro_fn_varargs_iso.c @@ -0,0 +1,11 @@ + +// RUN: clang-cc -E %s | grep 'foo{a, b, c, d, e}' && +// RUN: clang-cc -E %s | grep 'foo2{d, C, B}' && +// RUN: clang-cc -E %s | grep 'foo2{d,e, C, B}' + +#define va1(...) foo{a, __VA_ARGS__, e} +va1(b, c, d) +#define va2(a, b, ...) foo2{__VA_ARGS__, b, a} +va2(B, C, d) +va2(B, C, d,e) + diff --git a/test/Preprocessor/macro_fn_varargs_named.c b/test/Preprocessor/macro_fn_varargs_named.c new file mode 100644 index 0000000..c2841b1 --- /dev/null +++ b/test/Preprocessor/macro_fn_varargs_named.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -E %s | grep '^a: x$' && +// RUN: clang-cc -E %s | grep '^b: x y, z,h$' && +// RUN: clang-cc -E %s | grep '^c: foo(x)$' + +#define A(b, c...) b c +a: A(x) +b: A(x, y, z,h) + +#define B(b, c...) foo(b, ## c) +c: B(x) diff --git a/test/Preprocessor/macro_misc.c b/test/Preprocessor/macro_misc.c new file mode 100644 index 0000000..169c5ec --- /dev/null +++ b/test/Preprocessor/macro_misc.c @@ -0,0 +1,23 @@ +// RUN: clang-cc %s -Eonly -verify + +// This should not be rejected. +#ifdef defined +#endif + + + +// PR3764 + +// This should not produce a redefinition warning. +#define FUNC_LIKE(a) (a) +#define FUNC_LIKE(a)(a) + +// This either. +#define FUNC_LIKE2(a)\ +(a) +#define FUNC_LIKE2(a) (a) + +// This should. +#define FUNC_LIKE3(a) ( a) // expected-note {{previous definition is here}} +#define FUNC_LIKE3(a) (a) // expected-warning {{'FUNC_LIKE3' macro redefined}} + diff --git a/test/Preprocessor/macro_not_define.c b/test/Preprocessor/macro_not_define.c new file mode 100644 index 0000000..a42240b --- /dev/null +++ b/test/Preprocessor/macro_not_define.c @@ -0,0 +1,9 @@ +// RUN: clang-cc -E %s | grep '^ # define X 3$' + +#define H # + #define D define + + #define DEFINE(a, b) H D a b + + DEFINE(X, 3) + diff --git a/test/Preprocessor/macro_paste_bad.c b/test/Preprocessor/macro_paste_bad.c new file mode 100644 index 0000000..1212c44 --- /dev/null +++ b/test/Preprocessor/macro_paste_bad.c @@ -0,0 +1,35 @@ +// RUN: clang-cc -Eonly -verify -pedantic %s +// pasting ""x"" and ""+"" does not give a valid preprocessing token +#define XYZ x ## + +XYZ // expected-error {{pasting formed 'x+', an invalid preprocessing token}} +#define XXYZ . ## test +XXYZ // expected-error {{pasting formed '.test', an invalid preprocessing token}} + +// GCC PR 20077 + +#define a a ## ## // expected-error {{'##' cannot appear at end of macro expansion}} +#define b() b ## ## // expected-error {{'##' cannot appear at end of macro expansion}} +#define c c ## // expected-error {{'##' cannot appear at end of macro expansion}} +#define d() d ## // expected-error {{'##' cannot appear at end of macro expansion}} + + +#define e ## ## e // expected-error {{'##' cannot appear at start of macro expansion}} +#define f() ## ## f // expected-error {{'##' cannot appear at start of macro expansion}} +#define g ## g // expected-error {{'##' cannot appear at start of macro expansion}} +#define h() ## h // expected-error {{'##' cannot appear at start of macro expansion}} +#define i ## // expected-error {{'##' cannot appear at start of macro expansion}} +#define j() ## // expected-error {{'##' cannot appear at start of macro expansion}} + +// Invalid token pasting. +// PR3918 + +// When pasting creates poisoned identifiers, we error. +#pragma GCC poison BLARG +BLARG // expected-error {{attempt to use a poisoned identifier}} +#define XX BL ## ARG +XX // expected-error {{attempt to use a poisoned identifier}} + +#define VA __VA_ ## ARGS__ +int VA; // expected-warning {{__VA_ARGS__ can only appear in the expansion of a C99 variadic macro}} + + diff --git a/test/Preprocessor/macro_paste_bcpl_comment.c b/test/Preprocessor/macro_paste_bcpl_comment.c new file mode 100644 index 0000000..8bbee5d --- /dev/null +++ b/test/Preprocessor/macro_paste_bcpl_comment.c @@ -0,0 +1,5 @@ +// RUN: clang-cc %s -Eonly 2>&1 | grep error + +#define COMM1 / ## / +COMM1 + diff --git a/test/Preprocessor/macro_paste_c_block_comment.c b/test/Preprocessor/macro_paste_c_block_comment.c new file mode 100644 index 0000000..86f8124 --- /dev/null +++ b/test/Preprocessor/macro_paste_c_block_comment.c @@ -0,0 +1,7 @@ +// RUN: clang-cc %s -Eonly 2>&1 | grep error && +// RUN: clang-cc %s -Eonly 2>&1 | not grep unterminated && +// RUN: clang-cc %s -Eonly 2>&1 | not grep scratch + +#define COMM / ## * +COMM + diff --git a/test/Preprocessor/macro_paste_commaext.c b/test/Preprocessor/macro_paste_commaext.c new file mode 100644 index 0000000..e98849b --- /dev/null +++ b/test/Preprocessor/macro_paste_commaext.c @@ -0,0 +1,13 @@ +// RUN: clang-cc %s -E | grep 'V);' && +// RUN: clang-cc %s -E | grep 'W, 1, 2);' && +// RUN: clang-cc %s -E | grep 'X, 1, 2);' && +// RUN: clang-cc %s -E | grep 'Y, );' && +// RUN: clang-cc %s -E | grep 'Z, );' + +#define debug(format, ...) format, ## __VA_ARGS__) +debug(V); +debug(W, 1, 2); +debug(X, 1, 2 ); +debug(Y, ); +debug(Z,); + diff --git a/test/Preprocessor/macro_paste_empty.c b/test/Preprocessor/macro_paste_empty.c new file mode 100644 index 0000000..75504bc --- /dev/null +++ b/test/Preprocessor/macro_paste_empty.c @@ -0,0 +1,13 @@ +// RUN: clang-cc -E %s | grep 'a:Y' && +// RUN: clang-cc -E %s | grep 'b:Y' && +// RUN: clang-cc -E %s | grep 'c:YY' + +#define FOO(X) X ## Y +a:FOO() + +#define FOO2(X) Y ## X +b:FOO2() + +#define FOO3(X) X ## Y ## X ## Y ## X ## X +c:FOO3() + diff --git a/test/Preprocessor/macro_paste_hard.c b/test/Preprocessor/macro_paste_hard.c new file mode 100644 index 0000000..25b6c19 --- /dev/null +++ b/test/Preprocessor/macro_paste_hard.c @@ -0,0 +1,17 @@ +// RUN: clang-cc -E %s | grep '1: aaab 2' && +// RUN: clang-cc -E %s | grep '2: 2 baaa' && +// RUN: clang-cc -E %s | grep '3: 2 xx' + +#define a(n) aaa ## n +#define b 2 +1: a(b b) // aaab 2 2 gets expanded, not b. + +#undef a +#undef b +#define a(n) n ## aaa +#define b 2 +2: a(b b) // 2 baaa 2 gets expanded, not b. + +#define baaa xx +3: a(b b) // 2 xx + diff --git a/test/Preprocessor/macro_paste_hashhash.c b/test/Preprocessor/macro_paste_hashhash.c new file mode 100644 index 0000000..42654fd --- /dev/null +++ b/test/Preprocessor/macro_paste_hashhash.c @@ -0,0 +1,7 @@ +// RUN: clang-cc -E %s | grep '^"x ## y";$' +#define hash_hash # ## # +#define mkstr(a) # a +#define in_between(a) mkstr(a) +#define join(c, d) in_between(c hash_hash d) +join(x, y); + diff --git a/test/Preprocessor/macro_paste_mscomment.c b/test/Preprocessor/macro_paste_mscomment.c new file mode 100644 index 0000000..b0fc571 --- /dev/null +++ b/test/Preprocessor/macro_paste_mscomment.c @@ -0,0 +1,20 @@ +// RUN: clang-cc -P -E -fms-extensions %s | sed '/^#.\+/d' | tr -d '\n' | +// RUN: grep '^int foo;int bar;int baz;$' | count 1 +// This horrible stuff should preprocess into (other than whitespace): +// int foo; +// int bar; +// int baz; + +int foo; + +#define comment /##/ dead tokens live here +comment This is stupidity + +int bar; + +#define nested(x) int x comment cute little dead tokens... + +nested(baz) rise of the dead tokens + +; + diff --git a/test/Preprocessor/macro_paste_none.c b/test/Preprocessor/macro_paste_none.c new file mode 100644 index 0000000..e978fca --- /dev/null +++ b/test/Preprocessor/macro_paste_none.c @@ -0,0 +1,6 @@ +// RUN: clang-cc -E %s | grep '!!' + +#define A(B,C) B ## C + +!A(,)! + diff --git a/test/Preprocessor/macro_paste_simple.c b/test/Preprocessor/macro_paste_simple.c new file mode 100644 index 0000000..2affbac --- /dev/null +++ b/test/Preprocessor/macro_paste_simple.c @@ -0,0 +1,5 @@ +// RUN: clang-cc %s -E | grep "barbaz123" + +#define FOO bar ## baz ## 123 + +FOO diff --git a/test/Preprocessor/macro_paste_spacing.c b/test/Preprocessor/macro_paste_spacing.c new file mode 100644 index 0000000..130548d --- /dev/null +++ b/test/Preprocessor/macro_paste_spacing.c @@ -0,0 +1,7 @@ +// RUN: clang-cc %s -E | grep "^xy$" + +#define A x ## y +blah + +A + diff --git a/test/Preprocessor/macro_paste_spacing2.c b/test/Preprocessor/macro_paste_spacing2.c new file mode 100644 index 0000000..0db721a --- /dev/null +++ b/test/Preprocessor/macro_paste_spacing2.c @@ -0,0 +1,6 @@ +// RUN: clang-cc %s -E | grep "movl %eax" +// PR4132 +#define R1E %eax +#define epilogue(r1) movl r1 ## E; +epilogue(R1) + diff --git a/test/Preprocessor/macro_rescan.c b/test/Preprocessor/macro_rescan.c new file mode 100644 index 0000000..17b4dc2 --- /dev/null +++ b/test/Preprocessor/macro_rescan.c @@ -0,0 +1,9 @@ +// RUN: clang-cc -E %s | grep 'ei_1 = (17 +1);' && +// RUN: clang-cc -E %s | grep 'ei_2 = (M1)(17);' + +#define M1(a) (a+1) +#define M2(b) b + +int ei_1 = M2(M1)(17); /* becomes int ei_1 = (17+1); */ +int ei_2 = (M2(M1))(17); /* becomes int ei_2 = (M1)(17); */ + diff --git a/test/Preprocessor/macro_rescan2.c b/test/Preprocessor/macro_rescan2.c new file mode 100644 index 0000000..6914ae0 --- /dev/null +++ b/test/Preprocessor/macro_rescan2.c @@ -0,0 +1,15 @@ +// RUN: clang-cc %s -E | grep 'a: 2\*f(9)' && +// RUN: clang-cc %s -E | grep 'b: 2\*9\*g' + +#define f(a) a*g +#define g f +a: f(2)(9) + +#undef f +#undef g + +#define f(a) a*g +#define g(a) f(a) + +b: f(2)(9) + diff --git a/test/Preprocessor/macro_rescan_varargs.c b/test/Preprocessor/macro_rescan_varargs.c new file mode 100644 index 0000000..ed1056a --- /dev/null +++ b/test/Preprocessor/macro_rescan_varargs.c @@ -0,0 +1,10 @@ +// RUN: clang-cc -E %s | grep -F "1: F, (, 'a', 'b', );" && +// RUN: clang-cc -E %s | grep -F "2: 'a' + 'b';" +#define LPAREN ( +#define RPAREN ) +#define F(x, y) x + y +#define ELLIP_FUNC(...) __VA_ARGS__ + +1: ELLIP_FUNC(F, LPAREN, 'a', 'b', RPAREN); /* 1st invocation */ +2: ELLIP_FUNC(F LPAREN 'a', 'b' RPAREN); /* 2nd invocation */ + diff --git a/test/Preprocessor/macro_rparen_scan.c b/test/Preprocessor/macro_rparen_scan.c new file mode 100644 index 0000000..9275098 --- /dev/null +++ b/test/Preprocessor/macro_rparen_scan.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -E %s | grep '^3 ;$' + +/* Right paren scanning, hard case. Should expand to 3. */ +#define i(x) 3 +#define a i(yz +#define b ) +a b ) ; + diff --git a/test/Preprocessor/macro_rparen_scan2.c b/test/Preprocessor/macro_rparen_scan2.c new file mode 100644 index 0000000..41748ac --- /dev/null +++ b/test/Preprocessor/macro_rparen_scan2.c @@ -0,0 +1,8 @@ +// RUN: clang-cc -E %s | grep -F 'static int glob = (1 + 1 );' + +#define R_PAREN ) + +#define FUNC(a) a + +static int glob = (1 + FUNC(1 R_PAREN ); + diff --git a/test/Preprocessor/macro_space.c b/test/Preprocessor/macro_space.c new file mode 100644 index 0000000..4fdbb0a --- /dev/null +++ b/test/Preprocessor/macro_space.c @@ -0,0 +1,5 @@ +// RUN: clang-cc %s -E | grep '! ,' + +#define XX +! XX, + diff --git a/test/Preprocessor/mi_opt.c b/test/Preprocessor/mi_opt.c new file mode 100644 index 0000000..aa69e2b --- /dev/null +++ b/test/Preprocessor/mi_opt.c @@ -0,0 +1,11 @@ +// RUN: not clang-cc -fsyntax-only %s +// PR1900 +// This test should get a redefinition error from m_iopt.h: the MI opt +// shouldn't apply. + +#define MACRO +#include "mi_opt.h" +#undef MACRO +#define MACRO || 1 +#include "mi_opt.h" + diff --git a/test/Preprocessor/mi_opt.h b/test/Preprocessor/mi_opt.h new file mode 100644 index 0000000..a82aa6a --- /dev/null +++ b/test/Preprocessor/mi_opt.h @@ -0,0 +1,4 @@ +#if !defined foo MACRO +#define foo +int x = 2; +#endif diff --git a/test/Preprocessor/objc-pp.m b/test/Preprocessor/objc-pp.m new file mode 100644 index 0000000..4ab2f07 --- /dev/null +++ b/test/Preprocessor/objc-pp.m @@ -0,0 +1,4 @@ +// RUN: clang-cc %s -fsyntax-only -verify -pedantic + +#import <limits.h> // no warning on #import in objc mode. + diff --git a/test/Preprocessor/optimize.c b/test/Preprocessor/optimize.c new file mode 100644 index 0000000..46df2a6 --- /dev/null +++ b/test/Preprocessor/optimize.c @@ -0,0 +1,29 @@ +// RUN: clang-cc -Eonly %s -DOPT_O2 -O2 -verify && +#ifdef OPT_O2 + #ifndef __OPTIMIZE__ + #error "__OPTIMIZE__ not defined" + #endif + #ifdef __OPTIMIZE_SIZE__ + #error "__OPTIMIZE_SIZE__ defined" + #endif +#endif + +// RUN: clang-cc -Eonly %s -DOPT_O0 -O0 -verify && +#ifdef OPT_O0 + #ifdef __OPTIMIZE__ + #error "__OPTIMIZE__ defined" + #endif + #ifdef __OPTIMIZE_SIZE__ + #error "__OPTIMIZE_SIZE__ defined" + #endif +#endif + +// RUN: clang-cc -Eonly %s -DOPT_OS -Os -verify +#ifdef OPT_OS + #ifndef __OPTIMIZE__ + #error "__OPTIMIZE__ not defined" + #endif + #ifdef __OPTIMIZE_SIZE__ + #error "__OPTIMIZE_SIZE__ not defined" + #endif +#endif diff --git a/test/Preprocessor/output_paste_avoid.c b/test/Preprocessor/output_paste_avoid.c new file mode 100644 index 0000000..ff8afc3 --- /dev/null +++ b/test/Preprocessor/output_paste_avoid.c @@ -0,0 +1,23 @@ +// RUN: clang-cc -E %s -o %t && +// This should print as ".. ." to avoid turning into ... +// RUN: grep -F 'A: . . .' %t && +#define y(a) ..a +A: y(.) + +// RUN: grep -F 'C: .. .' %t && +#define DOT . +C: ..DOT + + +// RUN: grep -F 'D: + + - - + + = = =' %t && +#define PLUS + +#define EMPTY +#define f(x) =x= +D: +PLUS -EMPTY- PLUS+ f(=) + +// RUN: grep -F 'E: L "str"' %t + +// Should expand to L "str" not L"str" +#define test(x) L#x +E: test(str) + diff --git a/test/Preprocessor/overflow.c b/test/Preprocessor/overflow.c new file mode 100644 index 0000000..297a35e --- /dev/null +++ b/test/Preprocessor/overflow.c @@ -0,0 +1,25 @@ +// RUN: clang-cc -Eonly %s -verify -triple i686-pc-linux-gnu + +// Multiply signed overflow +#if 0x7FFFFFFFFFFFFFFF*2 // expected-warning {{overflow}} +#endif + +// Multiply unsigned overflow +#if 0xFFFFFFFFFFFFFFFF*2 +#endif + +// Add signed overflow +#if 0x7FFFFFFFFFFFFFFF+1 // expected-warning {{overflow}} +#endif + +// Add unsigned overflow +#if 0xFFFFFFFFFFFFFFFF+1 +#endif + +// Subtract signed overflow +#if 0x7FFFFFFFFFFFFFFF- -1 // expected-warning {{overflow}} +#endif + +// Subtract unsigned overflow +#if 0xFFFFFFFFFFFFFFFF- -1 // expected-warning {{converted from negative value}} +#endif diff --git a/test/Preprocessor/pic.c b/test/Preprocessor/pic.c new file mode 100644 index 0000000..1cddaa1 --- /dev/null +++ b/test/Preprocessor/pic.c @@ -0,0 +1,10 @@ +// RUN: clang -ccc-host-triple i386-unknown-unknown -static -dM -E -o %t %s && +// RUN: grep '#define __PIC__' %t | count 0 && +// RUN: grep '#define __pic__' %t | count 0 && +// RUN: clang -ccc-host-triple i386-unknown-unknown -fpic -dM -E -o %t %s && +// RUN: grep '#define __PIC__ 1' %t | count 1 && +// RUN: grep '#define __pic__ 1' %t | count 1 && +// RUN: clang -ccc-host-triple i386-unknown-unknown -fPIC -dM -E -o %t %s && +// RUN: grep '#define __PIC__ 2' %t | count 1 && +// RUN: grep '#define __pic__ 2' %t | count 1 && +// RUN: true diff --git a/test/Preprocessor/pr2086.c b/test/Preprocessor/pr2086.c new file mode 100644 index 0000000..4df65a4 --- /dev/null +++ b/test/Preprocessor/pr2086.c @@ -0,0 +1,11 @@ +// RUN: clang-cc -E %s + +#define test +#include "pr2086.h" +#define test +#include "pr2086.h" + +#ifdef test +#error +#endif + diff --git a/test/Preprocessor/pr2086.h b/test/Preprocessor/pr2086.h new file mode 100644 index 0000000..b98b996 --- /dev/null +++ b/test/Preprocessor/pr2086.h @@ -0,0 +1,6 @@ +#ifndef test +#endif + +#ifdef test +#undef test +#endif diff --git a/test/Preprocessor/pragma_microsoft.c b/test/Preprocessor/pragma_microsoft.c new file mode 100644 index 0000000..81e90e3 --- /dev/null +++ b/test/Preprocessor/pragma_microsoft.c @@ -0,0 +1,20 @@ +// RUN: clang-cc %s -fsyntax-only -verify -fms-extensions + +// rdar://6495941 + +#define FOO 1 +#define BAR "2" + +#pragma comment(linker,"foo=" FOO) // expected-error {{pragma comment requires parenthesized identifier and optional string}} +#pragma comment(linker," bar=" BAR) + +#pragma comment( user, "Compiled on " __DATE__ " at " __TIME__ ) + +#pragma comment(foo) // expected-error {{unknown kind of pragma comment}} +#pragma comment(compiler,) // expected-error {{pragma comment requires}} +#define foo compiler +#pragma comment(foo) // macro expand kind. +#pragma comment(foo) x // expected-error {{pragma comment requires}} + +#pragma comment(user, "foo\abar\nbaz\tsome thing") + diff --git a/test/Preprocessor/pragma_poison.c b/test/Preprocessor/pragma_poison.c new file mode 100644 index 0000000..d91feb7 --- /dev/null +++ b/test/Preprocessor/pragma_poison.c @@ -0,0 +1,20 @@ +// RUN: clang-cc %s -Eonly -verify + +#pragma GCC poison rindex +rindex(some_string, 'h'); // expected-error {{attempt to use a poisoned identifier}} + +#define BAR _Pragma ("GCC poison XYZW") XYZW /*NO ERROR*/ + XYZW // ok +BAR + XYZW // expected-error {{attempt to use a poisoned identifier}} + +// Pragma poison shouldn't warn from macro expansions defined before the token +// is poisoned. + +#define strrchr rindex2 +#pragma GCC poison rindex2 + +// Can poison multiple times. +#pragma GCC poison rindex2 + +strrchr(some_string, 'h'); // ok. diff --git a/test/Preprocessor/pragma_unknown.c b/test/Preprocessor/pragma_unknown.c new file mode 100644 index 0000000..16bf43b --- /dev/null +++ b/test/Preprocessor/pragma_unknown.c @@ -0,0 +1,28 @@ +// RUN: clang-cc -E %s | grep '#pragma foo bar' && +// RUN: clang-cc -fsyntax-only -Wunknown-pragmas -verify %s + +// GCC doesn't expand macro args for unrecognized pragmas. +#define bar xX +#pragma foo bar // expected-warning {{unknown pragma ignored}} + +#pragma STDC FP_CONTRACT ON +#pragma STDC FP_CONTRACT OFF +#pragma STDC FP_CONTRACT DEFAULT +#pragma STDC FP_CONTRACT IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} + +#pragma STDC FENV_ACCESS ON // expected-warning {{pragma STDC FENV_ACCESS ON is not supported, ignoring pragma}} +#pragma STDC FENV_ACCESS OFF +#pragma STDC FENV_ACCESS DEFAULT +#pragma STDC FENV_ACCESS IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} + +#pragma STDC CX_LIMITED_RANGE ON +#pragma STDC CX_LIMITED_RANGE OFF +#pragma STDC CX_LIMITED_RANGE DEFAULT +#pragma STDC CX_LIMITED_RANGE IN_BETWEEN // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} + +#pragma STDC CX_LIMITED_RANGE // expected-warning {{expected 'ON' or 'OFF' or 'DEFAULT' in pragma}} +#pragma STDC CX_LIMITED_RANGE ON FULL POWER // expected-warning {{expected end of macro in STDC pragma}} + +#pragma STDC SO_GREAT // expected-warning {{unknown pragma in STDC namespace}} +#pragma STDC // expected-warning {{unknown pragma in STDC namespace}} + diff --git a/test/Preprocessor/print_line_track.c b/test/Preprocessor/print_line_track.c new file mode 100644 index 0000000..539433d --- /dev/null +++ b/test/Preprocessor/print_line_track.c @@ -0,0 +1,17 @@ +/* RUN: clang-cc -E %s | grep 'a 3' && + * RUN: clang-cc -E %s | grep 'b 16' && + * RUN: clang-cc -E -P %s | grep 'a 3' && + * RUN: clang-cc -E -P %s | grep 'b 16' && + * RUN: clang-cc -E %s | not grep '# 0 ' + * PR1848 + * PR3437 +*/ + +#define t(x) x + +t(a +3) + +t(b +__LINE__) + diff --git a/test/Preprocessor/skipping_unclean.c b/test/Preprocessor/skipping_unclean.c new file mode 100644 index 0000000..31ce9b4 --- /dev/null +++ b/test/Preprocessor/skipping_unclean.c @@ -0,0 +1,9 @@ +// RUN: clang-cc -E %s | grep bark + +#if 0 +blah +#\ +else +bark +#endif + diff --git a/test/Preprocessor/stringize_misc.c b/test/Preprocessor/stringize_misc.c new file mode 100644 index 0000000..251116a --- /dev/null +++ b/test/Preprocessor/stringize_misc.c @@ -0,0 +1,26 @@ +// RUN: clang-cc -E %s | grep -F '"f(1, 2)" "g((x=y++, y))"' && +// RUN: clang-cc -E %s | grep -F '"{a=1" "b=2;}"' && +// RUN: clang-cc -E %s | grep -F '"<" "["' && +// RUN: clang-cc -E %s | grep -F '"(,)" "(...)"' && +// RUN: clang-cc -E %s | grep -F '{a=1 c=3; b=2;}' && +// RUN: clang-cc -E %s | grep -F '"a COMMA b" "(a, b)"' + +#define M(x, y) #x #y + +M( f(1, 2), g((x=y++, y))) +M( {a=1 , b=2;} ) /* A semicolon is not a comma */ +M( <, [ ) /* Passes the arguments < and [ */ +M( (,), (...) ) /* Passes the arguments (,) and (...) */ + +#define START_END(start, end) start c=3; end + +START_END( {a=1 , b=2;} ) /* braces are not parentheses */ + +/* + * To pass a comma token as an argument it is + * necessary to write: + */ +#define COMMA , + +M(a COMMA b, (a, b)) + diff --git a/test/Preprocessor/stringize_space.c b/test/Preprocessor/stringize_space.c new file mode 100644 index 0000000..e41736c --- /dev/null +++ b/test/Preprocessor/stringize_space.c @@ -0,0 +1,4 @@ +// RUN: clang-cc -E %s | grep -- '-"" , - "" , -"" , - ""' + +#define A(b) -#b , - #b , -# b , - # b +A() diff --git a/test/Preprocessor/stringize_space2.c b/test/Preprocessor/stringize_space2.c new file mode 100644 index 0000000..6a96894 --- /dev/null +++ b/test/Preprocessor/stringize_space2.c @@ -0,0 +1,6 @@ +/* RUN: clang-cc -E %s | grep 'a c' + */ +#define t(x) #x +t(a +c) + diff --git a/test/Preprocessor/undef-error.c b/test/Preprocessor/undef-error.c new file mode 100644 index 0000000..f818e59 --- /dev/null +++ b/test/Preprocessor/undef-error.c @@ -0,0 +1,5 @@ +// RUN: clang-cc %s -pedantic-errors -verify +// PR2045 + +#define b +/* expected-error {{extra tokens at end of #undef directive}} */ #undef a b diff --git a/test/Preprocessor/unterminated.c b/test/Preprocessor/unterminated.c new file mode 100644 index 0000000..2040aac --- /dev/null +++ b/test/Preprocessor/unterminated.c @@ -0,0 +1,5 @@ +// RUN: clang-cc -E -verify %s +// PR3096 +#ifdef FOO // expected-error {{unterminated conditional directive}} +/* /* */ + diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c new file mode 100644 index 0000000..90a717b --- /dev/null +++ b/test/Preprocessor/x86_target_features.c @@ -0,0 +1,35 @@ +// FIXME: Use -triple, not -ccc-host-triple. + +// RUN: clang -ccc-host-triple i386-unknown-unknown -march=core2 -msse4 -x c -E -dM -o %t %s && +// RUN: grep '#define __SSE2_MATH__ 1' %t && +// RUN: grep '#define __SSE2__ 1' %t && +// RUN: grep '#define __SSE3__ 1' %t && +// RUN: grep '#define __SSE4_1__ 1' %t && +// RUN: grep '#define __SSE4_2__ 1' %t && +// RUN: grep '#define __SSE_MATH__ 1' %t && +// RUN: grep '#define __SSE__ 1' %t && +// RUN: grep '#define __SSSE3__ 1' %t && + +// RUN: clang -ccc-host-triple i386-unknown-unknown -march=core2 -msse4 -mno-sse2 -x c -E -dM -o %t %s && +// RUN: grep '#define __SSE2_MATH__ 1' %t | count 0 && +// RUN: grep '#define __SSE2__ 1' %t | count 0 && +// RUN: grep '#define __SSE3__ 1' %t | count 0 && +// RUN: grep '#define __SSE4_1__ 1' %t | count 0 && +// RUN: grep '#define __SSE4_2__ 1' %t | count 0 && +// RUN: grep '#define __SSE_MATH__ 1' %t && +// RUN: grep '#define __SSE__ 1' %t && +// RUN: grep '#define __SSSE3__ 1' %t | count 0 && + +// RUN: clang -ccc-host-triple i386-unknown-unknown -march=pentium-m -x c -E -dM -o %t %s && +// RUN: grep '#define __SSE2_MATH__ 1' %t && +// RUN: grep '#define __SSE2__ 1' %t && +// RUN: grep '#define __SSE3__ 1' %t | count 0 && +// RUN: grep '#define __SSE4_1__ 1' %t | count 0 && +// RUN: grep '#define __SSE4_2__ 1' %t | count 0 && +// RUN: grep '#define __SSE_MATH__ 1' %t && +// RUN: grep '#define __SSE__ 1' %t && +// RUN: grep '#define __SSSE3__ 1' %t | count 0 && + +// RUN: true + + |