diff options
author | Chris Lattner <sabre@nondot.org> | 2008-10-20 02:05:46 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-10-20 02:05:46 +0000 |
commit | 8ff2c6c9f060b30f31c88d79d76a5c665157cbe3 (patch) | |
tree | 2b5eccdf8f6aaa78fbfcba0423f0e5ef477a0dad /clang/test/Parser/attributes.c | |
parent | 4b13d3f2f22755326ffca491f9478fede0f96fb4 (diff) | |
download | bcm5719-llvm-8ff2c6c9f060b30f31c88d79d76a5c665157cbe3.tar.gz bcm5719-llvm-8ff2c6c9f060b30f31c88d79d76a5c665157cbe3.zip |
Fix a parser bug where we let attributes interfere with our disambiguation
of whether a '(' was a grouping paren or the start of a function declarator.
This is PR2796.
Now we eat the attribute before deciding whether the paren is grouping or
not, then apply it to the resultant decl or to the first argument as needed.
One somewhat surprising aspect of this is that attributes interact with
implicit int in cases like this:
void a(x, y) // k&r style function
void b(__attribute__(()) x, y); // function with two implicit int arguments
void c(x, __attribute__(()) y); // error, can't have attr in identifier list.
Fun stuff.
llvm-svn: 57790
Diffstat (limited to 'clang/test/Parser/attributes.c')
-rw-r--r-- | clang/test/Parser/attributes.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/clang/test/Parser/attributes.c b/clang/test/Parser/attributes.c index 7161d6c22b1..0746517daa5 100644 --- a/clang/test/Parser/attributes.c +++ b/clang/test/Parser/attributes.c @@ -1,6 +1,45 @@ -// RUN: clang -fsyntax-only -verify %s -pedantic +// RUN: clang -fsyntax-only -verify %s -pedantic -std=c99 -static __inline void __attribute__((__always_inline__, __nodebug__)) // expected-warning {{extension used}} -foo (void) -{ +int __attribute__(()) x; // expected-warning {{extension used}} + +// Hide __attribute__ behind a macro, to silence extension warnings about +// "__attribute__ being an extension". +#define attribute __attribute__ + +__inline void attribute((__always_inline__, __nodebug__)) +foo(void) { } + + +attribute(()) y; // expected-warning {{defaults to 'int'}} + +// PR2796 +int (attribute(()) *z)(long y); + + +void f1(attribute(()) int x); + +int f2(y, attribute(()) x); // expected-error {{expected identifier}} + +// This is parsed as a normal argument list (with two args that are implicit +// int) because the attribute is a declspec. +void f3(attribute(()) x, // expected-warning {{defaults to 'int'}} + y); // expected-warning {{defaults to 'int'}} + +void f4(attribute(())); // expected-error {{expected parameter declarator}} + + +// This is ok, the attribute applies to the pointer. +int baz(int (attribute(()) *x)(long y)); + +void g1(void (*f1)(attribute(()) int x)); +void g2(int (*f2)(y, attribute(()) x)); // expected-error {{expected identifier}} +void g3(void (*f3)(attribute(()) x, int y)); // expected-warning {{defaults to 'int'}} +void g4(void (*f4)(attribute(()))); // expected-error {{expected parameter declarator}} + + +void (*h1)(void (*f1)(attribute(()) int x)); +void (*h2)(int (*f2)(y, attribute(()) x)); // expected-error {{expected identifier}} + +void (*h3)(void (*f3)(attribute(()) x)); // expected-warning {{defaults to 'int'}} +void (*h4)(void (*f4)(attribute(()))); // expected-error {{expected parameter declarator}} |