lint: in C23 mode, recognize the keyword 'thread_local'
This commit is contained in:
parent
98b184405d
commit
78e3dd62e3
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: c11.c,v 1.2 2023/07/12 18:26:04 rillig Exp $ */
|
||||
/* $NetBSD: c11.c,v 1.3 2023/07/13 20:30:21 rillig Exp $ */
|
||||
# 3 "c11.c"
|
||||
|
||||
/*
|
||||
|
@ -42,6 +42,12 @@ three_times(void)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
// In C11 mode, 'thread_local' is not yet known, but '_Thread_local' is.
|
||||
/* expect+2: error: old-style declaration; add 'int' [1] */
|
||||
/* expect+1: error: syntax error 'int' [249] */
|
||||
thread_local int thread_local_variable_c23;
|
||||
_Thread_local int thread_local_variable_c11;
|
||||
|
||||
/* The '_Noreturn' must not appear after the declarator. */
|
||||
void _Noreturn exit(int) _Noreturn;
|
||||
/* expect-1: error: formal parameter #1 lacks name [59] */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: c23.c,v 1.1 2023/07/02 23:45:10 rillig Exp $ */
|
||||
/* $NetBSD: c23.c,v 1.2 2023/07/13 20:30:21 rillig Exp $ */
|
||||
# 3 "c23.c"
|
||||
|
||||
// Tests for the option -Ac23, which allows features from C23 and all earlier
|
||||
|
@ -16,7 +16,27 @@ c23(void)
|
|||
int member;
|
||||
} s;
|
||||
|
||||
// Empty initializer braces were introduced in C23.
|
||||
s = (struct s){};
|
||||
s = (struct s){s.member};
|
||||
return s.member;
|
||||
}
|
||||
|
||||
// The keyword 'thread_local' was introduced in C23.
|
||||
thread_local int globally_visible;
|
||||
|
||||
// Thread-local functions don't make sense; they are syntactically allowed,
|
||||
// though.
|
||||
thread_local void
|
||||
thread_local_function(void)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
function(void)
|
||||
{
|
||||
// Not sure whether it makes sense to have a function-scoped
|
||||
// thread-local variable. Don't warn for now, let the compilers handle
|
||||
// this case.
|
||||
thread_local int function_scoped_thread_local;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: decl.c,v 1.352 2023/07/13 19:59:08 rillig Exp $ */
|
||||
/* $NetBSD: decl.c,v 1.353 2023/07/13 20:30:21 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID)
|
||||
__RCSID("$NetBSD: decl.c,v 1.352 2023/07/13 19:59:08 rillig Exp $");
|
||||
__RCSID("$NetBSD: decl.c,v 1.353 2023/07/13 20:30:21 rillig Exp $");
|
||||
#endif
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -1514,7 +1514,8 @@ declarator_name(sym_t *sym)
|
|||
*/
|
||||
sc = AUTO;
|
||||
sym->s_def = DEF;
|
||||
} else if (sc == AUTO || sc == STATIC || sc == TYPEDEF)
|
||||
} else if (sc == AUTO || sc == STATIC || sc == TYPEDEF
|
||||
|| sc == THREAD_LOCAL)
|
||||
sym->s_def = DEF;
|
||||
else if (sc == REG) {
|
||||
sym->s_register = true;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: lex.c,v 1.183 2023/07/13 19:59:08 rillig Exp $ */
|
||||
/* $NetBSD: lex.c,v 1.184 2023/07/13 20:30:21 rillig Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include <sys/cdefs.h>
|
||||
#if defined(__RCSID)
|
||||
__RCSID("$NetBSD: lex.c,v 1.183 2023/07/13 19:59:08 rillig Exp $");
|
||||
__RCSID("$NetBSD: lex.c,v 1.184 2023/07/13 20:30:21 rillig Exp $");
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
@ -68,18 +68,22 @@ bool in_gcc_attribute;
|
|||
bool in_system_header;
|
||||
|
||||
/*
|
||||
* Valid values for 'since' are 78, 90, 99, 11.
|
||||
* Valid values for 'since' are 78, 90, 99, 11, 23.
|
||||
*
|
||||
* The C11 keywords are added in C99 mode as well, to provide good error
|
||||
* messages instead of a simple parse error. If the keyword '_Generic' were
|
||||
* not defined, it would be interpreted as an implicit function call, leading
|
||||
* to a parse error.
|
||||
* The C11 keywords are all taken from the reserved namespace. They are added
|
||||
* in C99 mode as well, to make the parse error messages more useful. For
|
||||
* example, if the keyword '_Generic' were not defined, it would be interpreted
|
||||
* as an implicit function call, leading to a parse error.
|
||||
*
|
||||
* The C23 keywords are not made available in earlier modes, as they may
|
||||
* conflict with user-defined identifiers.
|
||||
*/
|
||||
#define kwdef(name, token, detail, since, gcc, deco) \
|
||||
{ \
|
||||
{ /* CONSTCOND */ \
|
||||
name, token, detail, \
|
||||
(since) == 90, \
|
||||
/* CONSTCOND */ (since) == 99 || (since) == 11, \
|
||||
(since) == 99 || (since) == 11, \
|
||||
(since) == 23, \
|
||||
(gcc) > 0, \
|
||||
((deco) & 1) != 0, ((deco) & 2) != 0, ((deco) & 4) != 0, \
|
||||
}
|
||||
|
@ -107,8 +111,9 @@ static const struct keyword {
|
|||
function_specifier kw_fs; /* if kw_token is
|
||||
* T_FUNCTION_SPECIFIER */
|
||||
} u;
|
||||
bool kw_c90:1; /* available in C90 mode */
|
||||
bool kw_c99_or_c11:1; /* available in C99 or C11 mode */
|
||||
bool kw_added_in_c90:1;
|
||||
bool kw_added_in_c99_or_c11:1;
|
||||
bool kw_added_in_c23:1;
|
||||
bool kw_gcc:1; /* available in GCC mode */
|
||||
bool kw_plain:1; /* 'name' */
|
||||
bool kw_leading:1; /* '__name' */
|
||||
|
@ -164,6 +169,7 @@ static const struct keyword {
|
|||
kwdef_token( "__symbolrename", T_SYMBOLRENAME, 78,0,1),
|
||||
kwdef_sclass( "__thread", THREAD_LOCAL, 78,1,1),
|
||||
kwdef_sclass( "_Thread_local", THREAD_LOCAL, 11,0,1),
|
||||
kwdef_sclass( "thread_local", THREAD_LOCAL, 23,0,1),
|
||||
kwdef_sclass( "typedef", TYPEDEF, 78,0,1),
|
||||
kwdef_token( "typeof", T_TYPEOF, 78,1,7),
|
||||
#ifdef INT128_SIZE
|
||||
|
@ -364,7 +370,9 @@ static bool
|
|||
is_keyword_known(const struct keyword *kw)
|
||||
{
|
||||
|
||||
if ((kw->kw_c90 || kw->kw_c99_or_c11) && !allow_c90)
|
||||
if (kw->kw_added_in_c23 && !allow_c23)
|
||||
return false;
|
||||
if ((kw->kw_added_in_c90 || kw->kw_added_in_c99_or_c11) && !allow_c90)
|
||||
return false;
|
||||
|
||||
/*
|
||||
|
@ -378,7 +386,7 @@ is_keyword_known(const struct keyword *kw)
|
|||
if (kw->kw_gcc)
|
||||
return false;
|
||||
|
||||
if (kw->kw_c99_or_c11 && !allow_c99)
|
||||
if (kw->kw_added_in_c99_or_c11 && !allow_c99)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue