diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-12 17:38:47 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-11-12 17:38:47 +0000 |
commit | d184e0c062dd6ac5543bc579372874c1109a2f8e (patch) | |
tree | dc4dfcb336fe8a6bf6fab451a6d9be16fbe15ec3 /gcc/c | |
parent | 53e4a58f546ed712282469b7dd46f16eba7eb570 (diff) | |
download | gcc-d184e0c062dd6ac5543bc579372874c1109a2f8e.tar.gz |
c-family:
* c-common.c (c_common_reswords): Add _Thread_local.
c:
* c-tree.h (struct c_declspecs): Add thread_gnu_p field.
* c-parser.c (c_parser_declspecs): Mention _Thread_local in
comment.
* c-decl.c (shadow_tag_warned, grokdeclarator): Mention __thread
or _Thread_local as appropriate in diagnostics.
(build_null_declspecs): Initialize ret->thread_gnu_p.
(declspecs_add_scspec): Handle either __thread or _Thread_local
for RID_THREAD. Diagnose _Thread_local for pre-C11 standards if
pedantic. Do not disallow _Thread_local extern and _Thread_local
static.
testsuite:
* gcc.dg/c90-thread-local-1.c, gcc.dg/c99-thread-local-1.c,
gcc.dg/c11-thread-local-1.c, gcc.dg/c11-thread-local-2.c: New
tests.
* gcc.dg/tls/diag-2.c, objc.dg/tls/diag-2.m: Update expected
diagnostics.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@204711 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 47 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 3 | ||||
-rw-r--r-- | gcc/c/c-tree.h | 4 |
4 files changed, 55 insertions, 12 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index e38bcb8cdbd..1cf5883c848 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,16 @@ +2013-11-12 Joseph Myers <joseph@codesourcery.com> + + * c-tree.h (struct c_declspecs): Add thread_gnu_p field. + * c-parser.c (c_parser_declspecs): Mention _Thread_local in + comment. + * c-decl.c (shadow_tag_warned, grokdeclarator): Mention __thread + or _Thread_local as appropriate in diagnostics. + (build_null_declspecs): Initialize ret->thread_gnu_p. + (declspecs_add_scspec): Handle either __thread or _Thread_local + for RID_THREAD. Diagnose _Thread_local for pre-C11 standards if + pedantic. Do not disallow _Thread_local extern and _Thread_local + static. + 2013-11-07 Joseph Myers <joseph@codesourcery.com> Andrew MacLeod <amacleod@redhat.com> diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 9520e4d2d6e..6fe418e9e4c 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -3805,7 +3805,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned) if (!warned && !in_system_header && declspecs->thread_p) { - warning (0, "useless %<__thread%> in empty declaration"); + warning (0, "useless %qs in empty declaration", + declspecs->thread_gnu_p ? "__thread" : "_Thread_local"); warned = 2; } @@ -5164,7 +5165,8 @@ grokdeclarator (const struct c_declarator *declarator, if (storage_class == csc_typedef) error_at (loc, "function definition declared %<typedef%>"); if (threadp) - error_at (loc, "function definition declared %<__thread%>"); + error_at (loc, "function definition declared %qs", + declspecs->thread_gnu_p ? "__thread" : "_Thread_local"); threadp = false; if (storage_class == csc_auto || storage_class == csc_register @@ -5233,8 +5235,8 @@ grokdeclarator (const struct c_declarator *declarator, else if (threadp && storage_class == csc_none) { error_at (loc, "function-scope %qE implicitly auto and declared " - "%<__thread%>", - name); + "%qs", name, + declspecs->thread_gnu_p ? "__thread" : "_Thread_local"); threadp = false; } } @@ -8980,6 +8982,7 @@ build_null_declspecs (void) ret->inline_p = false; ret->noreturn_p = false; ret->thread_p = false; + ret->thread_gnu_p = false; ret->const_p = false; ret->volatile_p = false; ret->atomic_p = false; @@ -9773,14 +9776,29 @@ declspecs_add_scspec (source_location loc, case RID_THREAD: dupe = specs->thread_p; if (specs->storage_class == csc_auto) - error ("%<__thread%> used with %<auto%>"); + error ("%qE used with %<auto%>", scspec); else if (specs->storage_class == csc_register) - error ("%<__thread%> used with %<register%>"); + error ("%qE used with %<register%>", scspec); else if (specs->storage_class == csc_typedef) - error ("%<__thread%> used with %<typedef%>"); + error ("%qE used with %<typedef%>", scspec); else { specs->thread_p = true; + specs->thread_gnu_p = (strcmp (IDENTIFIER_POINTER (scspec), + "__thread") == 0); + /* A diagnostic is not required for the use of this + identifier in the implementation namespace; only diagnose + it for the C11 spelling because of existing code using + the other spelling. */ + if (!flag_isoc11 && !specs->thread_gnu_p) + { + if (flag_isoc99) + pedwarn (loc, OPT_Wpedantic, + "ISO C99 does not support %qE", scspec); + else + pedwarn (loc, OPT_Wpedantic, + "ISO C90 does not support %qE", scspec); + } specs->locations[cdw_thread] = loc; } break; @@ -9790,7 +9808,7 @@ declspecs_add_scspec (source_location loc, case RID_EXTERN: n = csc_extern; /* Diagnose "__thread extern". */ - if (specs->thread_p) + if (specs->thread_p && specs->thread_gnu_p) error ("%<__thread%> before %<extern%>"); break; case RID_REGISTER: @@ -9799,7 +9817,7 @@ declspecs_add_scspec (source_location loc, case RID_STATIC: n = csc_static; /* Diagnose "__thread static". */ - if (specs->thread_p) + if (specs->thread_p && specs->thread_gnu_p) error ("%<__thread%> before %<static%>"); break; case RID_TYPEDEF: @@ -9811,7 +9829,12 @@ declspecs_add_scspec (source_location loc, if (n != csc_none && n == specs->storage_class) dupe = true; if (dupe) - error ("duplicate %qE", scspec); + { + if (i == RID_THREAD) + error ("duplicate %<_Thread_local%> or %<__thread%>"); + else + error ("duplicate %qE", scspec); + } if (n != csc_none) { if (specs->storage_class != csc_none && n != specs->storage_class) @@ -9824,7 +9847,9 @@ declspecs_add_scspec (source_location loc, specs->locations[cdw_storage_class] = loc; if (n != csc_extern && n != csc_static && specs->thread_p) { - error ("%<__thread%> used with %qE", scspec); + error ("%qs used with %qE", + specs->thread_gnu_p ? "__thread" : "_Thread_local", + scspec); specs->thread_p = false; } } diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index 09cce1c0924..5b4665a2a8d 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1969,6 +1969,9 @@ c_parser_static_assert_declaration_no_semi (c_parser *parser) static auto register + _Thread_local + + (_Thread_local is new in C11.) C99 6.7.4: function-specifier: diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 8dffa9c1674..502fdca4d7e 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -320,8 +320,10 @@ struct c_declspecs { BOOL_BITFIELD inline_p : 1; /* Whether "_Noreturn" was speciied. */ BOOL_BITFIELD noreturn_p : 1; - /* Whether "__thread" was specified. */ + /* Whether "__thread" or "_Thread_local" was specified. */ BOOL_BITFIELD thread_p : 1; + /* Whether "__thread" rather than "_Thread_local" was specified. */ + BOOL_BITFIELD thread_gnu_p : 1; /* Whether "const" was specified. */ BOOL_BITFIELD const_p : 1; /* Whether "volatile" was specified. */ |