diff --git a/compiler/src/dmd/cparse.d b/compiler/src/dmd/cparse.d index 3ad7ed093c..f3b863c324 100644 --- a/compiler/src/dmd/cparse.d +++ b/compiler/src/dmd/cparse.d @@ -982,6 +982,7 @@ final class CParser(AST) : Parser!AST * sizeof unary-expression * sizeof ( type-name ) * _Alignof ( type-name ) + * _Alignof unary-expression // gcc extension * * unary-operator: * & * + - ~ ! @@ -1044,8 +1045,10 @@ final class CParser(AST) : Parser!AST e = new AST.ComExp(loc, e); break; + case TOK._Alignof: case TOK.sizeof_: { + Identifier id = token.value == TOK.sizeof_? Id.__sizeof : Id.__xalignof; nextToken(); if (token.value == TOK.leftParenthesis) { @@ -1084,7 +1087,7 @@ final class CParser(AST) : Parser!AST e = cparseUnaryExp(); } - e = new AST.DotIdExp(loc, e, Id.__sizeof); + e = new AST.DotIdExp(loc, e, id); break; } @@ -1096,17 +1099,6 @@ final class CParser(AST) : Parser!AST e = cparseCastExp(); break; - case TOK._Alignof: - { - nextToken(); - check(TOK.leftParenthesis); - auto t = cparseTypeName(); - check(TOK.rightParenthesis); - e = new AST.TypeExp(loc, t); - e = new AST.DotIdExp(loc, e, Id.__xalignof); - break; - } - default: e = cparsePostfixExp(e); break; @@ -5025,6 +5017,7 @@ final class CParser(AST) : Parser!AST return false; break; + case TOK._Alignof: case TOK.sizeof_: t = peek(t); if (t.value == TOK.leftParenthesis) @@ -5042,15 +5035,6 @@ final class CParser(AST) : Parser!AST return false; break; - case TOK._Alignof: - t = peek(t); - if (t.value != TOK.leftParenthesis) - return false; - t = peek(t); - if (!isTypeName(t) || t.value != TOK.rightParenthesis) - return false; - break; - default: // Compound literals are handled by cast and sizeof expressions, // so be content with just seeing a primary expression. diff --git a/compiler/src/dmd/expressionsem.d b/compiler/src/dmd/expressionsem.d index 61ef350bde..e5f9e301a2 100644 --- a/compiler/src/dmd/expressionsem.d +++ b/compiler/src/dmd/expressionsem.d @@ -8191,37 +8191,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor if (exp.arrow) // ImportC only exp.e1 = exp.e1.expressionSemantic(sc).arrayFuncConv(sc); - if (exp.ident == Id.__xalignof && exp.e1.isTypeExp()) - { - // C11 6.5.3 says _Alignof only applies to types - Expression e; - Type t; - Dsymbol s; - dmd.typesem.resolve(exp.e1.type, exp.e1.loc, sc, e, t, s, true); - if (e) - { - error(exp.e1.loc, "argument to `_Alignof` must be a type"); - return setError(); - } - else if (t) - { - // Note similarity to getProperty() implementation of __xalignof - const explicitAlignment = t.alignment(); - const naturalAlignment = t.alignsize(); - const actualAlignment = (explicitAlignment.isDefault() ? naturalAlignment : explicitAlignment.get()); - result = new IntegerExp(exp.loc, actualAlignment, Type.tsize_t); - } - else if (s) - { - error(exp.e1.loc, "argument to `_Alignof` must be a type"); - return setError(); - } - else - assert(0); - return; - } - - if (exp.ident != Id.__sizeof) + if (exp.ident != Id.__sizeof && exp.ident != Id.__xalignof) { result = fieldLookup(exp.e1, sc, exp.ident, exp.arrow); return; diff --git a/compiler/test/compilable/alignas.c b/compiler/test/compilable/alignas.c index 1631ab61e2..623a2f8394 100644 --- a/compiler/test/compilable/alignas.c +++ b/compiler/test/compilable/alignas.c @@ -3,10 +3,10 @@ int printf(const char *, ...); _Alignas(4) _Alignas(8) _Alignas(0) int x = 5; -//_Static_assert(_Alignof(x) == 8, "in"); +_Static_assert(_Alignof(x) == 8, "in"); _Alignas(int) short y = 6; -//_Static_assert(_Alignof(y) == 4, "in"); +_Static_assert(_Alignof(y) == 4, "in"); struct S { diff --git a/compiler/test/compilable/testcstuff1.c b/compiler/test/compilable/testcstuff1.c index db0f59058f..5b92f507fd 100644 --- a/compiler/test/compilable/testcstuff1.c +++ b/compiler/test/compilable/testcstuff1.c @@ -329,6 +329,7 @@ void test4(int i) _Static_assert(sizeof 3 == 4, "ok"); _Static_assert(sizeof(3) == 4, "ok"); _Static_assert(_Alignof(int) == 4, "ok"); + _Static_assert(_Alignof 3 == 4, "ok"); _Static_assert((int)3 == 3, "ok"); _Static_assert(sizeof p[0] == 4, "ok"); _Static_assert(1 && 2, "ok"); diff --git a/compiler/test/fail_compilation/test22246.c b/compiler/test/fail_compilation/test22246.c deleted file mode 100644 index ff71913396..0000000000 --- a/compiler/test/fail_compilation/test22246.c +++ /dev/null @@ -1,17 +0,0 @@ -/* TEST_OUTPUT: ---- -fail_compilation/test22246.c(106): Error: argument to `_Alignof` must be a type ---- -*/ - -// https://issues.dlang.org/show_bug.cgi?id=22246 - -#line 100 - -struct S { int m; }; - -int test() -{ - struct S s; - return _Alignof(s); -}