@@ -135,7 +135,20 @@ pm_version(void) {
135135#define PM_NODE_LENGTH_SET_TOKEN(parser_, node_, token_) (PM_NODE_LENGTH(node_) = PM_TOKEN_END(parser_, token_) - PM_NODE_START(node_))
136136#define PM_NODE_LENGTH_SET_LOCATION(node_, location_) (PM_NODE_LENGTH(node_) = PM_LOCATION_END(location_) - PM_NODE_START(node_))
137137
138- #define PM_LOCATION_INIT(start_, length_) ((pm_location_t) { .start = (start_), .length = (length_) })
138+ /**
139+ * A function instead of a compound literal: MSVC 19.16 (VS2017) miscompiles a
140+ * conditional expression whose arms are both struct compound literals — it
141+ * materializes both arms before testing the condition, so the token
142+ * dereferences in the unselected arm of NTOK2LOC and friends fault on NULL.
143+ * Function call arguments are only evaluated on the selected branch.
144+ */
145+ static PRISM_INLINE pm_location_t
146+ pm_location_init(uint32_t start, uint32_t length) {
147+ pm_location_t location = { .start = start, .length = length };
148+ return location;
149+ }
150+
151+ #define PM_LOCATION_INIT(start_, length_) pm_location_init((start_), (length_))
139152#define PM_LOCATION_INIT_UNSET PM_LOCATION_INIT(0, 0)
140153#define PM_LOCATION_INIT_TOKEN(parser_, token_) PM_LOCATION_INIT(PM_TOKEN_START(parser_, token_), PM_TOKEN_LENGTH(token_))
141154#define PM_LOCATION_INIT_NODE(node_) UP(node_)->location
@@ -5670,12 +5683,15 @@ pm_match_write_node_create(pm_parser_t *parser, pm_call_node_t *call) {
56705683 */
56715684static pm_module_node_t *
56725685pm_module_node_create(pm_parser_t *parser, pm_constant_id_list_t *locals, const pm_token_t *module_keyword, pm_node_t *constant_path, const pm_token_t *name, pm_node_t *body, const pm_token_t *end_keyword) {
5686+ pm_constant_id_list_t module_locals = { .ids = NULL, .size = 0, .capacity = 0 };
5687+ if (locals != NULL) module_locals = *locals;
5688+
56735689 return pm_module_node_new(
56745690 parser->arena,
56755691 ++parser->node_id,
56765692 0,
56775693 PM_LOCATION_INIT_TOKENS(parser, module_keyword, end_keyword),
5678- (locals == NULL ? ((pm_constant_id_list_t) { .ids = NULL, .size = 0, .capacity = 0 }) : *locals) ,
5694+ module_locals ,
56795695 TOK2LOC(parser, module_keyword),
56805696 constant_path,
56815697 body,
@@ -17033,10 +17049,11 @@ parse_pattern_rest(pm_parser_t *parser, pm_constant_id_list_t *captures) {
1703317049 pm_parser_local_add(parser, constant_id, parser->previous.start, parser->previous.end, 0);
1703417050 }
1703517051
17036- parse_pattern_capture(parser, captures, constant_id, &TOK2LOC(parser, &parser->previous));
17052+ pm_location_t previous_loc = TOK2LOC(parser, &parser->previous);
17053+ parse_pattern_capture(parser, captures, constant_id, &previous_loc);
1703717054 name = UP(pm_local_variable_target_node_create(
1703817055 parser,
17039- &TOK2LOC(parser, &parser->previous) ,
17056+ &previous_loc ,
1704017057 constant_id,
1704117058 (uint32_t) (depth == -1 ? 0 : depth)
1704217059 ));
@@ -17069,10 +17086,11 @@ parse_pattern_keyword_rest(pm_parser_t *parser, pm_constant_id_list_t *captures)
1706917086 pm_parser_local_add(parser, constant_id, parser->previous.start, parser->previous.end, 0);
1707017087 }
1707117088
17072- parse_pattern_capture(parser, captures, constant_id, &TOK2LOC(parser, &parser->previous));
17089+ pm_location_t previous_loc = TOK2LOC(parser, &parser->previous);
17090+ parse_pattern_capture(parser, captures, constant_id, &previous_loc);
1707317091 value = UP(pm_local_variable_target_node_create(
1707417092 parser,
17075- &TOK2LOC(parser, &parser->previous) ,
17093+ &previous_loc ,
1707617094 constant_id,
1707717095 (uint32_t) (depth == -1 ? 0 : depth)
1707817096 ));
@@ -17316,10 +17334,11 @@ parse_pattern_primitive(pm_parser_t *parser, pm_constant_id_list_t *captures, pm
1731617334 pm_parser_local_add(parser, constant_id, parser->previous.start, parser->previous.end, 0);
1731717335 }
1731817336
17319- parse_pattern_capture(parser, captures, constant_id, &TOK2LOC(parser, &parser->previous));
17337+ pm_location_t previous_loc = TOK2LOC(parser, &parser->previous);
17338+ parse_pattern_capture(parser, captures, constant_id, &previous_loc);
1732017339 return UP(pm_local_variable_target_node_create(
1732117340 parser,
17322- &TOK2LOC(parser, &parser->previous) ,
17341+ &previous_loc ,
1732317342 constant_id,
1732417343 (uint32_t) (depth == -1 ? 0 : depth)
1732517344 ));
@@ -17668,10 +17687,11 @@ parse_pattern_primitives(pm_parser_t *parser, pm_constant_id_list_t *captures, p
1766817687 pm_parser_local_add(parser, constant_id, parser->previous.start, parser->previous.end, 0);
1766917688 }
1767017689
17671- parse_pattern_capture(parser, captures, constant_id, &TOK2LOC(parser, &parser->previous));
17690+ pm_location_t previous_loc = TOK2LOC(parser, &parser->previous);
17691+ parse_pattern_capture(parser, captures, constant_id, &previous_loc);
1767217692 pm_local_variable_target_node_t *target = pm_local_variable_target_node_create(
1767317693 parser,
17674- &TOK2LOC(parser, &parser->previous) ,
17694+ &previous_loc ,
1767517695 constant_id,
1767617696 (uint32_t) (depth == -1 ? 0 : depth)
1767717697 );
@@ -21459,7 +21479,9 @@ parse_regular_expression_named_capture(pm_parser_t *parser, const pm_string_t *c
2145921479
2146021480 // Next, create the local variable target and add it to the list of
2146121481 // targets for the match.
21462- pm_node_t *target = UP(pm_local_variable_target_node_create(parser, &TOK2LOC(parser, &((pm_token_t) { .type = 0, .start = start, .end = end })), name, depth == -1 ? 0 : (uint32_t) depth));
21482+ pm_token_t token = { .type = 0, .start = start, .end = end };
21483+ pm_location_t token_loc = TOK2LOC(parser, &token);
21484+ pm_node_t *target = UP(pm_local_variable_target_node_create(parser, &token_loc, name, depth == -1 ? 0 : (uint32_t) depth));
2146321485 pm_node_list_append(parser->arena, &callback_data->match->targets, target);
2146421486 }
2146521487
0 commit comments