mirror of
https://github.com/mirror/tinycc.git
synced 2025-02-24 07:50:12 +08:00
Fix _Alignas
* don't accept _Alignas as type qualifier (after pointer '*'). * accept type-names within _Alignas * add testcases
This commit is contained in:
parent
fa0ef91a24
commit
38a6aba468
45
tccgen.c
45
tccgen.c
@ -4176,20 +4176,25 @@ static int parse_btype(CType *type, AttributeDef *ad)
|
|||||||
goto basic_type;
|
goto basic_type;
|
||||||
case TOK_ALIGNAS:
|
case TOK_ALIGNAS:
|
||||||
{ int n;
|
{ int n;
|
||||||
next();
|
AttributeDef ad1;
|
||||||
/* TODO: _Alignas(type) -> _Alignas(_Alignof(type)) */
|
next();
|
||||||
if (tok == '(') {
|
skip('(');
|
||||||
next();
|
memset(&ad1, 0, sizeof(AttributeDef));
|
||||||
n = expr_const();
|
if (parse_btype(&type1, &ad1)) {
|
||||||
if (n <= 0 || (n & (n - 1)) != 0)
|
type_decl(&type1, &ad1, &n, TYPE_ABSTRACT);
|
||||||
|
if (ad1.a.aligned)
|
||||||
|
n = 1 << (ad1.a.aligned - 1);
|
||||||
|
else
|
||||||
|
type_size(&type1, &n);
|
||||||
|
} else {
|
||||||
|
n = expr_const();
|
||||||
|
if (n <= 0 || (n & (n - 1)) != 0)
|
||||||
tcc_error("alignment must be a positive power of two");
|
tcc_error("alignment must be a positive power of two");
|
||||||
skip(')');
|
}
|
||||||
} else {
|
skip(')');
|
||||||
expect("(");
|
ad->a.aligned = exact_log2p1(n);
|
||||||
}
|
}
|
||||||
ad->a.aligned = exact_log2p1(n);
|
continue;
|
||||||
}
|
|
||||||
continue;
|
|
||||||
case TOK_LONG:
|
case TOK_LONG:
|
||||||
if ((t & VT_BTYPE) == VT_DOUBLE) {
|
if ((t & VT_BTYPE) == VT_DOUBLE) {
|
||||||
t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
|
t = (t & ~(VT_BTYPE|VT_LONG)) | VT_LDOUBLE;
|
||||||
@ -4594,22 +4599,6 @@ static CType *type_decl(CType *type, AttributeDef *ad, int *v, int td)
|
|||||||
case TOK_RESTRICT2:
|
case TOK_RESTRICT2:
|
||||||
case TOK_RESTRICT3:
|
case TOK_RESTRICT3:
|
||||||
goto redo;
|
goto redo;
|
||||||
case TOK_ALIGNAS:
|
|
||||||
{ int n;
|
|
||||||
next();
|
|
||||||
/* TODO: _Alignas(type) -> _Alignas(_Alignof(type)) */
|
|
||||||
if (tok == '(') {
|
|
||||||
next();
|
|
||||||
n = expr_const();
|
|
||||||
if (n <= 0 || (n & (n - 1)) != 0)
|
|
||||||
tcc_error("alignment must be a positive power of two");
|
|
||||||
skip(')');
|
|
||||||
} else {
|
|
||||||
expect("(");
|
|
||||||
}
|
|
||||||
ad->a.aligned = exact_log2p1(n);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
/* XXX: clarify attribute handling */
|
/* XXX: clarify attribute handling */
|
||||||
case TOK_ATTRIBUTE1:
|
case TOK_ATTRIBUTE1:
|
||||||
case TOK_ATTRIBUTE2:
|
case TOK_ATTRIBUTE2:
|
||||||
|
28
tests/tests2/102_alignas.c
Normal file
28
tests/tests2/102_alignas.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
_Alignas(16) int i1;
|
||||||
|
int _Alignas(16) i2;
|
||||||
|
void _Alignas(16) *p2;
|
||||||
|
_Alignas(16) i3;
|
||||||
|
int _Alignas(double) i4;
|
||||||
|
int _Alignas(int) i5;
|
||||||
|
#if 0
|
||||||
|
/* The following are currently wrongly accepted by TCC but really shouldn't. */
|
||||||
|
int _Alignas(int _Alignas(16)) i6; //wrong, 'int _Alignas(16)' is no type-name
|
||||||
|
typedef int _Alignas(16) int16aligned_t; //wrong, _Alignas invalid on typedef
|
||||||
|
int16aligned_t i7;
|
||||||
|
#endif
|
||||||
|
/* i8 should get an alignment of 16, because unlike _Alignas the
|
||||||
|
corresponding attribute _does_ apply to type-name, though not in
|
||||||
|
some clang versions. */
|
||||||
|
int _Alignas(int __attribute__((aligned(16)))) i8;
|
||||||
|
extern int printf(const char*, ...);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define alignof(x) (int)__alignof(x)
|
||||||
|
#else
|
||||||
|
#define alignof(x) (int)__alignof__(x)
|
||||||
|
#endif
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
printf("%d %d %d %d\n",
|
||||||
|
alignof(i1), alignof(i4), alignof(i5), alignof(i8));
|
||||||
|
return 0;
|
||||||
|
}
|
1
tests/tests2/102_alignas.expect
Normal file
1
tests/tests2/102_alignas.expect
Normal file
@ -0,0 +1 @@
|
|||||||
|
16 8 4
|
@ -172,4 +172,7 @@ int X=1;
|
|||||||
int main(void) {
|
int main(void) {
|
||||||
int t[][][X];
|
int t[][][X];
|
||||||
}
|
}
|
||||||
|
#elif defined test_invalid_alignas
|
||||||
|
/* _Alignas is no type qualifier */
|
||||||
|
void * _Alignas(16) p1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -80,3 +80,6 @@
|
|||||||
|
|
||||||
[test_vla_1]
|
[test_vla_1]
|
||||||
60_errors_and_warnings.c:173: error: need explicit inner array size in VLAs
|
60_errors_and_warnings.c:173: error: need explicit inner array size in VLAs
|
||||||
|
|
||||||
|
[test_invalid_alignas]
|
||||||
|
60_errors_and_warnings.c:177: error: identifier expected
|
||||||
|
Loading…
Reference in New Issue
Block a user