Skip to content

Commit 9cd58ff

Browse files
committed
offsetof like macro is now constant expression
1 parent a7cdd03 commit 9cd58ff

10 files changed

Lines changed: 111026 additions & 110703 deletions

File tree

src/cakeconfig.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
//This was generated by running cake -autoconfig
22
//This file was generated reading the variable INCLUDE inside Visual Studio Command Prompt.
33
//echo %INCLUDE%
4-
#pragma dir "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/include/"
5-
#pragma dir "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.44.35207/ATLMFC/include/"
6-
#pragma dir "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Auxiliary/VS/include/"
4+
#pragma dir "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.44.35207/include/"
5+
#pragma dir "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Tools/MSVC/14.44.35207/ATLMFC/include/"
6+
#pragma dir "C:/Program Files/Microsoft Visual Studio/2022/Professional/VC/Auxiliary/VS/include/"
77
#pragma dir "C:/Program Files (x86)/Windows Kits/10/include/10.0.26100.0/ucrt/"
88
#pragma dir "C:/Program Files (x86)/Windows Kits/10//include/10.0.26100.0//um/"
99
#pragma dir "C:/Program Files (x86)/Windows Kits/10//include/10.0.26100.0//shared/"
1010
#pragma dir "C:/Program Files (x86)/Windows Kits/10//include/10.0.26100.0//winrt/"
1111
#pragma dir "C:/Program Files (x86)/Windows Kits/10//include/10.0.26100.0//cppwinrt/"
12+
#pragma dir "C:/Program Files (x86)/Windows Kits/NETFXSDK/4.8/include/um/"

src/expressions.c

Lines changed: 59 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2118,7 +2118,7 @@ struct expression* _Owner _Opt postfix_expression_tail(struct parser_ctx* ctx, s
21182118
else
21192119
{
21202120
/* not fixed yet */
2121-
/* assert(false); */
2121+
/* assert(false); */
21222122
}
21232123
}
21242124
else
@@ -2640,10 +2640,6 @@ static int check_sizeof_argument(struct parser_ctx* ctx,
26402640
const struct expression* p_expression,
26412641
const struct type* const p_type)
26422642
{
2643-
//sizeof(type) p_expression is the sizeof expression
2644-
//sizeof(expression) p_expression is expression
2645-
2646-
26472643
enum type_category category = type_get_category(p_type);
26482644

26492645
if (category == TYPE_CATEGORY_FUNCTION)
@@ -2900,6 +2896,46 @@ struct expression* _Owner _Opt unary_expression(struct parser_ctx* ctx, enum exp
29002896
*/
29012897
new_expression->expression_type = UNARY_EXPRESSION_ADDRESSOF;
29022898

2899+
if (new_expression->right->expression_type == POSTFIX_ARROW &&
2900+
object_has_constant_value(&new_expression->right->left->object))
2901+
{
2902+
/*
2903+
offsetof pattern evaluated at compile time
2904+
2905+
Sample:
2906+
& ((struct { int i; int i2; }*)0)->i2
2907+
2908+
If the pointer has a constant value, we compute the member's
2909+
offset and then add it to that constant value that is generally zero.
2910+
*/
2911+
2912+
const unsigned long long pointer_value =
2913+
object_to_unsigned_long_long(&new_expression->right->left->object);
2914+
2915+
struct type struct_type = type_remove_pointer(&new_expression->right->left->type);
2916+
if (type_is_struct_or_union(&struct_type))
2917+
{
2918+
size_t offset_of;
2919+
enum sizeof_result e =
2920+
type_get_offsetof(&struct_type,
2921+
new_expression->right->last_token->lexeme /*member identifier*/,
2922+
&offset_of,
2923+
ctx->options.target);
2924+
switch (e)
2925+
{
2926+
case SIZEOF_RESULT_OK:
2927+
new_expression->object = object_make_size_t(ctx->options.target, pointer_value + offset_of);
2928+
break;
2929+
case SIZEOF_RESULT_OVERLOW:
2930+
case SIZEOF_RESULT_RUNTIME:
2931+
case SIZEOF_RESULT_INCOMPLETE:
2932+
case SIZEOF_RESULT_FUNCTION:
2933+
break;
2934+
}
2935+
}
2936+
type_destroy(&struct_type);
2937+
}
2938+
29032939
if (!expression_is_lvalue(new_expression->right))
29042940
{
29052941
compiler_diagnostic(C_ERROR_ADDRESS_OF_REGISTER,
@@ -3273,20 +3309,23 @@ struct expression* _Owner _Opt unary_expression(struct parser_ctx* ctx, enum exp
32733309
}
32743310
else
32753311
{
3276-
if (type_is_vla(&new_expression->type_name->abstract_declarator->type))
3277-
{
3278-
/* not a constant */
3279-
}
3280-
else
3312+
size_t sz = 0;
3313+
enum sizeof_result sizeof_result =
3314+
type_get_sizeof(&new_expression->type_name->abstract_declarator->type, &sz, ctx->options.target);
3315+
switch (sizeof_result)
32813316
{
3282-
size_t type_sizeof = 0;
3283-
if (type_get_sizeof(&new_expression->type_name->abstract_declarator->type, &type_sizeof, ctx->options.target) != 0)
3284-
{
3285-
expression_delete(new_expression);
3286-
throw;
3287-
}
3317+
case SIZEOF_RESULT_OK:
3318+
new_expression->object = object_make_size_t(ctx->options.target, sz);
3319+
break;
3320+
3321+
case SIZEOF_RESULT_RUNTIME:
3322+
break;
32883323

3289-
new_expression->object = object_make_size_t(ctx->options.target, type_sizeof);
3324+
case SIZEOF_RESULT_OVERLOW:
3325+
case SIZEOF_RESULT_INCOMPLETE:
3326+
case SIZEOF_RESULT_FUNCTION:
3327+
expression_delete(new_expression);
3328+
throw;
32903329
}
32913330
}
32923331
}
@@ -3314,12 +3353,12 @@ struct expression* _Owner _Opt unary_expression(struct parser_ctx* ctx, enum exp
33143353
switch (res)
33153354
{
33163355
case SIZEOF_RESULT_OK:
3356+
new_expression->object = object_make_size_t(ctx->options.target, sz3);
33173357
break;
3318-
case SIZEOF_RESULT_OVERLOW:
3319-
expression_delete(new_expression);
3320-
throw;
33213358
case SIZEOF_RESULT_RUNTIME:
33223359
break;
3360+
3361+
case SIZEOF_RESULT_OVERLOW:
33233362
case SIZEOF_RESULT_INCOMPLETE:
33243363
expression_delete(new_expression);
33253364
throw;
@@ -3333,15 +3372,6 @@ struct expression* _Owner _Opt unary_expression(struct parser_ctx* ctx, enum exp
33333372
"size of function");
33343373
break;
33353374
}
3336-
3337-
if (res == SIZEOF_RESULT_RUNTIME)
3338-
{
3339-
/* not a constant */
3340-
}
3341-
else
3342-
{
3343-
new_expression->object = object_make_size_t(ctx->options.target, sz3);
3344-
}
33453375
}
33463376

33473377
type_destroy(&new_expression->type);

src/file.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1-
char str[]; /* incomplete type */
21

3-
char str[] = "initializer"; /* complete type */
2+
struct X
3+
{
4+
int i;
5+
int a[0];
6+
};
47

5-
void main(void) {}
8+
int main()
9+
{
10+
sizeof(struct X);
11+
}

0 commit comments

Comments
 (0)