do
nxt_token = cpp_peek_token (pfile, idx++);
while (nxt_token->type == CPP_PADDING);
- if (nxt_token->type == CPP_SCOPE)
+ if (!c_dialect_cxx ()
+ && nxt_token->type == CPP_COLON
+ && (nxt_token->flags & COLON_SCOPE) != 0)
+ {
+ const cpp_token *prev_token = nxt_token;
+ do
+ nxt_token = cpp_peek_token (pfile, idx++);
+ while (nxt_token->type == CPP_PADDING);
+ if (nxt_token->type == CPP_COLON)
+ {
+ /* __has_attribute (vendor::attr) in -std=c17 etc. modes.
+ :: isn't CPP_SCOPE but 2 CPP_COLON tokens, where the
+ first one should have COLON_SCOPE flag to distinguish
+ it from : :. */
+ have_scope = true;
+ get_token_no_padding (pfile); // Eat first colon.
+ }
+ else
+ nxt_token = prev_token;
+ }
+ if (nxt_token->type == CPP_SCOPE || have_scope)
{
have_scope = true;
get_token_no_padding (pfile); // Eat scope.
indicates whether this relaxation is in effect. */
static tree
-c_parser_std_attribute (c_parser *parser, bool for_tm,
- bool loose_scope_p = false)
+c_parser_std_attribute (c_parser *parser, bool for_tm)
{
c_token *token = c_parser_peek_token (parser);
tree ns, name, attribute;
name = canonicalize_attr_name (token->value);
c_parser_consume_token (parser);
if (c_parser_next_token_is (parser, CPP_SCOPE)
- || (loose_scope_p
- && c_parser_next_token_is (parser, CPP_COLON)
+ || (c_parser_next_token_is (parser, CPP_COLON)
+ && (c_parser_peek_token (parser)->flags & COLON_SCOPE) != 0
&& c_parser_peek_2nd_token (parser)->type == CPP_COLON))
{
ns = name;
}
static tree
-c_parser_std_attribute_list (c_parser *parser, bool for_tm,
- bool loose_scope_p = false)
+c_parser_std_attribute_list (c_parser *parser, bool for_tm)
{
tree attributes = NULL_TREE;
while (true)
c_parser_consume_token (parser);
continue;
}
- tree attribute = c_parser_std_attribute (parser, for_tm, loose_scope_p);
+ tree attribute = c_parser_std_attribute (parser, for_tm);
if (attribute != error_mark_node)
{
TREE_CHAIN (attribute) = attributes;
{
auto ext = disable_extension_diagnostics ();
c_parser_consume_token (parser);
- attributes = c_parser_std_attribute_list (parser, for_tm, true);
+ attributes = c_parser_std_attribute_list (parser, for_tm);
restore_extension_diagnostics (ext);
}
else
@end smallexample
suppresses warnings about using @samp{[[]]} attributes in C versions
-that predate C23@. Since the scope token @samp{::} is not a single
-lexing token in earlier versions of C, this construct also allows two colons
-to be used in place of @code{::}. GCC does not check whether the two
-colons are immediately adjacent.
+that predate C23@.
@end itemize
@code{__extension__} has no effect aside from this.
typedef int [[__extension__ gnu::vector_size (4)]] g1;
typedef int [[__extension__ gnu :: vector_size (4)]] g2;
-typedef int [[__extension__ gnu : : vector_size (4)]] g3;
-typedef int [[__extension__ gnu: :vector_size (4)]] g4;
-typedef int [[__extension__ gnu FOO vector_size (4)]] g5;
-typedef int [[__extension__ gnu BAR BAR vector_size (4)]] g6;
-typedef int [[__extension__ gnu :/**/: vector_size (4)]] g7;
-typedef int [[__extension__ gnu JOIN(:,:) vector_size (4)]] g8;
-typedef int [[__extension__ gnu :: vector_size (sizeof (void (*)(...)))]] g10;
-typedef int [[__extension__]] g11;
-typedef int [[__extension__,]] g12;
-typedef int [[__extension__, ,,,, ,, ,]] g13;
-[[__extension__ deprecated]] int g14 ();
-[[__extension__ nodiscard]] int g15 ();
-[[__extension__ noreturn]] void g16 ();
+typedef int [[__extension__ gnu FOO vector_size (4)]] g3;
+typedef int [[__extension__ gnu :: vector_size (sizeof (void (*)(...)))]] g4;
+typedef int [[__extension__]] g5;
+typedef int [[__extension__,]] g6;
+typedef int [[__extension__, ,,,, ,, ,]] g7;
+[[__extension__ deprecated]] int g8 ();
+[[__extension__ nodiscard]] int g9 ();
+[[__extension__ noreturn]] void g10 ();
int
cases (int x)
typedef int [[__extension__ gnu:vector_size(4)]] b4; /* { dg-error {expected '\]' before ':'} } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
typedef int [[__extension__ gnu JOIN2(:,:) vector_size (4)]] b5; /* { dg-error {pasting ":" and ":" does not give a valid preprocessing token} } */
-typedef int [[gnu::vector_size(4)]] b6; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {expected '\]' before ':'} "" { target *-*-* } .-1 } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-2 } */
+typedef int [[__extension__ gnu : : vector_size (4)]] b6; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[__extension__ gnu: :vector_size (4)]] b7; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[__extension__ gnu BAR BAR vector_size (4)]] b8; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[__extension__ gnu :/**/: vector_size (4)]] b9; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[__extension__ gnu JOIN(:,:) vector_size (4)]] b10; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[gnu::vector_size(4)]] b11; /* { dg-error {attributes before C23} } */
+typedef int [[gnu : : vector_size(4)]] b12; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu : vector_size(4)]] b13; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu: :vector_size (4)]] b14; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu BAR BAR vector_size (4)]] b15; /* { dg-error {expected '\]' before ':'} } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */
-typedef int [[gnu : : vector_size(4)]] b7; /* { dg-error {expected '\]' before ':'} } */
+typedef int [[gnu :/**/: vector_size (4)]] b16; /* { dg-error {expected '\]' before ':'} } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */
-typedef int [[gnu : vector_size(4)]] b8; /* { dg-error {expected '\]' before ':'} } */
+typedef int [[gnu JOIN(:,:) vector_size (4)]] b17; /* { dg-error {expected '\]' before ':'} } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
/* { dg-error {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu :: vector_size (4)]] b18; /* { dg-error {attributes before C23} } */
+typedef int [[gnu FOO vector_size (4)]] b19; /* { dg-error {attributes before C23} } */
+typedef int [[gnu :: vector_size (sizeof (void (*)(...)))]] b20; /* { dg-error {attributes before C23} } */
+/* { dg-error {requires a named argument before} "" { target *-*-* } .-1 } */
+typedef int [[gnu JOIN2(:,:) vector_size (4)]] b21; /* { dg-error {pasting ":" and ":" does not give a valid preprocessing token} } */
+/* { dg-error {expected '\]' before ':'} "" { target *-*-* } .-1 } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-2 } */
+/* { dg-error {attributes before C23} "" { target *-*-* } .-3 } */
typedef int [[__extension__ gnu::vector_size (4)]] g1;
typedef int [[__extension__ gnu :: vector_size (4)]] g2;
-typedef int [[__extension__ gnu : : vector_size (4)]] g3;
-typedef int [[__extension__ gnu: :vector_size (4)]] g4;
-typedef int [[__extension__ gnu FOO vector_size (4)]] g5;
-typedef int [[__extension__ gnu BAR BAR vector_size (4)]] g6;
-typedef int [[__extension__ gnu :/**/: vector_size (4)]] g7;
-typedef int [[__extension__ gnu JOIN(:,:) vector_size (4)]] g8;
-typedef int [[__extension__ gnu :: vector_size (sizeof (void (*)(...)))]] g10;
-typedef int [[__extension__]] g11;
-typedef int [[__extension__,]] g12;
-typedef int [[__extension__, ,,,, ,, ,]] g13;
-[[__extension__ deprecated]] int g14 ();
-[[__extension__ nodiscard]] int g15 ();
-[[__extension__ noreturn]] void g16 ();
+typedef int [[__extension__ gnu FOO vector_size (4)]] g3;
+typedef int [[__extension__ gnu :: vector_size (sizeof (void (*)(...)))]] g4;
+typedef int [[__extension__]] g5;
+typedef int [[__extension__,]] g6;
+typedef int [[__extension__, ,,,, ,, ,]] g7;
+[[__extension__ deprecated]] int g8 ();
+[[__extension__ nodiscard]] int g9 ();
+[[__extension__ noreturn]] void g10 ();
int
cases (int x)
typedef int [[__extension__ gnu:vector_size(4)]] b4; /* { dg-error {expected '\]' before ':'} } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
typedef int [[__extension__ gnu JOIN2(:,:) vector_size (4)]] b5;
-typedef int [[gnu::vector_size(4)]] b6; /* { dg-warning {attributes before C23} } */
-typedef int [[gnu : : vector_size(4)]] b7; /* { dg-error {expected '\]' before ':'} } */
+typedef int [[__extension__ gnu : : vector_size (4)]] b6; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[__extension__ gnu: :vector_size (4)]] b7; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[__extension__ gnu BAR BAR vector_size (4)]] b8; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[__extension__ gnu :/**/: vector_size (4)]] b9; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[__extension__ gnu JOIN(:,:) vector_size (4)]] b10; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+typedef int [[gnu::vector_size(4)]] b11; /* { dg-warning {attributes before C23} } */
+typedef int [[gnu : : vector_size(4)]] b12; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu : vector_size(4)]] b13; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu: :vector_size (4)]] b14; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu BAR BAR vector_size (4)]] b15; /* { dg-error {expected '\]' before ':'} } */
+/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
+/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu :/**/: vector_size (4)]] b16; /* { dg-error {expected '\]' before ':'} } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */
-typedef int [[gnu : vector_size(4)]] b8; /* { dg-error {expected '\]' before ':'} } */
+typedef int [[gnu JOIN(:,:) vector_size (4)]] b17; /* { dg-error {expected '\]' before ':'} } */
/* { dg-error {'gnu' attribute ignored} "" { target *-*-* } .-1 } */
/* { dg-warning {attributes before C23} "" { target *-*-* } .-2 } */
+typedef int [[gnu :: vector_size (4)]] b18; /* { dg-warning {attributes before C23} } */
+typedef int [[gnu FOO vector_size (4)]] b19; /* { dg-warning {attributes before C23} } */
+typedef int [[gnu :: vector_size (sizeof (void (*)(...)))]] b20; /* { dg-warning {attributes before C23} } */
+/* { dg-warning {requires a named argument before} "" { target *-*-* } .-1 } */
+typedef int [[gnu JOIN2(:,:) vector_size (4)]] b21; /* { dg-warning {attributes before C23} } */
--- /dev/null
+/* PR c/114007 */
+/* { dg-do compile } */
+/* { dg-options "-std=c11" } */
+
+#if __has_c_attribute (gnu::unused)
+[[gnu::unused]]
+#endif
+int i;
+#if __has_cpp_attribute (gnu::unused)
+[[gnu::unused]]
+#endif
+int j;
#define DECIMAL_INT (1 << 6) /* Decimal integer, set in c-lex.cc. */
#define PURE_ZERO (1 << 7) /* Single 0 digit, used by the C++ frontend,
set in c-lex.cc. */
+#define COLON_SCOPE PURE_ZERO /* Adjacent colons in C < 23. */
#define SP_DIGRAPH (1 << 8) /* # or ## token was a digraph. */
#define SP_PREV_WHITE (1 << 9) /* If whitespace before a ##
operator, or before this token
case ':':
result->type = CPP_COLON;
- if (*buffer->cur == ':' && CPP_OPTION (pfile, scope))
- buffer->cur++, result->type = CPP_SCOPE;
+ if (*buffer->cur == ':')
+ {
+ if (CPP_OPTION (pfile, scope))
+ buffer->cur++, result->type = CPP_SCOPE;
+ else
+ result->flags |= COLON_SCOPE;
+ }
else if (*buffer->cur == '>' && CPP_OPTION (pfile, digraphs))
{
buffer->cur++;