Parse the _Thread_local storage-class specifier.

This does not really do anything, because ORCA/C does not support multithreading, but the C11 and later standards indicate it should be allowed anyway.
This commit is contained in:
Stephen Heumann 2022-10-18 18:43:43 -05:00
parent cb5db95476
commit 6d8ca42734
5 changed files with 51 additions and 3 deletions

View File

@ -3139,12 +3139,18 @@ while token.kind in allowedTokens do begin
if doingForLoopClause1 then
if not (myStorageClass in [autosy,registersy]) then
Error(127);
if _Thread_localsy in myDeclarationModifiers then
if not (myStorageClass in [staticsy,externsy]) then
Error(177);
NextToken;
end;
_Thread_localsy: begin
myDeclarationModifiers := myDeclarationModifiers + [token.kind];
Error(139);
if doingParameters then
Error(87);
if not (myStorageClass in [ident,staticsy,externsy]) then
Error(177);
NextToken;
end;
@ -3464,6 +3470,10 @@ while token.kind in allowedTokens do begin
isForwardDeclared := myIsForwardDeclared;
skipDeclarator := mySkipDeclarator;
declSpecifiers.declarationModifiers := myDeclarationModifiers;
if _Thread_localsy in myDeclarationModifiers then
if myStorageClass = ident then
if doingFunction then
Error(177);
if myTypeSpec = nil then begin
myTypeSpec := intPtr; {under C89, default type is int}
if (lint & lintC99Syntax) <> 0 then
@ -3780,6 +3790,8 @@ if isFunction then begin
Error(120);
if alignmentSpecified then
Error(142);
if _Thread_localsy in declSpecifiers.declarationModifiers then
Error(178);
if isPascal then begin {reverse prototyped parameters}
p1 := fnType^.parameterList;
if p1 <> nil then begin

View File

@ -715,7 +715,7 @@ if list or (numErr <> 0) then begin
136: msg := @'complex or imaginary types are not supported by ORCA/C';
137: msg := @'atomic types are not supported by ORCA/C';
138: msg := @'unsupported alignment';
139: msg := @'thread-local storage is not supported by ORCA/C';
{139: msg := @'thread-local storage is not supported by ORCA/C';}
140: msg := @'unexpected token';
141: msg := @'_Noreturn specifier is only allowed on functions';
142: msg := @'_Alignas may not be used in this declaration or type name';
@ -753,6 +753,8 @@ if list or (numErr <> 0) then begin
174: msg := @'''__VA_ARGS__'' may only be used in a variadic macro';
175: msg := @'duplicate macro parameter name';
176: msg := @'declarator expected';
177: msg := @'_Thread_local may not be used with the specified storage class';
178: msg := @'_Thread_local may not appear in a function declaration';
otherwise: Error(57);
end; {case}
writeln(msg^);

View File

@ -31,3 +31,4 @@
{1} c11uchar.c
{1} c11ternary.c
{1} c11anonsu.c
{1} c11thrdlcl.c

View File

@ -0,0 +1,29 @@
/*
* Test _Thread_local (C11).
*/
#include <stdio.h>
extern _Thread_local int i;
char static _Thread_local c = 5;
_Thread_local struct {int x,y,z;} s = {3,6,8};
int main(void) {
_Thread_local int extern j;
static _Thread_local long d = 4567;
d = 123;
i = 14;
if (i+j+c+d+s.x+s.y+s.z != 171)
goto Fail;
printf ("Passed Conformance Test c11thrdlcl\n");
return 0;
Fail:
printf ("Failed Conformance Test c11thrdlcl\n");
}
int _Thread_local i = 9999;
_Thread_local int j = 12;

View File

@ -426,7 +426,7 @@ ORCA/C 2.2.0 adds support for several new C language features. Most are feature
restrict
inline (already treated as a keyword by ORCA/C)
Of these, _Atomic, _Complex, _Imaginary, and _Thread_local are recognized as keywords, but the corresponding language features are not yet supported, so any attempt to use them will produce an error message. The other new keywords are supported, as described below.
Of these, _Atomic, _Complex, and _Imaginary are recognized as keywords, but the corresponding language features are not supported, so any attempt to use them will produce an error message. The other new keywords are supported, as described below.
2. (C99) Statements and declarations may now be mixed within a block; declarations are no longer required to come before statements. The first clause of a for loop statement may also be a declaration (with auto or register storage class only). Variables may only be referred to by name in code syntactically after their declaration, but their lifetime continues as long as control remains in the enclosing block scope, even if it returns to a point before the declaration. Initializers for variables with automatic storage duration are evaluated whenever execution reaches the point where they appear in the code.
@ -579,6 +579,10 @@ Here is an example of a structure containing an anonymous union that in turn con
Members of anonymous structures or unions (including nested ones) may be accessed as if they are members of the containing structure or union. For example, given the declaration above, the expressions s.a, s.b, s.c, and s.d may be used to access the various fields. All the fields must have distinct names.
28. (C11) ORCA/C can now accept the _Thread_local storage-class specifier, which indicates that a variable has thread-local storage. On platforms that support multithreading, there would be a separate copy of the variable for each running thread in the program. ORCA/C does not support multithreading, so the whole execution of an ORCA/C program consists of a single thread, and therefore there is only one copy of each thread-local variable. Accordingly, the _Thread_local storage-class specifier is essentially ignored by ORCA/C, but it may be used in portable code designed to support multithreading on other systems.
The _Thread_local storage-class specifier may be used together with static or extern. This has the normal effect of the other storage-class specifier while also indicating that the variable has thread-local storage. For declarations within a function, _Thread_local must be used together with static or extern.
Multi-Character Character Constants
-----------------------------------