summaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-12 17:38:47 +0000
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>2013-11-12 17:38:47 +0000
commitd184e0c062dd6ac5543bc579372874c1109a2f8e (patch)
treedc4dfcb336fe8a6bf6fab451a6d9be16fbe15ec3 /gcc/c
parent53e4a58f546ed712282469b7dd46f16eba7eb570 (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/c/c-decl.c47
-rw-r--r--gcc/c/c-parser.c3
-rw-r--r--gcc/c/c-tree.h4
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. */