aboutsummaryrefslogtreecommitdiff
path: root/gcc/c/c-decl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/c/c-decl.cc')
-rw-r--r--gcc/c/c-decl.cc20
1 files changed, 17 insertions, 3 deletions
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 945e45b..b5b491c 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -2442,8 +2442,20 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
return false;
}
- /* Multiple initialized definitions are not allowed (6.9p3,5). */
- if (DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl))
+ /* Multiple initialized definitions are not allowed (6.9p3,5).
+ For this purpose, C2x makes it clear that thread-local
+ declarations without extern are definitions, not tentative
+ definitions, whether or not they have initializers. The
+ wording before C2x was unclear; literally it would have made
+ uninitialized thread-local declarations into tentative
+ definitions only if they also used static, but without saying
+ explicitly whether or not other cases count as
+ definitions at all. */
+ if ((DECL_INITIAL (newdecl) && DECL_INITIAL (olddecl))
+ || (flag_isoc2x
+ && DECL_THREAD_LOCAL_P (newdecl)
+ && !DECL_EXTERNAL (newdecl)
+ && !DECL_EXTERNAL (olddecl)))
{
auto_diagnostic_group d;
error ("redefinition of %q+D", newdecl);
@@ -5714,10 +5726,12 @@ finish_decl (tree decl, location_t init_loc, tree init,
/* A static variable with an incomplete type
is an error if it is initialized.
Also if it is not file scope.
+ Also if it is thread-local (in C2x).
Otherwise, let it through, but if it is not `extern'
then it may cause an error message later. */
? (DECL_INITIAL (decl) != NULL_TREE
- || !DECL_FILE_SCOPE_P (decl))
+ || !DECL_FILE_SCOPE_P (decl)
+ || (flag_isoc2x && DECL_THREAD_LOCAL_P (decl)))
/* An automatic variable with an incomplete type
is an error. */
: !DECL_EXTERNAL (decl)))