authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-28 02:33:32-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-09-28 02:33:32-04:00
logb581da41f82cd1e19701030bf47675b426608adf
treebbfebb52858935e2e91ffabd8b0c2b02fb58ca27
parente5fd8efcb60cd0223a7dd5e5825d3b9efc006c2a

remove compiler directives

* add `setFnTest`, `setFnVisible`, `setFnStaticEval`, `setFnNoInline` builtin functions to replace previous directive functionality * add `coldcc` and `nakedcc` as keywords which can be used as part of a function prototype. * `setDebugSafety` builtin can be used to set debug safety features at a per block scope level. * closes #169

40 files changed, 812 insertions(+), 528 deletions(-)

doc/langref.md+6-6
......@@ -3,9 +3,11 @@
33## Grammar
44
55```
6Root = many(TopLevelDecl) "EOF"
6Root = many(TopLevelItem) "EOF"
77
8TopLevelDecl = many(Directive) option(VisibleMod) (FnDef | ExternDecl | ContainerDecl | GlobalVarDecl | ErrorValueDecl | TypeDecl | UseDecl)
8TopLevelItem = ErrorValueDecl | Block | TopLevelDecl
9
10TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | ContainerDecl | GlobalVarDecl | TypeDecl | UseDecl)
911
1012TypeDecl = "type" Symbol "=" TypeExpr ";"
1113
......@@ -17,7 +19,7 @@ VariableDeclaration = ("var" | "const") Symbol option(":" TypeExpr) "=" Expressi
1719
1820ContainerDecl = ("struct" | "enum" | "union") Symbol option(ParamDeclList) "{" many(StructMember) "}"
1921
20StructMember = many(Directive) option(VisibleMod) (StructField | FnDef | GlobalVarDecl | ContainerDecl)
22StructMember = (StructField | FnDef | GlobalVarDecl | ContainerDecl)
2123
2224StructField = Symbol option(":" Expression) ",")
2325
......@@ -25,9 +27,7 @@ UseDecl = "use" Expression ";"
2527
2628ExternDecl = "extern" (FnProto | VariableDeclaration) ";"
2729
28FnProto = "fn" option(Symbol) ParamDeclList option("->" TypeExpr)
29
30Directive = "#" Symbol "(" Expression ")"
30FnProto = option("coldcc" | "nakedcc") "fn" option(Symbol) ParamDeclList option("->" TypeExpr)
3131
3232VisibleMod = "pub" | "export"
3333
doc/vim/syntax/zig.vim+1-1
......@@ -8,7 +8,7 @@ if exists("b:current_syntax")
88endif
99let b:current_syntax = "zig"
1010
11syn keyword zigStorage const var extern export pub noalias inline noinline
11syn keyword zigStorage const var extern export pub noalias inline nakedcc coldcc
1212syn keyword zigStructure struct enum union
1313syn keyword zigStatement goto break return continue asm defer
1414syn keyword zigConditional if else switch
src/all_types.hpp+13-9
......@@ -129,7 +129,6 @@ enum TldResolution {
129129struct TopLevelDecl {
130130 // populated by parser
131131 Buf *name;
132 ZigList<AstNode *> *directives;
133132 VisibMod visib_mod;
134133
135134 // populated by semantic analyzer
......@@ -153,7 +152,6 @@ enum NodeType {
153152 NodeTypeFnDecl,
154153 NodeTypeParamDecl,
155154 NodeTypeBlock,
156 NodeTypeDirective,
157155 NodeTypeReturnExpr,
158156 NodeTypeDefer,
159157 NodeTypeVariableDeclaration,
......@@ -210,6 +208,8 @@ struct AstNodeFnProto {
210208 bool is_var_args;
211209 bool is_extern;
212210 bool is_inline;
211 bool is_coldcc;
212 bool is_nakedcc;
213213
214214 // populated by semantic analyzer:
215215
......@@ -459,11 +459,6 @@ struct AstNodeFieldAccessExpr {
459459 AstNode *container_init_expr_node;
460460};
461461
462struct AstNodeDirective {
463 Buf *name;
464 AstNode *expr;
465};
466
467462enum PrefixOp {
468463 PrefixOpInvalid,
469464 PrefixOpBoolNot,
......@@ -802,7 +797,6 @@ struct AstNode {
802797 AstNodeErrorValueDecl error_value_decl;
803798 AstNodeBinOpExpr bin_op_expr;
804799 AstNodeUnwrapErrorExpr unwrap_err_expr;
805 AstNodeDirective directive;
806800 AstNodePrefixOpExpr prefix_op_expr;
807801 AstNodeFnCallExpr fn_call_expr;
808802 AstNodeArrayAccessExpr array_access_expr;
......@@ -1109,10 +1103,14 @@ struct FnTableEntry {
11091103 WantPure want_pure;
11101104 AstNode *want_pure_attr_node;
11111105 AstNode *want_pure_return_type;
1112 bool safety_off;
11131106 FnInline fn_inline;
11141107 FnAnalState anal_state;
11151108
1109 AstNode *fn_no_inline_set_node;
1110 AstNode *fn_export_set_node;
1111 AstNode *fn_test_set_node;
1112 AstNode *fn_static_eval_set_node;
1113
11161114 ZigList<AstNode *> cast_alloca_list;
11171115 ZigList<StructValExprCodeGen *> struct_val_expr_alloca_list;
11181116 ZigList<VariableTableEntry *> variable_list;
......@@ -1154,6 +1152,11 @@ enum BuiltinFnId {
11541152 BuiltinFnIdTruncate,
11551153 BuiltinFnIdIntType,
11561154 BuiltinFnIdUnreachable,
1155 BuiltinFnIdSetFnTest,
1156 BuiltinFnIdSetFnVisible,
1157 BuiltinFnIdSetFnStaticEval,
1158 BuiltinFnIdSetFnNoInline,
1159 BuiltinFnIdSetDebugSafety,
11571160};
11581161
11591162struct BuiltinFnEntry {
......@@ -1373,6 +1376,7 @@ struct BlockContext {
13731376 bool codegen_excluded;
13741377
13751378 bool safety_off;
1379 AstNode *safety_set_node;
13761380};
13771381
13781382enum AtomicOrder {
src/analyze.cpp+231-96
......@@ -75,7 +75,6 @@ static AstNode *first_executing_node(AstNode *node) {
7575 case NodeTypeFnDecl:
7676 case NodeTypeParamDecl:
7777 case NodeTypeBlock:
78 case NodeTypeDirective:
7978 case NodeTypeReturnExpr:
8079 case NodeTypeDefer:
8180 case NodeTypeVariableDeclaration:
......@@ -1123,6 +1122,28 @@ static bool resolve_const_expr_bool(CodeGen *g, ImportTableEntry *import, BlockC
11231122 return true;
11241123}
11251124
1125static FnTableEntry *resolve_const_expr_fn(CodeGen *g, ImportTableEntry *import, BlockContext *context,
1126 AstNode **node)
1127{
1128 TypeTableEntry *resolved_type = analyze_expression(g, import, context, nullptr, *node);
1129
1130 if (resolved_type->id == TypeTableEntryIdInvalid) {
1131 return nullptr;
1132 } else if (resolved_type->id == TypeTableEntryIdFn) {
1133 ConstExprValue *const_val = &get_resolved_expr(*node)->const_val;
1134
1135 if (!const_val->ok) {
1136 add_node_error(g, *node, buf_sprintf("unable to evaluate constant expression"));
1137 return nullptr;
1138 }
1139
1140 return const_val->data.x_fn;
1141 } else {
1142 add_node_error(g, *node, buf_sprintf("expected function, got '%s'", buf_ptr(&resolved_type->name)));
1143 return nullptr;
1144 }
1145}
1146
11261147static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_table_entry,
11271148 ImportTableEntry *import, BlockContext *containing_context)
11281149{
......@@ -1133,85 +1154,6 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
11331154 return;
11341155 }
11351156
1136 bool is_cold = false;
1137 bool is_naked = false;
1138 bool is_test = false;
1139 bool is_noinline = false;
1140
1141 if (fn_proto->top_level_decl.directives) {
1142 for (size_t i = 0; i < fn_proto->top_level_decl.directives->length; i += 1) {
1143 AstNode *directive_node = fn_proto->top_level_decl.directives->at(i);
1144 Buf *name = directive_node->data.directive.name;
1145
1146 if (buf_eql_str(name, "attribute")) {
1147 if (fn_table_entry->fn_def_node) {
1148 Buf *attr_name = resolve_const_expr_str(g, import, import->block_context,
1149 &directive_node->data.directive.expr);
1150 if (attr_name) {
1151 if (buf_eql_str(attr_name, "naked")) {
1152 is_naked = true;
1153 } else if (buf_eql_str(attr_name, "noinline")) {
1154 is_noinline = true;
1155 } else if (buf_eql_str(attr_name, "cold")) {
1156 is_cold = true;
1157 } else if (buf_eql_str(attr_name, "test")) {
1158 is_test = true;
1159 g->test_fn_count += 1;
1160 } else {
1161 add_node_error(g, directive_node,
1162 buf_sprintf("invalid function attribute: '%s'", buf_ptr(name)));
1163 }
1164 }
1165 } else {
1166 add_node_error(g, directive_node,
1167 buf_sprintf("invalid function attribute: '%s'", buf_ptr(name)));
1168 }
1169 } else if (buf_eql_str(name, "debug_safety")) {
1170 if (!fn_table_entry->fn_def_node) {
1171 add_node_error(g, directive_node,
1172 buf_sprintf("#debug_safety valid only on function definitions"));
1173 } else {
1174 bool enable;
1175 bool ok = resolve_const_expr_bool(g, import, import->block_context,
1176 &directive_node->data.directive.expr, &enable);
1177 if (ok && !enable) {
1178 fn_table_entry->safety_off = true;
1179 }
1180 }
1181 } else if (buf_eql_str(name, "condition")) {
1182 if (fn_proto->top_level_decl.visib_mod == VisibModExport) {
1183 bool include;
1184 bool ok = resolve_const_expr_bool(g, import, import->block_context,
1185 &directive_node->data.directive.expr, &include);
1186 if (ok && !include) {
1187 fn_proto->top_level_decl.visib_mod = VisibModPub;
1188 }
1189 } else {
1190 add_node_error(g, directive_node,
1191 buf_sprintf("#condition valid only on exported symbols"));
1192 }
1193 } else if (buf_eql_str(name, "static_eval_enable")) {
1194 if (!fn_table_entry->fn_def_node) {
1195 add_node_error(g, directive_node,
1196 buf_sprintf("#static_val_enable valid only on function definitions"));
1197 } else {
1198 bool enable;
1199 bool ok = resolve_const_expr_bool(g, import, import->block_context,
1200 &directive_node->data.directive.expr, &enable);
1201 if (!ok || !enable) {
1202 fn_table_entry->want_pure = WantPureFalse;
1203 } else if (ok && enable) {
1204 fn_table_entry->want_pure = WantPureTrue;
1205 fn_table_entry->want_pure_attr_node = directive_node->data.directive.expr;
1206 }
1207 }
1208 } else {
1209 add_node_error(g, directive_node,
1210 buf_sprintf("invalid directive: '%s'", buf_ptr(name)));
1211 }
1212 }
1213 }
1214
12151157 bool is_internal = (fn_proto->top_level_decl.visib_mod != VisibModExport);
12161158 bool is_c_compat = !is_internal || fn_proto->is_extern;
12171159 fn_table_entry->internal_linkage = !is_c_compat;
......@@ -1219,24 +1161,17 @@ static void resolve_function_proto(CodeGen *g, AstNode *node, FnTableEntry *fn_t
12191161
12201162
12211163 TypeTableEntry *fn_type = analyze_fn_proto_type(g, import, containing_context, nullptr, node,
1222 is_naked, is_cold, fn_table_entry);
1164 fn_proto->is_nakedcc, fn_proto->is_coldcc, fn_table_entry);
12231165
12241166 fn_table_entry->type_entry = fn_type;
1225 fn_table_entry->is_test = is_test;
12261167
12271168 if (fn_type->id == TypeTableEntryIdInvalid) {
12281169 fn_proto->skip = true;
12291170 return;
12301171 }
12311172
1232 if (fn_proto->is_inline && is_noinline) {
1233 add_node_error(g, node, buf_sprintf("function is both inline and noinline"));
1234 fn_proto->skip = true;
1235 return;
1236 } else if (fn_proto->is_inline) {
1173 if (fn_proto->is_inline) {
12371174 fn_table_entry->fn_inline = FnInlineAlways;
1238 } else if (is_noinline) {
1239 fn_table_entry->fn_inline = FnInlineNever;
12401175 }
12411176
12421177
......@@ -1881,7 +1816,6 @@ static void resolve_top_level_decl(CodeGen *g, AstNode *node, bool pointer_only)
18811816 zig_panic("TODO resolve_top_level_decl NodeTypeUse");
18821817 break;
18831818 case NodeTypeFnDef:
1884 case NodeTypeDirective:
18851819 case NodeTypeParamDecl:
18861820 case NodeTypeFnDecl:
18871821 case NodeTypeReturnExpr:
......@@ -2406,13 +2340,11 @@ BlockContext *new_block_context(AstNode *node, BlockContext *parent) {
24062340 context->parent_loop_node = parent->parent_loop_node;
24072341 context->c_import_buf = parent->c_import_buf;
24082342 context->codegen_excluded = parent->codegen_excluded;
2409 context->safety_off = parent->safety_off;
24102343 }
24112344
24122345 if (node && node->type == NodeTypeFnDef) {
24132346 AstNode *fn_proto_node = node->data.fn_def.fn_proto;
24142347 context->fn_entry = fn_proto_node->data.fn_proto.fn_table_entry;
2415 context->safety_off = context->fn_entry->safety_off;
24162348 } else if (parent) {
24172349 context->fn_entry = parent->fn_entry;
24182350 }
......@@ -5246,6 +5178,203 @@ static TypeTableEntry *analyze_int_type(CodeGen *g, ImportTableEntry *import,
52465178
52475179}
52485180
5181static TypeTableEntry *analyze_set_fn_test(CodeGen *g, ImportTableEntry *import,
5182 BlockContext *context, AstNode *node)
5183{
5184 AstNode **fn_node = &node->data.fn_call_expr.params.at(0);
5185 AstNode **value_node = &node->data.fn_call_expr.params.at(1);
5186
5187 FnTableEntry *fn_entry = resolve_const_expr_fn(g, import, context, fn_node);
5188 if (!fn_entry) {
5189 return g->builtin_types.entry_invalid;
5190 }
5191
5192 bool ok = resolve_const_expr_bool(g, import, context, value_node, &fn_entry->is_test);
5193 if (!ok) {
5194 return g->builtin_types.entry_invalid;
5195 }
5196
5197 if (fn_entry->fn_test_set_node) {
5198 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("function test attribute set twice"));
5199 add_error_note(g, msg, fn_entry->fn_test_set_node, buf_sprintf("first set here"));
5200 return g->builtin_types.entry_invalid;
5201 }
5202 fn_entry->fn_test_set_node = node;
5203
5204 g->test_fn_count += 1;
5205 return g->builtin_types.entry_void;
5206}
5207
5208static TypeTableEntry *analyze_set_fn_no_inline(CodeGen *g, ImportTableEntry *import,
5209 BlockContext *context, AstNode *node)
5210{
5211 AstNode **fn_node = &node->data.fn_call_expr.params.at(0);
5212 AstNode **value_node = &node->data.fn_call_expr.params.at(1);
5213
5214 FnTableEntry *fn_entry = resolve_const_expr_fn(g, import, context, fn_node);
5215 if (!fn_entry) {
5216 return g->builtin_types.entry_invalid;
5217 }
5218
5219 bool is_noinline;
5220 bool ok = resolve_const_expr_bool(g, import, context, value_node, &is_noinline);
5221 if (!ok) {
5222 return g->builtin_types.entry_invalid;
5223 }
5224
5225 if (fn_entry->fn_no_inline_set_node) {
5226 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("function no inline attribute set twice"));
5227 add_error_note(g, msg, fn_entry->fn_no_inline_set_node, buf_sprintf("first set here"));
5228 return g->builtin_types.entry_invalid;
5229 }
5230 fn_entry->fn_no_inline_set_node = node;
5231
5232 if (fn_entry->fn_inline == FnInlineAlways) {
5233 add_node_error(g, node, buf_sprintf("function is both inline and noinline"));
5234 fn_entry->proto_node->data.fn_proto.skip = true;
5235 return g->builtin_types.entry_invalid;
5236 } else if (is_noinline) {
5237 fn_entry->fn_inline = FnInlineNever;
5238 }
5239
5240 return g->builtin_types.entry_void;
5241}
5242
5243static TypeTableEntry *analyze_set_fn_static_eval(CodeGen *g, ImportTableEntry *import,
5244 BlockContext *context, AstNode *node)
5245{
5246 AstNode **fn_node = &node->data.fn_call_expr.params.at(0);
5247 AstNode **value_node = &node->data.fn_call_expr.params.at(1);
5248
5249 FnTableEntry *fn_entry = resolve_const_expr_fn(g, import, context, fn_node);
5250 if (!fn_entry) {
5251 return g->builtin_types.entry_invalid;
5252 }
5253
5254 bool want_static_eval;
5255 bool ok = resolve_const_expr_bool(g, import, context, value_node, &want_static_eval);
5256 if (!ok) {
5257 return g->builtin_types.entry_invalid;
5258 }
5259
5260 if (fn_entry->fn_static_eval_set_node) {
5261 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("function static eval attribute set twice"));
5262 add_error_note(g, msg, fn_entry->fn_static_eval_set_node, buf_sprintf("first set here"));
5263 return g->builtin_types.entry_invalid;
5264 }
5265 fn_entry->fn_static_eval_set_node = node;
5266
5267 if (want_static_eval && !context->fn_entry->is_pure) {
5268 add_node_error(g, node, buf_sprintf("attribute appears too late within function"));
5269 return g->builtin_types.entry_invalid;
5270 }
5271
5272 if (want_static_eval) {
5273 fn_entry->want_pure = WantPureTrue;
5274 fn_entry->want_pure_attr_node = node;
5275 } else {
5276 fn_entry->want_pure = WantPureFalse;
5277 fn_entry->is_pure = false;
5278 }
5279
5280 return g->builtin_types.entry_void;
5281}
5282
5283static TypeTableEntry *analyze_set_fn_visible(CodeGen *g, ImportTableEntry *import,
5284 BlockContext *context, AstNode *node)
5285{
5286 AstNode **fn_node = &node->data.fn_call_expr.params.at(0);
5287 AstNode **value_node = &node->data.fn_call_expr.params.at(1);
5288
5289 FnTableEntry *fn_entry = resolve_const_expr_fn(g, import, context, fn_node);
5290 if (!fn_entry) {
5291 return g->builtin_types.entry_invalid;
5292 }
5293
5294 bool want_export;
5295 bool ok = resolve_const_expr_bool(g, import, context, value_node, &want_export);
5296 if (!ok) {
5297 return g->builtin_types.entry_invalid;
5298 }
5299
5300 if (fn_entry->fn_export_set_node) {
5301 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("function visibility set twice"));
5302 add_error_note(g, msg, fn_entry->fn_export_set_node, buf_sprintf("first set here"));
5303 return g->builtin_types.entry_invalid;
5304 }
5305 fn_entry->fn_export_set_node = node;
5306
5307 AstNodeFnProto *fn_proto = &fn_entry->proto_node->data.fn_proto;
5308 if (fn_proto->top_level_decl.visib_mod != VisibModExport) {
5309 ErrorMsg *msg = add_node_error(g, node,
5310 buf_sprintf("function must be marked export to set function visibility"));
5311 add_error_note(g, msg, fn_entry->proto_node, buf_sprintf("function declared here"));
5312 return g->builtin_types.entry_void;
5313 }
5314 if (!want_export) {
5315 fn_proto->top_level_decl.visib_mod = VisibModPub;
5316 }
5317
5318 return g->builtin_types.entry_void;
5319}
5320
5321static TypeTableEntry *analyze_set_debug_safety(CodeGen *g, ImportTableEntry *import,
5322 BlockContext *parent_context, AstNode *node)
5323{
5324 AstNode **target_node = &node->data.fn_call_expr.params.at(0);
5325 AstNode **value_node = &node->data.fn_call_expr.params.at(1);
5326
5327 TypeTableEntry *target_type = analyze_expression(g, import, parent_context, nullptr, *target_node);
5328 BlockContext *target_context;
5329 ConstExprValue *const_val = &get_resolved_expr(*target_node)->const_val;
5330 if (target_type->id == TypeTableEntryIdInvalid) {
5331 return g->builtin_types.entry_invalid;
5332 }
5333 if (!const_val->ok) {
5334 add_node_error(g, *target_node, buf_sprintf("unable to evaluate constant expression"));
5335 return g->builtin_types.entry_invalid;
5336 }
5337 if (target_type->id == TypeTableEntryIdBlock) {
5338 target_context = const_val->data.x_block;
5339 } else if (target_type->id == TypeTableEntryIdFn) {
5340 target_context = const_val->data.x_fn->fn_def_node->data.fn_def.block_context;
5341 } else if (target_type->id == TypeTableEntryIdMetaType) {
5342 TypeTableEntry *type_arg = const_val->data.x_type;
5343 if (type_arg->id == TypeTableEntryIdStruct) {
5344 target_context = type_arg->data.structure.block_context;
5345 } else if (type_arg->id == TypeTableEntryIdEnum) {
5346 target_context = type_arg->data.enumeration.block_context;
5347 } else if (type_arg->id == TypeTableEntryIdUnion) {
5348 target_context = type_arg->data.unionation.block_context;
5349 } else {
5350 add_node_error(g, *target_node,
5351 buf_sprintf("expected scope reference, got type '%s'", buf_ptr(&type_arg->name)));
5352 return g->builtin_types.entry_invalid;
5353 }
5354 } else {
5355 add_node_error(g, *target_node,
5356 buf_sprintf("expected scope reference, got type '%s'", buf_ptr(&target_type->name)));
5357 return g->builtin_types.entry_invalid;
5358 }
5359
5360 bool want_debug_safety;
5361 bool ok = resolve_const_expr_bool(g, import, parent_context, value_node, &want_debug_safety);
5362 if (!ok) {
5363 return g->builtin_types.entry_invalid;
5364 }
5365
5366 if (target_context->safety_set_node) {
5367 ErrorMsg *msg = add_node_error(g, node, buf_sprintf("debug safety for scope set twice"));
5368 add_error_note(g, msg, target_context->safety_set_node, buf_sprintf("first set here"));
5369 return g->builtin_types.entry_invalid;
5370 }
5371 target_context->safety_set_node = node;
5372
5373 target_context->safety_off = !want_debug_safety;
5374
5375 return g->builtin_types.entry_void;
5376}
5377
52495378static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context,
52505379 TypeTableEntry *expected_type, AstNode *node)
52515380{
......@@ -5607,6 +5736,16 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
56075736 return analyze_int_type(g, import, context, node);
56085737 case BuiltinFnIdUnreachable:
56095738 return g->builtin_types.entry_unreachable;
5739 case BuiltinFnIdSetFnTest:
5740 return analyze_set_fn_test(g, import, context, node);
5741 case BuiltinFnIdSetFnNoInline:
5742 return analyze_set_fn_no_inline(g, import, context, node);
5743 case BuiltinFnIdSetFnStaticEval:
5744 return analyze_set_fn_static_eval(g, import, context, node);
5745 case BuiltinFnIdSetFnVisible:
5746 return analyze_set_fn_visible(g, import, context, node);
5747 case BuiltinFnIdSetDebugSafety:
5748 return analyze_set_debug_safety(g, import, context, node);
56105749 }
56115750 zig_unreachable();
56125751}
......@@ -6876,7 +7015,6 @@ static TypeTableEntry *analyze_expression_pointer_only(CodeGen *g, ImportTableEn
68767015 break;
68777016 case NodeTypeSwitchProng:
68787017 case NodeTypeSwitchRange:
6879 case NodeTypeDirective:
68807018 case NodeTypeFnDecl:
68817019 case NodeTypeParamDecl:
68827020 case NodeTypeRoot:
......@@ -7109,7 +7247,6 @@ static void scan_decls(CodeGen *g, ImportTableEntry *import, BlockContext *conte
71097247 // error value declarations do not depend on other top level decls
71107248 preview_error_value_decl(g, node);
71117249 break;
7112 case NodeTypeDirective:
71137250 case NodeTypeParamDecl:
71147251 case NodeTypeFnDecl:
71157252 case NodeTypeReturnExpr:
......@@ -7418,7 +7555,6 @@ Expr *get_resolved_expr(AstNode *node) {
74187555 case NodeTypeFnDef:
74197556 case NodeTypeFnDecl:
74207557 case NodeTypeParamDecl:
7421 case NodeTypeDirective:
74227558 case NodeTypeUse:
74237559 case NodeTypeContainerDecl:
74247560 case NodeTypeStructField:
......@@ -7469,7 +7605,6 @@ static TopLevelDecl *get_as_top_level_decl(AstNode *node) {
74697605 case NodeTypeFnDecl:
74707606 case NodeTypeParamDecl:
74717607 case NodeTypeBlock:
7472 case NodeTypeDirective:
74737608 case NodeTypeStringLiteral:
74747609 case NodeTypeCharLiteral:
74757610 case NodeTypeSymbol:
src/ast_render.cpp-14
......@@ -141,8 +141,6 @@ static const char *node_type_str(NodeType node_type) {
141141 return "ArrayAccessExpr";
142142 case NodeTypeSliceExpr:
143143 return "SliceExpr";
144 case NodeTypeDirective:
145 return "Directive";
146144 case NodeTypeReturnExpr:
147145 return "ReturnExpr";
148146 case NodeTypeDefer:
......@@ -416,13 +414,6 @@ static void render_node(AstRender *ar, AstNode *node) {
416414 }
417415 case NodeTypeFnDef:
418416 {
419 ZigList<AstNode *> *directives =
420 node->data.fn_def.fn_proto->data.fn_proto.top_level_decl.directives;
421 if (directives) {
422 for (size_t i = 0; i < directives->length; i += 1) {
423 render_node(ar, directives->at(i));
424 }
425 }
426417 render_node(ar, node->data.fn_def.fn_proto);
427418 fprintf(ar->f, " ");
428419 render_node(ar, node->data.fn_def.body);
......@@ -445,11 +436,6 @@ static void render_node(AstRender *ar, AstNode *node) {
445436 print_indent(ar);
446437 fprintf(ar->f, "}");
447438 break;
448 case NodeTypeDirective:
449 fprintf(ar->f, "#%s(", buf_ptr(node->data.directive.name));
450 render_node(ar, node->data.directive.expr);
451 fprintf(ar->f, ")\n");
452 break;
453439 case NodeTypeReturnExpr:
454440 {
455441 const char *return_str = return_string(node->data.return_expr.kind);
src/codegen.cpp+25-2
......@@ -352,8 +352,20 @@ static LLVMValueRef get_handle_value(CodeGen *g, AstNode *source_node, LLVMValue
352352 }
353353}
354354
355static bool want_debug_safety_recursive(CodeGen *g, BlockContext *context) {
356 if (context->safety_set_node || !context->parent) {
357 return !context->safety_off;
358 }
359 context->safety_off = want_debug_safety_recursive(g, context->parent);
360 context->safety_set_node = context->parent->safety_set_node;
361 return !context->safety_off;
362}
363
355364static bool want_debug_safety(CodeGen *g, AstNode *node) {
356 return !g->is_release_build && !node->block_context->safety_off;
365 if (g->is_release_build) {
366 return false;
367 }
368 return want_debug_safety_recursive(g, node->block_context);
357369}
358370
359371static void gen_debug_safety_crash(CodeGen *g) {
......@@ -709,6 +721,13 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
709721 return gen_truncate(g, node);
710722 case BuiltinFnIdUnreachable:
711723 return gen_unreachable(g, node);
724 case BuiltinFnIdSetFnTest:
725 case BuiltinFnIdSetFnVisible:
726 case BuiltinFnIdSetFnStaticEval:
727 case BuiltinFnIdSetFnNoInline:
728 case BuiltinFnIdSetDebugSafety:
729 // do nothing
730 return nullptr;
712731 }
713732 zig_unreachable();
714733}
......@@ -3617,7 +3636,6 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) {
36173636 case NodeTypeFnDef:
36183637 case NodeTypeFnDecl:
36193638 case NodeTypeParamDecl:
3620 case NodeTypeDirective:
36213639 case NodeTypeUse:
36223640 case NodeTypeContainerDecl:
36233641 case NodeTypeStructField:
......@@ -4880,6 +4898,11 @@ static void define_builtin_fns(CodeGen *g) {
48804898 create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileErr, "compileError", 1);
48814899 create_builtin_fn_with_arg_count(g, BuiltinFnIdIntType, "intType", 2);
48824900 create_builtin_fn_with_arg_count(g, BuiltinFnIdUnreachable, "unreachable", 0);
4901 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnTest, "setFnTest", 2);
4902 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnVisible, "setFnVisible", 2);
4903 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnStaticEval, "setFnStaticEval", 2);
4904 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetFnNoInline, "setFnNoInline", 2);
4905 create_builtin_fn_with_arg_count(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
48834906}
48844907
48854908static void init(CodeGen *g, Buf *source_path) {
src/eval.cpp+6-1
......@@ -963,6 +963,12 @@ static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_
963963 case BuiltinFnIdCompileErr:
964964 case BuiltinFnIdIntType:
965965 zig_unreachable();
966 case BuiltinFnIdSetFnTest:
967 case BuiltinFnIdSetFnVisible:
968 case BuiltinFnIdSetFnStaticEval:
969 case BuiltinFnIdSetFnNoInline:
970 case BuiltinFnIdSetDebugSafety:
971 return false;
966972 }
967973
968974 return false;
......@@ -1398,7 +1404,6 @@ static bool eval_expr(EvalFn *ef, AstNode *node, ConstExprValue *out) {
13981404 case NodeTypeUse:
13991405 case NodeTypeAsmExpr:
14001406 case NodeTypeParamDecl:
1401 case NodeTypeDirective:
14021407 case NodeTypeTypeDecl:
14031408 zig_unreachable();
14041409 }
src/parseh.cpp-1
......@@ -124,7 +124,6 @@ static AstNode *create_typed_var_decl_node(Context *c, bool is_const, const char
124124 node->data.variable_declaration.is_const = is_const;
125125 node->data.variable_declaration.top_level_decl.visib_mod = c->visib_mod;
126126 node->data.variable_declaration.expr = init_node;
127 node->data.variable_declaration.top_level_decl.directives = nullptr;
128127 node->data.variable_declaration.type = type_node;
129128 normalize_parent_ptrs(node);
130129 return node;
src/parser.cpp+53-150
......@@ -211,8 +211,7 @@ static AstNode *ast_parse_if_expr(ParseContext *pc, size_t *token_index, bool ma
211211static AstNode *ast_parse_block_expr(ParseContext *pc, size_t *token_index, bool mandatory);
212212static AstNode *ast_parse_unwrap_expr(ParseContext *pc, size_t *token_index, bool mandatory);
213213static AstNode *ast_parse_prefix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory);
214static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory,
215 ZigList<AstNode*> *directives, VisibMod visib_mod);
214static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod);
216215static AstNode *ast_parse_return_expr(ParseContext *pc, size_t *token_index);
217216static AstNode *ast_parse_grouped_expr(ParseContext *pc, size_t *token_index, bool mandatory);
218217
......@@ -233,39 +232,6 @@ static Token *ast_eat_token(ParseContext *pc, size_t *token_index, TokenId token
233232 return token;
234233}
235234
236/*
237Directive = "#" "Symbol" "(" Expression ")"
238*/
239static AstNode *ast_parse_directive(ParseContext *pc, size_t *token_index) {
240 Token *number_sign = ast_eat_token(pc, token_index, TokenIdNumberSign);
241
242 AstNode *node = ast_create_node(pc, NodeTypeDirective, number_sign);
243
244 Token *name_symbol = ast_eat_token(pc, token_index, TokenIdSymbol);
245
246 node->data.directive.name = token_buf(name_symbol);
247
248 node->data.directive.expr = ast_parse_grouped_expr(pc, token_index, true);
249
250 normalize_parent_ptrs(node);
251 return node;
252}
253
254static void ast_parse_directives(ParseContext *pc, size_t *token_index,
255 ZigList<AstNode *> *directives)
256{
257 for (;;) {
258 Token *token = &pc->tokens->at(*token_index);
259 if (token->id == TokenIdNumberSign) {
260 AstNode *directive_node = ast_parse_directive(pc, token_index);
261 directives->append(directive_node);
262 } else {
263 return;
264 }
265 }
266 zig_unreachable();
267}
268
269235/*
270236TypeExpr = PrefixOpExpression | "var"
271237*/
......@@ -686,7 +652,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
686652 return node;
687653 } else if (token->id == TokenIdKeywordExtern) {
688654 *token_index += 1;
689 AstNode *node = ast_parse_fn_proto(pc, token_index, true, nullptr, VisibModPrivate);
655 AstNode *node = ast_parse_fn_proto(pc, token_index, true, VisibModPrivate);
690656 node->data.fn_proto.is_extern = true;
691657 return node;
692658 } else if (token->id == TokenIdAtSign) {
......@@ -735,7 +701,7 @@ static AstNode *ast_parse_primary_expr(ParseContext *pc, size_t *token_index, bo
735701 return array_type_node;
736702 }
737703
738 AstNode *fn_proto_node = ast_parse_fn_proto(pc, token_index, false, nullptr, VisibModPrivate);
704 AstNode *fn_proto_node = ast_parse_fn_proto(pc, token_index, false, VisibModPrivate);
739705 if (fn_proto_node) {
740706 return fn_proto_node;
741707 }
......@@ -1487,7 +1453,7 @@ static AstNode *ast_parse_defer_expr(ParseContext *pc, size_t *token_index) {
14871453VariableDeclaration : ("var" | "const") "Symbol" ("=" Expression | ":" PrefixOpExpression option("=" Expression))
14881454*/
14891455static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *token_index, bool mandatory,
1490 ZigList<AstNode*> *directives, VisibMod visib_mod)
1456 VisibMod visib_mod)
14911457{
14921458 Token *first_token = &pc->tokens->at(*token_index);
14931459
......@@ -1509,7 +1475,6 @@ static AstNode *ast_parse_variable_declaration_expr(ParseContext *pc, size_t *to
15091475
15101476 node->data.variable_declaration.is_const = is_const;
15111477 node->data.variable_declaration.top_level_decl.visib_mod = visib_mod;
1512 node->data.variable_declaration.top_level_decl.directives = directives;
15131478
15141479 Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol);
15151480 node->data.variable_declaration.symbol = token_buf(name_token);
......@@ -1985,8 +1950,7 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
19851950 if (statement_node) {
19861951 semicolon_expected = false;
19871952 } else {
1988 statement_node = ast_parse_variable_declaration_expr(pc, token_index, false,
1989 nullptr, VisibModPrivate);
1953 statement_node = ast_parse_variable_declaration_expr(pc, token_index, false, VisibModPrivate);
19901954 if (!statement_node) {
19911955 statement_node = ast_parse_defer_expr(pc, token_index);
19921956 }
......@@ -2023,25 +1987,35 @@ static AstNode *ast_parse_block(ParseContext *pc, size_t *token_index, bool mand
20231987}
20241988
20251989/*
2026FnProto = "fn" option("Symbol") ParamDeclList option("->" TypeExpr)
1990FnProto = option("coldcc" | "nakedcc") "fn" option(Symbol) ParamDeclList option("->" TypeExpr)
20271991*/
2028static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory,
2029 ZigList<AstNode*> *directives, VisibMod visib_mod)
2030{
1992static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
20311993 Token *first_token = &pc->tokens->at(*token_index);
1994 Token *fn_token;
20321995
2033 if (first_token->id != TokenIdKeywordFn) {
2034 if (mandatory) {
2035 ast_expect_token(pc, first_token, TokenIdKeywordFn);
2036 } else {
2037 return nullptr;
2038 }
1996 bool is_coldcc = false;
1997 bool is_nakedcc = false;
1998 if (first_token->id == TokenIdKeywordColdCC) {
1999 *token_index += 1;
2000 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
2001 is_coldcc = true;
2002 } else if (first_token->id == TokenIdKeywordNakedCC) {
2003 *token_index += 1;
2004 fn_token = ast_eat_token(pc, token_index, TokenIdKeywordFn);
2005 is_nakedcc = true;
2006 } else if (first_token->id == TokenIdKeywordFn) {
2007 fn_token = first_token;
2008 *token_index += 1;
2009 } else if (mandatory) {
2010 ast_expect_token(pc, first_token, TokenIdKeywordFn);
2011 } else {
2012 return nullptr;
20392013 }
2040 *token_index += 1;
20412014
2042 AstNode *node = ast_create_node(pc, NodeTypeFnProto, first_token);
2015 AstNode *node = ast_create_node(pc, NodeTypeFnProto, fn_token);
20432016 node->data.fn_proto.top_level_decl.visib_mod = visib_mod;
2044 node->data.fn_proto.top_level_decl.directives = directives;
2017 node->data.fn_proto.is_coldcc = is_coldcc;
2018 node->data.fn_proto.is_nakedcc = is_nakedcc;
20452019
20462020 Token *fn_name = &pc->tokens->at(*token_index);
20472021 if (fn_name->id == TokenIdSymbol) {
......@@ -2068,9 +2042,7 @@ static AstNode *ast_parse_fn_proto(ParseContext *pc, size_t *token_index, bool m
20682042/*
20692043FnDef = option("inline" | "extern") FnProto Block
20702044*/
2071static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool mandatory,
2072 ZigList<AstNode*> *directives, VisibMod visib_mod)
2073{
2045static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
20742046 Token *first_token = &pc->tokens->at(*token_index);
20752047 bool is_inline;
20762048 bool is_extern;
......@@ -2087,7 +2059,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool man
20872059 is_extern = false;
20882060 }
20892061
2090 AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory, directives, visib_mod);
2062 AstNode *fn_proto = ast_parse_fn_proto(pc, token_index, mandatory, visib_mod);
20912063 if (!fn_proto) {
20922064 if (is_inline || is_extern) {
20932065 *token_index -= 1;
......@@ -2115,9 +2087,7 @@ static AstNode *ast_parse_fn_def(ParseContext *pc, size_t *token_index, bool man
21152087/*
21162088ExternDecl = "extern" (FnProto | VariableDeclaration) ";"
21172089*/
2118static AstNode *ast_parse_extern_decl(ParseContext *pc, size_t *token_index, bool mandatory,
2119 ZigList<AstNode *> *directives, VisibMod visib_mod)
2120{
2090static AstNode *ast_parse_extern_decl(ParseContext *pc, size_t *token_index, bool mandatory, VisibMod visib_mod) {
21212091 Token *extern_kw = &pc->tokens->at(*token_index);
21222092 if (extern_kw->id != TokenIdKeywordExtern) {
21232093 if (mandatory) {
......@@ -2128,7 +2098,7 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, size_t *token_index, boo
21282098 }
21292099 *token_index += 1;
21302100
2131 AstNode *fn_proto_node = ast_parse_fn_proto(pc, token_index, false, directives, visib_mod);
2101 AstNode *fn_proto_node = ast_parse_fn_proto(pc, token_index, false, visib_mod);
21322102 if (fn_proto_node) {
21332103 ast_eat_token(pc, token_index, TokenIdSemicolon);
21342104
......@@ -2138,7 +2108,7 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, size_t *token_index, boo
21382108 return fn_proto_node;
21392109 }
21402110
2141 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, directives, visib_mod);
2111 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod);
21422112 if (var_decl_node) {
21432113 ast_eat_token(pc, token_index, TokenIdSemicolon);
21442114
......@@ -2155,9 +2125,7 @@ static AstNode *ast_parse_extern_decl(ParseContext *pc, size_t *token_index, boo
21552125/*
21562126UseDecl = "use" Expression ";"
21572127*/
2158static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index,
2159 ZigList<AstNode*> *directives, VisibMod visib_mod)
2160{
2128static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
21612129 Token *use_kw = &pc->tokens->at(*token_index);
21622130 if (use_kw->id != TokenIdKeywordUse)
21632131 return nullptr;
......@@ -2165,7 +2133,6 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index,
21652133
21662134 AstNode *node = ast_create_node(pc, NodeTypeUse, use_kw);
21672135 node->data.use.top_level_decl.visib_mod = visib_mod;
2168 node->data.use.top_level_decl.directives = directives;
21692136 node->data.use.expr = ast_parse_expression(pc, token_index, true);
21702137
21712138 ast_eat_token(pc, token_index, TokenIdSemicolon);
......@@ -2175,13 +2142,11 @@ static AstNode *ast_parse_use(ParseContext *pc, size_t *token_index,
21752142}
21762143
21772144/*
2178ContainerDecl = ("struct" | "enum" | "union") "Symbol" option(ParamDeclList) "{" many(StructMember) "}"
2179StructMember = many(Directive) option(VisibleMod) (StructField | FnDef | GlobalVarDecl | ContainerDecl)
2180StructField : "Symbol" option(":" Expression) ",")
2145ContainerDecl = ("struct" | "enum" | "union") Symbol option(ParamDeclList) "{" many(StructMember) "}"
2146StructMember = (StructField | FnDef | GlobalVarDecl | ContainerDecl)
2147StructField = Symbol option(":" Expression) ",")
21812148*/
2182static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
2183 ZigList<AstNode*> *directives, VisibMod visib_mod)
2184{
2149static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
21852150 Token *first_token = &pc->tokens->at(*token_index);
21862151
21872152 ContainerKind kind;
......@@ -2203,7 +2168,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
22032168 node->data.struct_decl.kind = kind;
22042169 node->data.struct_decl.name = token_buf(struct_name);
22052170 node->data.struct_decl.top_level_decl.visib_mod = visib_mod;
2206 node->data.struct_decl.top_level_decl.directives = directives;
22072171
22082172 Token *paren_or_brace = &pc->tokens->at(*token_index);
22092173 if (paren_or_brace->id == TokenIdLParen) {
......@@ -2217,10 +2181,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
22172181 }
22182182
22192183 for (;;) {
2220 Token *directive_token = &pc->tokens->at(*token_index);
2221 ZigList<AstNode *> *directive_list = allocate<ZigList<AstNode*>>(1);
2222 ast_parse_directives(pc, token_index, directive_list);
2223
22242184 Token *visib_tok = &pc->tokens->at(*token_index);
22252185 VisibMod visib_mod;
22262186 if (visib_tok->id == TokenIdKeywordPub) {
......@@ -2233,20 +2193,20 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
22332193 visib_mod = VisibModPrivate;
22342194 }
22352195
2236 AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, directive_list, visib_mod);
2196 AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, visib_mod);
22372197 if (fn_def_node) {
22382198 node->data.struct_decl.decls.append(fn_def_node);
22392199 continue;
22402200 }
22412201
2242 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, directive_list, visib_mod);
2202 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod);
22432203 if (var_decl_node) {
22442204 ast_eat_token(pc, token_index, TokenIdSemicolon);
22452205 node->data.struct_decl.decls.append(var_decl_node);
22462206 continue;
22472207 }
22482208
2249 AstNode *container_decl_node = ast_parse_container_decl(pc, token_index, directive_list, visib_mod);
2209 AstNode *container_decl_node = ast_parse_container_decl(pc, token_index, visib_mod);
22502210 if (container_decl_node) {
22512211 node->data.struct_decl.decls.append(container_decl_node);
22522212 continue;
......@@ -2255,10 +2215,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
22552215 Token *token = &pc->tokens->at(*token_index);
22562216
22572217 if (token->id == TokenIdRBrace) {
2258 if (directive_list->length > 0) {
2259 ast_error(pc, directive_token, "invalid directive");
2260 }
2261
22622218 *token_index += 1;
22632219 break;
22642220 } else if (token->id == TokenIdSymbol) {
......@@ -2266,7 +2222,6 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
22662222 *token_index += 1;
22672223
22682224 field_node->data.struct_field.top_level_decl.visib_mod = visib_mod;
2269 field_node->data.struct_field.top_level_decl.directives = directive_list;
22702225 field_node->data.struct_field.name = token_buf(token);
22712226
22722227 Token *expr_or_comma = &pc->tokens->at(*token_index);
......@@ -2293,9 +2248,7 @@ static AstNode *ast_parse_container_decl(ParseContext *pc, size_t *token_index,
22932248/*
22942249ErrorValueDecl : "error" "Symbol" ";"
22952250*/
2296static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index,
2297 ZigList<AstNode*> *directives, VisibMod visib_mod)
2298{
2251static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
22992252 Token *first_token = &pc->tokens->at(*token_index);
23002253
23012254 if (first_token->id != TokenIdKeywordError) {
......@@ -2308,7 +2261,6 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
23082261
23092262 AstNode *node = ast_create_node(pc, NodeTypeErrorValueDecl, first_token);
23102263 node->data.error_value_decl.top_level_decl.visib_mod = visib_mod;
2311 node->data.error_value_decl.top_level_decl.directives = directives;
23122264 node->data.error_value_decl.name = token_buf(name_tok);
23132265
23142266 normalize_parent_ptrs(node);
......@@ -2318,9 +2270,7 @@ static AstNode *ast_parse_error_value_decl(ParseContext *pc, size_t *token_index
23182270/*
23192271TypeDecl = "type" "Symbol" "=" TypeExpr ";"
23202272*/
2321static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index,
2322 ZigList<AstNode*> *directives, VisibMod visib_mod)
2323{
2273static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index, VisibMod visib_mod) {
23242274 Token *first_token = &pc->tokens->at(*token_index);
23252275
23262276 if (first_token->id != TokenIdKeywordType) {
......@@ -2338,21 +2288,17 @@ static AstNode *ast_parse_type_decl(ParseContext *pc, size_t *token_index,
23382288 ast_eat_token(pc, token_index, TokenIdSemicolon);
23392289
23402290 node->data.type_decl.top_level_decl.visib_mod = visib_mod;
2341 node->data.type_decl.top_level_decl.directives = directives;
23422291
23432292 normalize_parent_ptrs(node);
23442293 return node;
23452294}
23462295
23472296/*
2348TopLevelDecl = many(Directive) option(VisibleMod) (FnDef | ExternDecl | Import | ContainerDecl | GlobalVarDecl | ErrorValueDecl | CImportDecl | TypeDecl)
2297TopLevelItem = ErrorValueDecl | Block | TopLevelDecl
2298TopLevelDecl = option(VisibleMod) (FnDef | ExternDecl | ContainerDecl | GlobalVarDecl | TypeDecl | UseDecl)
23492299*/
23502300static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, ZigList<AstNode *> *top_level_decls) {
23512301 for (;;) {
2352 Token *directive_token = &pc->tokens->at(*token_index);
2353 ZigList<AstNode *> *directives = allocate<ZigList<AstNode*>>(1);
2354 ast_parse_directives(pc, token_index, directives);
2355
23562302 Token *visib_tok = &pc->tokens->at(*token_index);
23572303 VisibMod visib_mod;
23582304 if (visib_tok->id == TokenIdKeywordPub) {
......@@ -2365,61 +2311,56 @@ static void ast_parse_top_level_decls(ParseContext *pc, size_t *token_index, Zig
23652311 visib_mod = VisibModPrivate;
23662312 }
23672313
2368 AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, directives, visib_mod);
2314 AstNode *fn_def_node = ast_parse_fn_def(pc, token_index, false, visib_mod);
23692315 if (fn_def_node) {
23702316 top_level_decls->append(fn_def_node);
23712317 continue;
23722318 }
23732319
2374 AstNode *fn_proto_node = ast_parse_extern_decl(pc, token_index, false, directives, visib_mod);
2320 AstNode *fn_proto_node = ast_parse_extern_decl(pc, token_index, false, visib_mod);
23752321 if (fn_proto_node) {
23762322 top_level_decls->append(fn_proto_node);
23772323 continue;
23782324 }
23792325
2380 AstNode *use_node = ast_parse_use(pc, token_index, directives, visib_mod);
2326 AstNode *use_node = ast_parse_use(pc, token_index, visib_mod);
23812327 if (use_node) {
23822328 top_level_decls->append(use_node);
23832329 continue;
23842330 }
23852331
2386 AstNode *struct_node = ast_parse_container_decl(pc, token_index, directives, visib_mod);
2332 AstNode *struct_node = ast_parse_container_decl(pc, token_index, visib_mod);
23872333 if (struct_node) {
23882334 top_level_decls->append(struct_node);
23892335 continue;
23902336 }
23912337
2392 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false,
2393 directives, visib_mod);
2338 AstNode *var_decl_node = ast_parse_variable_declaration_expr(pc, token_index, false, visib_mod);
23942339 if (var_decl_node) {
23952340 ast_eat_token(pc, token_index, TokenIdSemicolon);
23962341 top_level_decls->append(var_decl_node);
23972342 continue;
23982343 }
23992344
2400 AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index, directives, visib_mod);
2345 AstNode *error_value_node = ast_parse_error_value_decl(pc, token_index, visib_mod);
24012346 if (error_value_node) {
24022347 top_level_decls->append(error_value_node);
24032348 continue;
24042349 }
24052350
2406 AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, directives, visib_mod);
2351 AstNode *type_decl_node = ast_parse_type_decl(pc, token_index, visib_mod);
24072352 if (type_decl_node) {
24082353 top_level_decls->append(type_decl_node);
24092354 continue;
24102355 }
24112356
2412 if (directives->length > 0) {
2413 ast_error(pc, directive_token, "invalid directive");
2414 }
2415
24162357 return;
24172358 }
24182359 zig_unreachable();
24192360}
24202361
24212362/*
2422Root : many(TopLevelDecl) token(EOF)
2363Root = many(TopLevelItem) "EOF"
24232364 */
24242365static AstNode *ast_parse_root(ParseContext *pc, size_t *token_index) {
24252366 AstNode *node = ast_create_node(pc, NodeTypeRoot, &pc->tokens->at(*token_index));
......@@ -2471,7 +2412,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
24712412 break;
24722413 case NodeTypeFnProto:
24732414 visit_field(&node->data.fn_proto.return_type, visit, context);
2474 visit_node_list(node->data.fn_proto.top_level_decl.directives, visit, context);
24752415 visit_node_list(&node->data.fn_proto.params, visit, context);
24762416 break;
24772417 case NodeTypeFnDef:
......@@ -2487,9 +2427,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
24872427 case NodeTypeBlock:
24882428 visit_node_list(&node->data.block.statements, visit, context);
24892429 break;
2490 case NodeTypeDirective:
2491 visit_field(&node->data.directive.expr, visit, context);
2492 break;
24932430 case NodeTypeReturnExpr:
24942431 visit_field(&node->data.return_expr.expr, visit, context);
24952432 break;
......@@ -2497,12 +2434,10 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
24972434 visit_field(&node->data.defer.expr, visit, context);
24982435 break;
24992436 case NodeTypeVariableDeclaration:
2500 visit_node_list(node->data.variable_declaration.top_level_decl.directives, visit, context);
25012437 visit_field(&node->data.variable_declaration.type, visit, context);
25022438 visit_field(&node->data.variable_declaration.expr, visit, context);
25032439 break;
25042440 case NodeTypeTypeDecl:
2505 visit_node_list(node->data.type_decl.top_level_decl.directives, visit, context);
25062441 visit_field(&node->data.type_decl.child_type, visit, context);
25072442 break;
25082443 case NodeTypeErrorValueDecl:
......@@ -2550,7 +2485,6 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
25502485 break;
25512486 case NodeTypeUse:
25522487 visit_field(&node->data.use.expr, visit, context);
2553 visit_node_list(node->data.use.top_level_decl.directives, visit, context);
25542488 break;
25552489 case NodeTypeBoolLiteral:
25562490 // none
......@@ -2626,11 +2560,9 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont
26262560 case NodeTypeContainerDecl:
26272561 visit_node_list(&node->data.struct_decl.fields, visit, context);
26282562 visit_node_list(&node->data.struct_decl.decls, visit, context);
2629 visit_node_list(node->data.struct_decl.top_level_decl.directives, visit, context);
26302563 break;
26312564 case NodeTypeStructField:
26322565 visit_field(&node->data.struct_field.type, visit, context);
2633 visit_node_list(node->data.struct_field.top_level_decl.directives, visit, context);
26342566 break;
26352567 case NodeTypeContainerInitExpr:
26362568 visit_field(&node->data.container_init_expr.type, visit, context);
......@@ -2688,16 +2620,6 @@ static void clone_subtree_list_omit_inline_params(ZigList<AstNode *> *dest, ZigL
26882620 }
26892621}
26902622
2691static void clone_subtree_list_ptr(ZigList<AstNode *> **dest_ptr, ZigList<AstNode *> *src,
2692 uint32_t *next_node_index)
2693{
2694 if (src) {
2695 ZigList<AstNode *> *dest = allocate<ZigList<AstNode *>>(1);
2696 *dest_ptr = dest;
2697 clone_subtree_list(dest, src, next_node_index);
2698 }
2699}
2700
27012623static void clone_subtree_field_special(AstNode **dest, AstNode *src, uint32_t *next_node_index,
27022624 enum AstCloneSpecial special)
27032625{
......@@ -2713,10 +2635,6 @@ static void clone_subtree_field(AstNode **dest, AstNode *src, uint32_t *next_nod
27132635 return clone_subtree_field_special(dest, src, next_node_index, AstCloneSpecialNone);
27142636}
27152637
2716static void clone_subtree_tld(TopLevelDecl *dest, TopLevelDecl *src, uint32_t *next_node_index) {
2717 clone_subtree_list_ptr(&dest->directives, src->directives, next_node_index);
2718}
2719
27202638AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index, enum AstCloneSpecial special) {
27212639 AstNode *new_node = allocate_nonzero<AstNode>(1);
27222640 safe_memcpy(new_node, old_node, 1);
......@@ -2730,8 +2648,6 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,
27302648 &old_node->data.root.top_level_decls, next_node_index);
27312649 break;
27322650 case NodeTypeFnProto:
2733 clone_subtree_tld(&new_node->data.fn_proto.top_level_decl, &old_node->data.fn_proto.top_level_decl,
2734 next_node_index);
27352651 clone_subtree_field(&new_node->data.fn_proto.return_type, old_node->data.fn_proto.return_type,
27362652 next_node_index);
27372653
......@@ -2761,9 +2677,6 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,
27612677 clone_subtree_list(&new_node->data.block.statements, &old_node->data.block.statements,
27622678 next_node_index);
27632679 break;
2764 case NodeTypeDirective:
2765 clone_subtree_field(&new_node->data.directive.expr, old_node->data.directive.expr, next_node_index);
2766 break;
27672680 case NodeTypeReturnExpr:
27682681 clone_subtree_field(&new_node->data.return_expr.expr, old_node->data.return_expr.expr, next_node_index);
27692682 break;
......@@ -2771,14 +2684,10 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,
27712684 clone_subtree_field(&new_node->data.defer.expr, old_node->data.defer.expr, next_node_index);
27722685 break;
27732686 case NodeTypeVariableDeclaration:
2774 clone_subtree_list_ptr(&new_node->data.variable_declaration.top_level_decl.directives,
2775 old_node->data.variable_declaration.top_level_decl.directives, next_node_index);
27762687 clone_subtree_field(&new_node->data.variable_declaration.type, old_node->data.variable_declaration.type, next_node_index);
27772688 clone_subtree_field(&new_node->data.variable_declaration.expr, old_node->data.variable_declaration.expr, next_node_index);
27782689 break;
27792690 case NodeTypeTypeDecl:
2780 clone_subtree_list_ptr(&new_node->data.type_decl.top_level_decl.directives,
2781 old_node->data.type_decl.top_level_decl.directives, next_node_index);
27822691 clone_subtree_field(&new_node->data.type_decl.child_type, old_node->data.type_decl.child_type, next_node_index);
27832692 break;
27842693 case NodeTypeErrorValueDecl:
......@@ -2832,8 +2741,6 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,
28322741 break;
28332742 case NodeTypeUse:
28342743 clone_subtree_field(&new_node->data.use.expr, old_node->data.use.expr, next_node_index);
2835 clone_subtree_list_ptr(&new_node->data.use.top_level_decl.directives,
2836 old_node->data.use.top_level_decl.directives, next_node_index);
28372744 break;
28382745 case NodeTypeBoolLiteral:
28392746 // none
......@@ -2908,13 +2815,9 @@ AstNode *ast_clone_subtree_special(AstNode *old_node, uint32_t *next_node_index,
29082815 next_node_index);
29092816 clone_subtree_list(&new_node->data.struct_decl.decls, &old_node->data.struct_decl.decls,
29102817 next_node_index);
2911 clone_subtree_list_ptr(&new_node->data.struct_decl.top_level_decl.directives,
2912 old_node->data.struct_decl.top_level_decl.directives, next_node_index);
29132818 break;
29142819 case NodeTypeStructField:
29152820 clone_subtree_field(&new_node->data.struct_field.type, old_node->data.struct_field.type, next_node_index);
2916 clone_subtree_list_ptr(&new_node->data.struct_field.top_level_decl.directives,
2917 old_node->data.struct_field.top_level_decl.directives, next_node_index);
29182821 break;
29192822 case NodeTypeContainerInitExpr:
29202823 clone_subtree_field(&new_node->data.container_init_expr.type, old_node->data.container_init_expr.type, next_node_index);
src/tokenizer.cpp+4
......@@ -109,6 +109,7 @@ struct ZigKeyword {
109109static const struct ZigKeyword zig_keywords[] = {
110110 {"asm", TokenIdKeywordAsm},
111111 {"break", TokenIdKeywordBreak},
112 {"coldcc", TokenIdKeywordColdCC},
112113 {"const", TokenIdKeywordConst},
113114 {"continue", TokenIdKeywordContinue},
114115 {"defer", TokenIdKeywordDefer},
......@@ -123,6 +124,7 @@ static const struct ZigKeyword zig_keywords[] = {
123124 {"goto", TokenIdKeywordGoto},
124125 {"if", TokenIdKeywordIf},
125126 {"inline", TokenIdKeywordInline},
127 {"nakedcc", TokenIdKeywordNakedCC},
126128 {"noalias", TokenIdKeywordNoAlias},
127129 {"null", TokenIdKeywordNull},
128130 {"pub", TokenIdKeywordPub},
......@@ -1476,6 +1478,8 @@ const char * token_name(TokenId id) {
14761478 case TokenIdKeywordType: return "type";
14771479 case TokenIdKeywordInline: return "inline";
14781480 case TokenIdKeywordDefer: return "defer";
1481 case TokenIdKeywordColdCC: return "coldcc";
1482 case TokenIdKeywordNakedCC: return "nakedcc";
14791483 case TokenIdLParen: return "(";
14801484 case TokenIdRParen: return ")";
14811485 case TokenIdComma: return ",";
src/tokenizer.hpp+2
......@@ -46,6 +46,8 @@ enum TokenId {
4646 TokenIdKeywordInline,
4747 TokenIdKeywordDefer,
4848 TokenIdKeywordThis,
49 TokenIdKeywordColdCC,
50 TokenIdKeywordNakedCC,
4951 TokenIdLParen,
5052 TokenIdRParen,
5153 TokenIdComma,
std/bootstrap.zig+5-4
......@@ -13,9 +13,9 @@ const want_main_symbol = !want_start_symbol;
1313var argc: usize = undefined;
1414var argv: &&u8 = undefined;
1515
16#attribute("naked")
17#condition(want_start_symbol)
18export fn _start() -> unreachable {
16export nakedcc fn _start() -> unreachable {
17 @setFnVisible(this, want_start_symbol);
18
1919 switch (@compileVar("arch")) {
2020 x86_64 => {
2121 argc = asm("mov (%%rsp), %[argc]": [argc] "=r" (-> usize));
......@@ -44,8 +44,9 @@ fn callMainAndExit() -> unreachable {
4444 linux.exit(0);
4545}
4646
47#condition(want_main_symbol)
4847export fn main(c_argc: i32, c_argv: &&u8) -> i32 {
48 @setFnVisible(this, want_main_symbol);
49
4950 argc = usize(c_argc);
5051 argv = c_argv;
5152 callMain() %% return 1;
std/builtin.zig+4-2
......@@ -1,8 +1,9 @@
11// These functions are provided when not linking against libc because LLVM
22// sometimes generates code that calls them.
33
4#debug_safety(false)
54export fn memset(dest: &u8, c: u8, n: usize) -> &u8 {
5 @setDebugSafety(this, false);
6
67 var index: usize = 0;
78 while (index != n) {
89 dest[index] = c;
......@@ -11,8 +12,9 @@ export fn memset(dest: &u8, c: u8, n: usize) -> &u8 {
1112 return dest;
1213}
1314
14#debug_safety(false)
1515export fn memcpy(noalias dest: &u8, noalias src: &const u8, n: usize) -> &u8 {
16 @setDebugSafety(this, false);
17
1618 var index: usize = 0;
1719 while (index != n) {
1820 dest[index] = src[index];
std/compiler_rt.zig+10-6
......@@ -8,18 +8,19 @@ const udwords = [2]su_int;
88const low = if (@compileVar("is_big_endian")) 1 else 0;
99const high = 1 - low;
1010
11#debug_safety(false)
1211export fn __udivdi3(a: du_int, b: du_int) -> du_int {
12 @setDebugSafety(this, false);
1313 return __udivmoddi4(a, b, null);
1414}
1515
16#debug_safety(false)
1716fn du_int_to_udwords(x: du_int) -> udwords {
17 @setDebugSafety(this, false);
1818 return *(&udwords)(&x);
1919}
2020
21#debug_safety(false)
2221export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
22 @setDebugSafety(this, false);
23
2324 const n_uword_bits = @sizeOf(su_int) * CHAR_BIT;
2425 const n_udword_bits = @sizeOf(du_int) * CHAR_BIT;
2526 var n = du_int_to_udwords(a);
......@@ -203,15 +204,17 @@ export fn __udivmoddi4(a: du_int, b: du_int, maybe_rem: ?&du_int) -> du_int {
203204 return *(&du_int)(&q[0]);
204205}
205206
206#debug_safety(false)
207207export fn __umoddi3(a: du_int, b: du_int) -> du_int {
208 @setDebugSafety(this, false);
209
208210 var r: du_int = undefined;
209211 __udivmoddi4(a, b, &r);
210212 return r;
211213}
212214
213#attribute("test")
214215fn test_umoddi3() {
216 @setFnTest(this, true);
217
215218 test_one_umoddi3(0, 1, 0);
216219 test_one_umoddi3(2, 1, 0);
217220 test_one_umoddi3(0x8000000000000000, 1, 0x0);
......@@ -224,8 +227,9 @@ fn test_one_umoddi3(a: du_int, b: du_int, expected_r: du_int) {
224227 assert(r == expected_r);
225228}
226229
227#attribute("test")
228230fn test_udivmoddi4() {
231 @setFnTest(this, true);
232
229233 const cases = [][4]du_int {
230234 []du_int{0x0000000000000000, 0x0000000000000001, 0x0000000000000000, 0x0000000000000000},
231235 []du_int{0x0000000080000000, 0x0000000100000001, 0x0000000000000000, 0x0000000080000000},
std/cstr.zig+6-3
......@@ -126,8 +126,9 @@ pub struct CBuf {
126126 }
127127}
128128
129#attribute("test")
130129fn testSimpleCBuf() {
130 @setFnTest(this, true);
131
131132 var buf = %%CBuf.initEmpty(&debug.global_allocator);
132133 assert(buf.len() == 0);
133134 %%buf.appendCStr(c"hello");
......@@ -146,12 +147,14 @@ fn testSimpleCBuf() {
146147 assert(buf.startsWithCBuf(&buf2));
147148}
148149
149#attribute("test")
150150fn testCompileTimeStrCmp() {
151 @setFnTest(this, true);
152
151153 assert(@constEval(cmp(c"aoeu", c"aoez") == -1));
152154}
153155
154#attribute("test")
155156fn testCompileTimeStrLen() {
157 @setFnTest(this, true);
158
156159 assert(@constEval(len(c"123456789") == 9));
157160}
std/hash_map.zig+2-1
......@@ -230,8 +230,9 @@ pub struct SmallHashMap(K: type, V: type, hash: fn(key: K)->u32, eql: fn(a: K, b
230230 }
231231}
232232
233#attribute("test")
234233fn basicHashMapTest() {
234 @setFnTest(this, true);
235
235236 var map: HashMap(i32, i32, hash_i32, eql_i32) = undefined;
236237 map.init(&debug.global_allocator);
237238 defer map.deinit();
std/io.zig+2-1
......@@ -423,8 +423,9 @@ fn bufPrintUnsigned(inline T: type, out_buf: []u8, x: T) -> usize {
423423 return len;
424424}
425425
426#attribute("test")
427426fn parseU64DigitTooBig() {
427 @setFnTest(this, true);
428
428429 parseUnsigned(u64, "123a", 10) %% |err| {
429430 if (err == error.InvalidChar) return;
430431 @unreachable();
std/list.zig+2-1
......@@ -49,8 +49,9 @@ pub struct List(T: type) {
4949 }
5050}
5151
52#attribute("test")
5352fn basicListTest() {
53 @setFnTest(this, true);
54
5455 var list = List(i32).init(&debug.global_allocator);
5556 defer list.deinit();
5657
std/mem.zig+1-1
......@@ -77,8 +77,8 @@ pub fn sliceAsInt(buf: []u8, is_be: bool, inline T: type) -> T {
7777 return result;
7878}
7979
80#attribute("test")
8180fn testSliceAsInt() {
81 @setFnTest(this, true);
8282 {
8383 const buf = []u8{0x00, 0x00, 0x12, 0x34};
8484 const answer = sliceAsInt(buf[0...], true, u64);
std/net.zig+8-4
......@@ -180,8 +180,9 @@ error Overflow;
180180error JunkAtEnd;
181181error Incomplete;
182182
183#static_eval_enable(false)
184183fn parseIp6(buf: []const u8) -> %Address {
184 @setFnStaticEval(this, false);
185
185186 var result: Address = undefined;
186187 result.family = linux.AF_INET6;
187188 result.scope_id = 0;
......@@ -318,8 +319,9 @@ fn parseIp4(buf: []const u8) -> %u32 {
318319}
319320
320321
321#attribute("test")
322322fn testParseIp4() {
323 @setFnTest(this, true);
324
323325 assert(%%parseIp4("127.0.0.1") == endian.swapIfLe(u32, 0x7f000001));
324326 switch (parseIp4("256.0.0.1")) { Overflow => {}, else => @unreachable(), }
325327 switch (parseIp4("x.0.0.1")) { InvalidChar => {}, else => @unreachable(), }
......@@ -328,8 +330,9 @@ fn testParseIp4() {
328330 switch (parseIp4("100..0.1")) { InvalidChar => {}, else => @unreachable(), }
329331}
330332
331#attribute("test")
332333fn testParseIp6() {
334 @setFnTest(this, true);
335
333336 {
334337 const addr = %%parseIp6("FF01:0:0:0:0:0:0:FB");
335338 assert(addr.addr[0] == 0xff);
......@@ -338,8 +341,9 @@ fn testParseIp6() {
338341 }
339342}
340343
341#attribute("test")
342344fn testLookupSimpleIp() {
345 @setFnTest(this, true);
346
343347 {
344348 var addrs_buf: [5]Address = undefined;
345349 const addrs = %%lookup("192.168.1.1", addrs_buf);
std/os.zig+1-2
......@@ -27,8 +27,7 @@ pub fn getRandomBytes(buf: []u8) -> %void {
2727 }
2828}
2929
30#attribute("cold")
31pub fn abort() -> unreachable {
30pub coldcc fn abort() -> unreachable {
3231 switch (@compileVar("os")) {
3332 linux, darwin => {
3433 system.raise(system.SIGABRT);
std/rand.zig+6-3
......@@ -153,8 +153,9 @@ struct MersenneTwister(
153153 }
154154}
155155
156#attribute("test")
157156fn testFloat32() {
157 @setFnTest(this, true);
158
158159 var r: Rand = undefined;
159160 r.init(42);
160161
......@@ -165,8 +166,9 @@ fn testFloat32() {
165166 }}
166167}
167168
168#attribute("test")
169169fn testMT19937_64() {
170 @setFnTest(this, true);
171
170172 var rng: MT19937_64 = undefined;
171173 rng.init(rand_test.mt64_seed);
172174 for (rand_test.mt64_data) |value| {
......@@ -174,8 +176,9 @@ fn testMT19937_64() {
174176 }
175177}
176178
177#attribute("test")
178179fn testMT19937_32() {
180 @setFnTest(this, true);
181
179182 var rng: MT19937_32 = undefined;
180183 rng.init(rand_test.mt32_seed);
181184 for (rand_test.mt32_data) |value| {
std/str.zig+3-2
......@@ -12,8 +12,9 @@ pub fn sliceEql(inline T: type, a: []const T, b: []const T) -> bool {
1212 return true;
1313}
1414
15#attribute("test")
16fn stringEquality() {
15fn testStringEquality() {
16 @setFnTest(this, true);
17
1718 assert(eql("abcd", "abcd"));
1819 assert(!eql("abcdef", "abZdef"));
1920 assert(!eql("abcdefg", "abcdef"));
test/cases/const_slice_child.zig+10-5
......@@ -2,8 +2,9 @@ const assert = @import("std").debug.assert;
22
33var argv: &&const u8 = undefined;
44
5#attribute("test")
65fn constSliceChild() {
6 @setFnTest(this, true);
7
78 const strs = ([]&const u8) {
89 c"one",
910 c"two",
......@@ -13,16 +14,18 @@ fn constSliceChild() {
1314 bar(strs.len);
1415}
1516
16#static_eval_enable(false)
1717fn foo(args: [][]const u8) {
18 @setFnStaticEval(this, false);
19
1820 assert(args.len == 3);
1921 assert(streql(args[0], "one"));
2022 assert(streql(args[1], "two"));
2123 assert(streql(args[2], "three"));
2224}
2325
24#static_eval_enable(false)
2526fn bar(argc: usize) {
27 @setFnStaticEval(this, false);
28
2629 var args: [argc][]u8 = undefined;
2730 for (args) |_, i| {
2831 const ptr = argv[i];
......@@ -31,15 +34,17 @@ fn bar(argc: usize) {
3134 foo(args);
3235}
3336
34#static_eval_enable(false)
3537fn strlen(ptr: &const u8) -> usize {
38 @setFnStaticEval(this, false);
39
3640 var count: usize = 0;
3741 while (ptr[count] != 0; count += 1) {}
3842 return count;
3943}
4044
41#static_eval_enable(false)
4245fn streql(a: []const u8, b: []const u8) -> bool {
46 @setFnStaticEval(this, false);
47
4348 if (a.len != b.len) return false;
4449 for (a) |item, index| {
4550 if (b[index] != item) return false;
test/cases/enum_to_int.zig+16-9
......@@ -8,17 +8,24 @@ enum Number {
88 Four,
99}
1010
11#attribute("test")
1211fn enumToInt() {
13 shouldEqual(Number.Zero, 0);
14 shouldEqual(Number.One, 1);
15 shouldEqual(Number.Two, 2);
16 shouldEqual(Number.Three, 3);
17 shouldEqual(Number.Four, 4);
12 @setFnTest(this, true);
13
14 shouldEqual(false, Number.Zero, 0);
15 shouldEqual(false, Number.One, 1);
16 shouldEqual(false, Number.Two, 2);
17 shouldEqual(false, Number.Three, 3);
18 shouldEqual(false, Number.Four, 4);
19
20 shouldEqual(true, Number.Zero, 0);
21 shouldEqual(true, Number.One, 1);
22 shouldEqual(true, Number.Two, 2);
23 shouldEqual(true, Number.Three, 3);
24 shouldEqual(true, Number.Four, 4);
1825}
1926
20// TODO add test with this disabled
21#static_eval_enable(false)
22fn shouldEqual(n: Number, expected: usize) {
27fn shouldEqual(inline static_eval: bool, n: Number, expected: usize) {
28 @setFnStaticEval(this, static_eval);
29
2330 assert(usize(n) == expected);
2431}
test/cases/enum_with_members.zig+2-1
......@@ -15,8 +15,9 @@ enum ET {
1515 }
1616}
1717
18#attribute("test")
1918fn enumWithMembers() {
19 @setFnTest(this, true);
20
2021 const a = ET.SINT { -42 };
2122 const b = ET.UINT { 42 };
2223 var buf: [20]u8 = undefined;
test/cases/max_value_type.zig+2-1
......@@ -1,7 +1,8 @@
11const assert = @import("std").debug.assert;
22
3#attribute("test")
43fn maxValueType() {
4 @setFnTest(this, true);
5
56 // If the type of @maxValue(i32) was i32 then this implicit cast to
67 // u32 would not work. But since the value is a number literal,
78 // it works fine.
test/cases/maybe_return.zig+5-3
......@@ -1,15 +1,17 @@
11const assert = @import("std").debug.assert;
22
3#attribute("test")
43fn maybeReturn() {
4 @setFnTest(this, true);
5
56 assert(??foo(1235));
67 assert(if (const _ ?= foo(null)) false else true);
78 assert(!??foo(1234));
89}
910
10// TODO add another function with static_eval_enable(true)
11#static_eval_enable(false)
11// TODO test static eval maybe return
1212fn foo(x: ?i32) -> ?bool {
13 @setFnStaticEval(this, false);
14
1315 const value = ?return x;
1416 return value > 1234;
1517}
test/cases/namespace_depends_on_compile_var/index.zig+2-1
......@@ -1,7 +1,8 @@
11const assert = @import("std").debug.assert;
22
3#attribute("test")
43fn namespaceDependsOnCompileVar() {
4 @setFnTest(this, true);
5
56 if (some_namespace.a_bool) {
67 assert(some_namespace.a_bool);
78 } else {
test/cases/pub_enum/index.zig+4-2
......@@ -1,16 +1,18 @@
11const assert = @import("std").debug.assert;
22const other = @import("other.zig");
33
4#attribute("test")
54fn pubEnum() {
5 @setFnTest(this, true);
6
67 pubEnumTest(other.APubEnum.Two);
78}
89fn pubEnumTest(foo: other.APubEnum) {
910 assert(foo == other.APubEnum.Two);
1011}
1112
12#attribute("test")
1313fn castWithImportedSymbol() {
14 @setFnTest(this, true);
15
1416 assert(other.size_t(42) == 42);
1517}
1618
test/cases/return_type_type.zig+2-1
......@@ -10,8 +10,9 @@ pub struct SmallList(inline T: type, inline STATIC_SIZE: usize) {
1010 prealloc_items: [STATIC_SIZE]T,
1111}
1212
13#attribute("test")
1413fn functionWithReturnTypeType() {
14 @setFnTest(this, true);
15
1516 var list: List(i32) = undefined;
1617 var list2: List(i32) = undefined;
1718 list.length = 10;
test/cases/sizeof_and_typeof.zig+2-1
......@@ -1,7 +1,8 @@
11const assert = @import("std").debug.assert;
22
3#attribute("test")
43fn sizeofAndTypeOf() {
4 @setFnTest(this, true);
5
56 const y: @typeOf(x) = 120;
67 assert(@sizeOf(@typeOf(y)) == 2);
78}
test/cases/struct_contains_slice_of_itself.zig+2-1
......@@ -5,8 +5,9 @@ struct Node {
55 children: []Node,
66}
77
8#attribute("test")
98fn structContainsSliceOfItself() {
9 @setFnTest(this, true);
10
1011 var nodes = []Node {
1112 Node {
1213 .payload = 1,
test/cases/switch_prong_err_enum.zig+4-2
......@@ -14,16 +14,18 @@ enum FormValue {
1414 Other: bool,
1515}
1616
17#static_eval_enable(false)
1817fn doThing(form_id: u64) -> %FormValue {
18 @setFnStaticEval(this, false);
19
1920 return switch (form_id) {
2021 17 => FormValue.Address { %return readOnce() },
2122 else => error.InvalidDebugInfo,
2223 }
2324}
2425
25#attribute("test")
2626fn switchProngReturnsErrorEnum() {
27 @setFnTest(this, true);
28
2729 %%doThing(17);
2830 assert(read_count == 1);
2931}
test/cases/switch_prong_implicit_cast.zig+4-2
......@@ -7,8 +7,9 @@ enum FormValue {
77
88error Whatever;
99
10#static_eval_enable(false)
1110fn foo(id: u64) -> %FormValue {
11 @setFnStaticEval(this, false);
12
1213 switch (id) {
1314 2 => FormValue.Two { true },
1415 1 => FormValue.One,
......@@ -16,8 +17,9 @@ fn foo(id: u64) -> %FormValue {
1617 }
1718}
1819
19#attribute("test")
2020fn switchProngImplicitCast() {
21 @setFnTest(this, true);
22
2123 const result = switch (%%foo(2)) {
2224 One => false,
2325 Two => |x| x,
test/cases/this.zig+6-3
......@@ -25,13 +25,15 @@ fn factorial(x: i32) -> i32 {
2525 }
2626}
2727
28#attribute("test")
2928fn thisReferToModuleCallPrivateFn() {
29 @setFnTest(this, true);
30
3031 assert(module.add(1, 2) == 3);
3132}
3233
33#attribute("test")
3434fn thisReferToContainer() {
35 @setFnTest(this, true);
36
3537 var pt = Point(i32) {
3638 .x = 12,
3739 .y = 34,
......@@ -41,7 +43,8 @@ fn thisReferToContainer() {
4143 assert(pt.y == 35);
4244}
4345
44#attribute("test")
4546fn thisReferToFn() {
47 @setFnTest(this, true);
48
4649 assert(factorial(5) == 120);
4750}
test/cases/var_params.zig+6-3
......@@ -1,7 +1,8 @@
11const assert = @import("std").debug.assert;
22
3#attribute("test")
43fn varParams() {
4 @setFnTest(this, true);
5
56 assert(max_i32(12, 34) == 34);
67 assert(max_f64(1.2, 3.4) == 3.4);
78
......@@ -21,12 +22,14 @@ fn max_f64(a: f64, b: f64) -> f64 {
2122 max(a, b)
2223}
2324
24#static_eval_enable(false)
2525fn max_i32_noeval(a: i32, b: i32) -> i32 {
26 @setFnStaticEval(this, false);
27
2628 max(a, b)
2729}
2830
29#static_eval_enable(false)
3031fn max_f64_noeval(a: f64, b: f64) -> f64 {
32 @setFnStaticEval(this, false);
33
3134 max(a, b)
3235}
test/cases/zeroes.zig+2-1
......@@ -7,8 +7,9 @@ struct Foo {
77 d: ?i32,
88}
99
10#attribute("test")
1110fn initializing_a_struct_with_zeroes() {
11 @setFnTest(this, true);
12
1213 const foo: Foo = zeroes;
1314 assert(foo.a == 0.0);
1415 assert(foo.b == 0);
test/run_tests.cpp+40-28
......@@ -279,8 +279,9 @@ pub fn bar_function() {
279279 )SOURCE");
280280
281281 add_source_file(tc, "other.zig", R"SOURCE(
282#static_eval_enable(false)
283282pub fn foo_function() -> bool {
283 @setFnStaticEval(this, false);
284
284285 // this one conflicts with the one from foo
285286 return true;
286287}
......@@ -686,14 +687,6 @@ fn a() {}
686687fn a() {}
687688 )SOURCE", 1, ".tmp_source.zig:3:1: error: redefinition of 'a'");
688689
689 add_compile_fail_case("bad directive", R"SOURCE(
690#bogus1("")
691extern fn b();
692#bogus2("")
693fn a() {}
694 )SOURCE", 2, ".tmp_source.zig:2:1: error: invalid directive: 'bogus1'",
695 ".tmp_source.zig:4:1: error: invalid directive: 'bogus2'");
696
697690 add_compile_fail_case("unreachable with return", R"SOURCE(
698691fn a() -> unreachable {return;}
699692 )SOURCE", 1, ".tmp_source.zig:2:24: error: expected type 'unreachable', got 'void'");
......@@ -1280,8 +1273,11 @@ struct Foo {
12801273 x: i32,
12811274}
12821275const a = get_it();
1283#static_eval_enable(false)
1284fn get_it() -> Foo { Foo {.x = 13} }
1276fn get_it() -> Foo {
1277 @setFnStaticEval(this, false);
1278 Foo {.x = 13}
1279}
1280
12851281 )SOURCE", 1, ".tmp_source.zig:5:17: error: unable to evaluate constant expression");
12861282
12871283 add_compile_fail_case("undeclared identifier error should mark fn as impure", R"SOURCE(
......@@ -1316,8 +1312,11 @@ fn foo() {
13161312 else => 3,
13171313 };
13181314}
1319#static_eval_enable(false)
1320fn bar() -> i32 { 2 }
1315fn bar() -> i32 {
1316 @setFnStaticEval(this, false);
1317 2
1318}
1319
13211320 )SOURCE", 1, ".tmp_source.zig:3:15: error: unable to infer expression type");
13221321
13231322 add_compile_fail_case("atomic orderings of cmpxchg", R"SOURCE(
......@@ -1458,7 +1457,6 @@ pub struct SmallList(inline T: type, inline STATIC_SIZE: usize) {
14581457 prealloc_items: [STATIC_SIZE]T,
14591458}
14601459
1461#attribute("test")
14621460fn function_with_return_type_type() {
14631461 var list: List(i32) = undefined;
14641462 list.length = 10;
......@@ -1623,12 +1621,15 @@ pub fn main(args: [][]u8) -> %void {
16231621 const a = []i32{1, 2, 3, 4};
16241622 baz(bar(a));
16251623}
1626#static_eval_enable(false)
16271624fn bar(a: []i32) -> i32 {
1625 @setFnStaticEval(this, false);
1626
16281627 a[4]
16291628}
1630#static_eval_enable(false)
1631fn baz(a: i32) {}
1629fn baz(a: i32) {
1630 @setFnStaticEval(this, false);
1631}
1632
16321633 )SOURCE");
16331634
16341635 add_debug_safety_case("integer addition overflow", R"SOURCE(
......@@ -1637,8 +1638,9 @@ pub fn main(args: [][]u8) -> %void {
16371638 const x = add(65530, 10);
16381639 if (x == 0) return error.Whatever;
16391640}
1640#static_eval_enable(false)
16411641fn add(a: u16, b: u16) -> u16 {
1642 @setFnStaticEval(this, false);
1643
16421644 a + b
16431645}
16441646 )SOURCE");
......@@ -1649,8 +1651,9 @@ pub fn main(args: [][]u8) -> %void {
16491651 const x = sub(10, 20);
16501652 if (x == 0) return error.Whatever;
16511653}
1652#static_eval_enable(false)
16531654fn sub(a: u16, b: u16) -> u16 {
1655 @setFnStaticEval(this, false);
1656
16541657 a - b
16551658}
16561659 )SOURCE");
......@@ -1661,8 +1664,9 @@ pub fn main(args: [][]u8) -> %void {
16611664 const x = mul(300, 6000);
16621665 if (x == 0) return error.Whatever;
16631666}
1664#static_eval_enable(false)
16651667fn mul(a: u16, b: u16) -> u16 {
1668 @setFnStaticEval(this, false);
1669
16661670 a * b
16671671}
16681672 )SOURCE");
......@@ -1673,8 +1677,9 @@ pub fn main(args: [][]u8) -> %void {
16731677 const x = neg(-32768);
16741678 if (x == 0) return error.Whatever;
16751679}
1676#static_eval_enable(false)
16771680fn neg(a: i16) -> i16 {
1681 @setFnStaticEval(this, false);
1682
16781683 -a
16791684}
16801685 )SOURCE");
......@@ -1685,8 +1690,9 @@ pub fn main(args: [][]u8) -> %void {
16851690 const x = shl(-16385, 1);
16861691 if (x == 0) return error.Whatever;
16871692}
1688#static_eval_enable(false)
16891693fn shl(a: i16, b: i16) -> i16 {
1694 @setFnStaticEval(this, false);
1695
16901696 a << b
16911697}
16921698 )SOURCE");
......@@ -1697,8 +1703,9 @@ pub fn main(args: [][]u8) -> %void {
16971703 const x = shl(0b0010111111111111, 3);
16981704 if (x == 0) return error.Whatever;
16991705}
1700#static_eval_enable(false)
17011706fn shl(a: u16, b: u16) -> u16 {
1707 @setFnStaticEval(this, false);
1708
17021709 a << b
17031710}
17041711 )SOURCE");
......@@ -1708,8 +1715,9 @@ error Whatever;
17081715pub fn main(args: [][]u8) -> %void {
17091716 const x = div0(999, 0);
17101717}
1711#static_eval_enable(false)
17121718fn div0(a: i32, b: i32) -> i32 {
1719 @setFnStaticEval(this, false);
1720
17131721 a / b
17141722}
17151723 )SOURCE");
......@@ -1720,8 +1728,9 @@ pub fn main(args: [][]u8) -> %void {
17201728 const x = divExact(10, 3);
17211729 if (x == 0) return error.Whatever;
17221730}
1723#static_eval_enable(false)
17241731fn divExact(a: i32, b: i32) -> i32 {
1732 @setFnStaticEval(this, false);
1733
17251734 @divExact(a, b)
17261735}
17271736 )SOURCE");
......@@ -1732,8 +1741,9 @@ pub fn main(args: [][]u8) -> %void {
17321741 const x = widenSlice([]u8{1, 2, 3, 4, 5});
17331742 if (x.len == 0) return error.Whatever;
17341743}
1735#static_eval_enable(false)
17361744fn widenSlice(slice: []u8) -> []i32 {
1745 @setFnStaticEval(this, false);
1746
17371747 ([]i32)(slice)
17381748}
17391749 )SOURCE");
......@@ -1744,8 +1754,9 @@ pub fn main(args: [][]u8) -> %void {
17441754 const x = shorten_cast(200);
17451755 if (x == 0) return error.Whatever;
17461756}
1747#static_eval_enable(false)
17481757fn shorten_cast(x: i32) -> i8 {
1758 @setFnStaticEval(this, false);
1759
17491760 i8(x)
17501761}
17511762 )SOURCE");
......@@ -1756,8 +1767,9 @@ pub fn main(args: [][]u8) -> %void {
17561767 const x = unsigned_cast(-10);
17571768 if (x == 0) return error.Whatever;
17581769}
1759#static_eval_enable(false)
17601770fn unsigned_cast(x: i32) -> u32 {
1771 @setFnStaticEval(this, false);
1772
17611773 u32(x)
17621774}
17631775 )SOURCE");
test/self_hosted.zig+312-154
......@@ -19,12 +19,15 @@ const test_this = @import("cases/this.zig");
1919// normal comment
2020/// this is a documentation comment
2121/// doc comment line 2
22#attribute("test")
23fn emptyFunctionWithComments() {}
22fn emptyFunctionWithComments() {
23 @setFnTest(this, true);
24}
25
2426
2527
26#attribute("test")
2728fn ifStatements() {
29 @setFnTest(this, true);
30
2831 shouldBeEqual(1, 1);
2932 firstEqlThird(2, 1, 2);
3033}
......@@ -48,8 +51,9 @@ fn firstEqlThird(a: i32, b: i32, c: i32) {
4851}
4952
5053
51#attribute("test")
5254fn params() {
55 @setFnTest(this, true);
56
5357 assert(testParamsAdd(22, 11) == 33);
5458}
5559fn testParamsAdd(a: i32, b: i32) -> i32 {
......@@ -57,8 +61,9 @@ fn testParamsAdd(a: i32, b: i32) -> i32 {
5761}
5862
5963
60#attribute("test")
6164fn localVariables() {
65 @setFnTest(this, true);
66
6267 testLocVars(2);
6368}
6469fn testLocVars(b: i32) {
......@@ -66,14 +71,16 @@ fn testLocVars(b: i32) {
6671 if (a + b != 3) @unreachable();
6772}
6873
69#attribute("test")
7074fn boolLiterals() {
75 @setFnTest(this, true);
76
7177 assert(true);
7278 assert(!false);
7379}
7480
75#attribute("test")
7681fn voidParameters() {
82 @setFnTest(this, true);
83
7784 voidFun(1, void{}, 2, {});
7885}
7986fn voidFun(a : i32, b : void, c : i32, d : void) {
......@@ -83,8 +90,9 @@ fn voidFun(a : i32, b : void, c : i32, d : void) {
8390 return vv;
8491}
8592
86#attribute("test")
8793fn mutableLocalVariables() {
94 @setFnTest(this, true);
95
8896 var zero : i32 = 0;
8997 assert(zero == 0);
9098
......@@ -95,8 +103,9 @@ fn mutableLocalVariables() {
95103 assert(i == 3);
96104}
97105
98#attribute("test")
99106fn arrays() {
107 @setFnTest(this, true);
108
100109 var array : [5]u32 = undefined;
101110
102111 var i : u32 = 0;
......@@ -120,8 +129,9 @@ fn getArrayLen(a: []u32) -> usize {
120129 a.len
121130}
122131
123#attribute("test")
124132fn shortCircuit() {
133 @setFnTest(this, true);
134
125135 var hit_1 = false;
126136 var hit_2 = false;
127137 var hit_3 = false;
......@@ -148,13 +158,15 @@ fn shortCircuit() {
148158 assert(hit_4);
149159}
150160
151#static_eval_enable(false)
152161fn assertRuntime(b: bool) {
162 @setFnStaticEval(this, false);
163
153164 if (!b) @unreachable()
154165}
155166
156#attribute("test")
157167fn modifyOperators() {
168 @setFnTest(this, true);
169
158170 var i : i32 = 0;
159171 i += 5; assert(i == 5);
160172 i -= 2; assert(i == 3);
......@@ -171,8 +183,9 @@ fn modifyOperators() {
171183}
172184
173185
174#attribute("test")
175186fn separateBlockScopes() {
187 @setFnTest(this, true);
188
176189 {
177190 const no_conflict : i32 = 5;
178191 assert(no_conflict == 5);
......@@ -186,8 +199,9 @@ fn separateBlockScopes() {
186199}
187200
188201
189#attribute("test")
190202fn voidStructFields() {
203 @setFnTest(this, true);
204
191205 const foo = VoidStructFieldsFoo {
192206 .a = void{},
193207 .b = 1,
......@@ -204,8 +218,9 @@ struct VoidStructFieldsFoo {
204218
205219
206220
207#attribute("test")
208221pub fn structs() {
222 @setFnTest(this, true);
223
209224 var foo : StructFoo = undefined;
210225 @memset(&foo, 0, @sizeOf(StructFoo));
211226 foo.a += 1;
......@@ -234,8 +249,9 @@ struct Val {
234249 x: i32,
235250}
236251
237#attribute("test")
238252fn structPointToSelf() {
253 @setFnTest(this, true);
254
239255 var root : Node = undefined;
240256 root.val.x = 1;
241257
......@@ -248,8 +264,9 @@ fn structPointToSelf() {
248264 assert(node.next.next.next.val.x == 1);
249265}
250266
251#attribute("test")
252267fn structByvalAssign() {
268 @setFnTest(this, true);
269
253270 var foo1 : StructFoo = undefined;
254271 var foo2 : StructFoo = undefined;
255272
......@@ -269,16 +286,18 @@ fn structInitializer() {
269286const g1 : i32 = 1233 + 1;
270287var g2 : i32 = 0;
271288
272#attribute("test")
273289fn globalVariables() {
290 @setFnTest(this, true);
291
274292 assert(g2 == 0);
275293 g2 = g1;
276294 assert(g2 == 1234);
277295}
278296
279297
280#attribute("test")
281298fn whileLoop() {
299 @setFnTest(this, true);
300
282301 var i : i32 = 0;
283302 while (i < 4) {
284303 i += 1;
......@@ -295,8 +314,9 @@ fn whileLoop2() -> i32 {
295314 }
296315}
297316
298#attribute("test")
299317fn voidArrays() {
318 @setFnTest(this, true);
319
300320 var array: [4]void = undefined;
301321 array[0] = void{};
302322 array[1] = array[2];
......@@ -305,8 +325,9 @@ fn voidArrays() {
305325}
306326
307327
308#attribute("test")
309328fn threeExprInARow() {
329 @setFnTest(this, true);
330
310331 assertFalse(false || false || false);
311332 assertFalse(true && true && false);
312333 assertFalse(1 | 2 | 4 != 7);
......@@ -325,8 +346,9 @@ fn assertFalse(b: bool) {
325346}
326347
327348
328#attribute("test")
329349fn maybeType() {
350 @setFnTest(this, true);
351
330352 const x : ?bool = true;
331353
332354 if (const y ?= x) {
......@@ -353,8 +375,9 @@ fn maybeType() {
353375}
354376
355377
356#attribute("test")
357378fn enumType() {
379 @setFnTest(this, true);
380
358381 const foo1 = EnumTypeFoo.One {13};
359382 const foo2 = EnumTypeFoo.Two {EnumType { .x = 1234, .y = 5678, }};
360383 const bar = EnumTypeBar.B;
......@@ -387,8 +410,9 @@ enum EnumTypeBar {
387410}
388411
389412
390#attribute("test")
391413fn arrayLiteral() {
414 @setFnTest(this, true);
415
392416 const hex_mult = []u16{4096, 256, 16, 1};
393417
394418 assert(hex_mult.len == 4);
......@@ -396,8 +420,9 @@ fn arrayLiteral() {
396420}
397421
398422
399#attribute("test")
400423fn constNumberLiteral() {
424 @setFnTest(this, true);
425
401426 const one = 1;
402427 const eleven = ten + one;
403428
......@@ -406,8 +431,9 @@ fn constNumberLiteral() {
406431const ten = 10;
407432
408433
409#attribute("test")
410434fn errorValues() {
435 @setFnTest(this, true);
436
411437 const a = i32(error.err1);
412438 const b = i32(error.err2);
413439 assert(a != b);
......@@ -417,8 +443,9 @@ error err2;
417443
418444
419445
420#attribute("test")
421446fn fnCallOfStructField() {
447 @setFnTest(this, true);
448
422449 assert(callStructField(Foo {.ptr = aFunc,}) == 13);
423450}
424451
......@@ -434,8 +461,9 @@ fn callStructField(foo: Foo) -> i32 {
434461
435462
436463
437#attribute("test")
438464fn redefinitionOfErrorValuesAllowed() {
465 @setFnTest(this, true);
466
439467 shouldBeNotEqual(error.AnError, error.SecondError);
440468}
441469error AnError;
......@@ -448,8 +476,9 @@ fn shouldBeNotEqual(a: error, b: error) {
448476
449477
450478
451#attribute("test")
452479fn constantEnumWithPayload() {
480 @setFnTest(this, true);
481
453482 var empty = AnEnumWithPayload.Empty;
454483 var full = AnEnumWithPayload.Full {13};
455484 shouldBeEmpty(empty);
......@@ -476,8 +505,9 @@ enum AnEnumWithPayload {
476505}
477506
478507
479#attribute("test")
480508fn continueInForLoop() {
509 @setFnTest(this, true);
510
481511 const array = []i32 {1, 2, 3, 4, 5};
482512 var sum : i32 = 0;
483513 for (array) |x| {
......@@ -491,8 +521,9 @@ fn continueInForLoop() {
491521}
492522
493523
494#attribute("test")
495524fn castBoolToInt() {
525 @setFnTest(this, true);
526
496527 const t = true;
497528 const f = false;
498529 assert(i32(t) == i32(1));
......@@ -506,8 +537,9 @@ fn nonConstCastBoolToInt(t: bool, f: bool) {
506537}
507538
508539
509#attribute("test")
510540fn switchOnEnum() {
541 @setFnTest(this, true);
542
511543 const fruit = Fruit.Orange;
512544 nonConstSwitchOnEnum(fruit);
513545}
......@@ -516,8 +548,9 @@ enum Fruit {
516548 Orange,
517549 Banana,
518550}
519#static_eval_enable(false)
520551fn nonConstSwitchOnEnum(fruit: Fruit) {
552 @setFnStaticEval(this, false);
553
521554 switch (fruit) {
522555 Apple => @unreachable(),
523556 Orange => {},
......@@ -525,12 +558,14 @@ fn nonConstSwitchOnEnum(fruit: Fruit) {
525558 }
526559}
527560
528#attribute("test")
529561fn switchStatement() {
562 @setFnTest(this, true);
563
530564 nonConstSwitch(SwitchStatmentFoo.C);
531565}
532#static_eval_enable(false)
533566fn nonConstSwitch(foo: SwitchStatmentFoo) {
567 @setFnStaticEval(this, false);
568
534569 const val: i32 = switch (foo) {
535570 A => 1,
536571 B => 2,
......@@ -547,8 +582,9 @@ enum SwitchStatmentFoo {
547582}
548583
549584
550#attribute("test")
551585fn switchProngWithVar() {
586 @setFnTest(this, true);
587
552588 switchProngWithVarFn(SwitchProngWithVarEnum.One {13});
553589 switchProngWithVarFn(SwitchProngWithVarEnum.Two {13.0});
554590 switchProngWithVarFn(SwitchProngWithVarEnum.Meh);
......@@ -558,8 +594,9 @@ enum SwitchProngWithVarEnum {
558594 Two: f32,
559595 Meh,
560596}
561#static_eval_enable(false)
562597fn switchProngWithVarFn(a: SwitchProngWithVarEnum) {
598 @setFnStaticEval(this, false);
599
563600 switch(a) {
564601 One => |x| {
565602 if (x != 13) @unreachable();
......@@ -574,13 +611,15 @@ fn switchProngWithVarFn(a: SwitchProngWithVarEnum) {
574611}
575612
576613
577#attribute("test")
578614fn errReturnInAssignment() {
615 @setFnTest(this, true);
616
579617 %%doErrReturnInAssignment();
580618}
581619
582#static_eval_enable(false)
583620fn doErrReturnInAssignment() -> %void {
621 @setFnStaticEval(this, false);
622
584623 var x : i32 = undefined;
585624 x = %return makeANonErr();
586625}
......@@ -591,15 +630,17 @@ fn makeANonErr() -> %i32 {
591630
592631
593632
594#attribute("test")
595633fn rhsMaybeUnwrapReturn() {
634 @setFnTest(this, true);
635
596636 const x = ?true;
597637 const y = x ?? return;
598638}
599639
600640
601#attribute("test")
602641fn implicitCastFnUnreachableReturn() {
642 @setFnTest(this, true);
643
603644 wantsFnWithVoid(fnWithUnreachable);
604645}
605646
......@@ -610,15 +651,17 @@ fn fnWithUnreachable() -> unreachable {
610651}
611652
612653
613#attribute("test")
614654fn explicitCastMaybePointers() {
655 @setFnTest(this, true);
656
615657 const a: ?&i32 = undefined;
616658 const b: ?&f32 = (?&f32)(a);
617659}
618660
619661
620#attribute("test")
621662fn constExprEvalOnSingleExprBlocks() {
663 @setFnTest(this, true);
664
622665 assert(constExprEvalOnSingleExprBlocksFn(1, true) == 3);
623666}
624667
......@@ -635,14 +678,16 @@ fn constExprEvalOnSingleExprBlocksFn(x: i32, b: bool) -> i32 {
635678}
636679
637680
638#attribute("test")
639681fn builtinConstEval() {
682 @setFnTest(this, true);
683
640684 const x : i32 = @constEval(1 + 2 + 3);
641685 assert(x == @constEval(6));
642686}
643687
644#attribute("test")
645688fn slicing() {
689 @setFnTest(this, true);
690
646691 var array : [20]i32 = undefined;
647692
648693 array[5] = 1234;
......@@ -659,8 +704,9 @@ fn slicing() {
659704}
660705
661706
662#attribute("test")
663707fn memcpyAndMemsetIntrinsics() {
708 @setFnTest(this, true);
709
664710 var foo : [20]u8 = undefined;
665711 var bar : [20]u8 = undefined;
666712
......@@ -671,31 +717,36 @@ fn memcpyAndMemsetIntrinsics() {
671717}
672718
673719
674#attribute("test")
675fn arrayDotLenConstExpr() { }
720fn arrayDotLenConstExpr() {
721 @setFnTest(this, true);
722}
723
676724struct ArrayDotLenConstExpr {
677725 y: [@constEval(some_array.len)]u8,
678726}
679727const some_array = []u8 {0, 1, 2, 3};
680728
681729
682#attribute("test")
683730fn countLeadingZeroes() {
731 @setFnTest(this, true);
732
684733 assert(@clz(u8, 0b00001010) == 4);
685734 assert(@clz(u8, 0b10001010) == 0);
686735 assert(@clz(u8, 0b00000000) == 8);
687736}
688737
689#attribute("test")
690738fn countTrailingZeroes() {
739 @setFnTest(this, true);
740
691741 assert(@ctz(u8, 0b10100000) == 5);
692742 assert(@ctz(u8, 0b10001010) == 1);
693743 assert(@ctz(u8, 0b00000000) == 8);
694744}
695745
696746
697#attribute("test")
698747fn multilineString() {
748 @setFnTest(this, true);
749
699750 const s1 =
700751 \\one
701752 \\two)
......@@ -705,8 +756,9 @@ fn multilineString() {
705756 assert(str.eql(s1, s2));
706757}
707758
708#attribute("test")
709759fn multilineCString() {
760 @setFnTest(this, true);
761
710762 const s1 =
711763 c\\one
712764 c\\two)
......@@ -718,8 +770,9 @@ fn multilineCString() {
718770
719771
720772
721#attribute("test")
722773fn simpleGenericFn() {
774 @setFnTest(this, true);
775
723776 assert(max(i32, 3, -1) == 3);
724777 assert(max(f32, 0.123, 0.456) == 0.456);
725778 assert(add(2, 3) == 5);
......@@ -734,8 +787,9 @@ fn add(inline a: i32, b: i32) -> i32 {
734787}
735788
736789
737#attribute("test")
738790fn constantEqualFunctionPointers() {
791 @setFnTest(this, true);
792
739793 const alias = emptyFn;
740794 assert(@constEval(emptyFn == alias));
741795}
......@@ -743,44 +797,50 @@ fn constantEqualFunctionPointers() {
743797fn emptyFn() {}
744798
745799
746#attribute("test")
747800fn genericMallocFree() {
801 @setFnTest(this, true);
802
748803 const a = %%memAlloc(u8, 10);
749804 memFree(u8, a);
750805}
751806const some_mem : [100]u8 = undefined;
752#static_eval_enable(false)
753807fn memAlloc(inline T: type, n: usize) -> %[]T {
808 @setFnStaticEval(this, false);
809
754810 return (&T)(&some_mem[0])[0...n];
755811}
756812fn memFree(inline T: type, mem: []T) { }
757813
758814
759#attribute("test")
760815fn callFnWithEmptyString() {
816 @setFnTest(this, true);
817
761818 acceptsString("");
762819}
763820
764821fn acceptsString(foo: []u8) { }
765822
766823
767#attribute("test")
768824fn hexEscape() {
825 @setFnTest(this, true);
826
769827 assert(str.eql("\x68\x65\x6c\x6c\x6f", "hello"));
770828}
771829
772830
773831error AnError;
774832error ALongerErrorName;
775#attribute("test")
776833fn errorNameString() {
834 @setFnTest(this, true);
835
777836 assert(str.eql(@errorName(error.AnError), "AnError"));
778837 assert(str.eql(@errorName(error.ALongerErrorName), "ALongerErrorName"));
779838}
780839
781840
782#attribute("test")
783841fn gotoAndLabels() {
842 @setFnTest(this, true);
843
784844 gotoLoop();
785845 assert(goto_counter == 10);
786846}
......@@ -799,12 +859,14 @@ var goto_counter: i32 = 0;
799859
800860
801861
802#attribute("test")
803862fn gotoLeaveDeferScope() {
863 @setFnTest(this, true);
864
804865 testGotoLeaveDeferScope(true);
805866}
806#static_eval_enable(false)
807867fn testGotoLeaveDeferScope(b: bool) {
868 @setFnStaticEval(this, false);
869
808870 var it_worked = false;
809871
810872 goto entry;
......@@ -819,8 +881,9 @@ entry:
819881}
820882
821883
822#attribute("test")
823884fn castUndefined() {
885 @setFnTest(this, true);
886
824887 const array: [100]u8 = undefined;
825888 const slice = ([]u8)(array);
826889 testCastUndefined(slice);
......@@ -828,8 +891,9 @@ fn castUndefined() {
828891fn testCastUndefined(x: []u8) {}
829892
830893
831#attribute("test")
832894fn castSmallUnsignedToLargerSigned() {
895 @setFnTest(this, true);
896
833897 assert(castSmallUnsignedToLargerSigned1(200) == i16(200));
834898 assert(castSmallUnsignedToLargerSigned2(9999) == i64(9999));
835899}
......@@ -837,8 +901,9 @@ fn castSmallUnsignedToLargerSigned1(x: u8) -> i16 { x }
837901fn castSmallUnsignedToLargerSigned2(x: u16) -> i64 { x }
838902
839903
840#attribute("test")
841904fn implicitCastAfterUnreachable() {
905 @setFnTest(this, true);
906
842907 assert(outer() == 1234);
843908}
844909fn inner() -> i32 { 1234 }
......@@ -847,8 +912,9 @@ fn outer() -> i64 {
847912}
848913
849914
850#attribute("test")
851915fn elseIfExpression() {
916 @setFnTest(this, true);
917
852918 assert(elseIfExpressionF(1) == 1);
853919}
854920fn elseIfExpressionF(c: u8) -> u8 {
......@@ -861,8 +927,9 @@ fn elseIfExpressionF(c: u8) -> u8 {
861927 }
862928}
863929
864#attribute("test")
865930fn errBinaryOperator() {
931 @setFnTest(this, true);
932
866933 const a = errBinaryOperatorG(true) %% 3;
867934 const b = errBinaryOperatorG(false) %% 3;
868935 assert(a == 3);
......@@ -877,16 +944,18 @@ fn errBinaryOperatorG(x: bool) -> %isize {
877944 }
878945}
879946
880#attribute("test")
881947fn unwrapSimpleValueFromError() {
948 @setFnTest(this, true);
949
882950 const i = %%unwrapSimpleValueFromErrorDo();
883951 assert(i == 13);
884952}
885953fn unwrapSimpleValueFromErrorDo() -> %isize { 13 }
886954
887955
888#attribute("test")
889956fn storeMemberFunctionInVariable() {
957 @setFnTest(this, true);
958
890959 const instance = MemberFnTestFoo { .x = 1234, };
891960 const memberFn = MemberFnTestFoo.member;
892961 const result = memberFn(instance);
......@@ -897,15 +966,17 @@ struct MemberFnTestFoo {
897966 fn member(foo: MemberFnTestFoo) -> i32 { foo.x }
898967}
899968
900#attribute("test")
901969fn callMemberFunctionDirectly() {
970 @setFnTest(this, true);
971
902972 const instance = MemberFnTestFoo { .x = 1234, };
903973 const result = MemberFnTestFoo.member(instance);
904974 assert(result == 1234);
905975}
906976
907#attribute("test")
908977fn memberFunctions() {
978 @setFnTest(this, true);
979
909980 const r = MemberFnRand {.seed = 1234};
910981 assert(r.getSeed() == 1234);
911982}
......@@ -916,16 +987,18 @@ struct MemberFnRand {
916987 }
917988}
918989
919#attribute("test")
920990fn staticFunctionEvaluation() {
991 @setFnTest(this, true);
992
921993 assert(statically_added_number == 3);
922994}
923995const statically_added_number = staticAdd(1, 2);
924996fn staticAdd(a: i32, b: i32) -> i32 { a + b }
925997
926998
927#attribute("test")
928999fn staticallyInitalizedList() {
1000 @setFnTest(this, true);
1001
9291002 assert(static_point_list[0].x == 1);
9301003 assert(static_point_list[0].y == 2);
9311004 assert(static_point_list[1].x == 3);
......@@ -944,8 +1017,9 @@ fn makePoint(x: i32, y: i32) -> Point {
9441017}
9451018
9461019
947#attribute("test")
9481020fn staticEvalRecursive() {
1021 @setFnTest(this, true);
1022
9491023 assert(some_data.len == 21);
9501024}
9511025var some_data: [usize(fibbonaci(7))]u8 = undefined;
......@@ -954,8 +1028,9 @@ fn fibbonaci(x: i32) -> i32 {
9541028 return fibbonaci(x - 1) + fibbonaci(x - 2);
9551029}
9561030
957#attribute("test")
9581031fn staticEvalWhile() {
1032 @setFnTest(this, true);
1033
9591034 assert(static_eval_while_number == 1);
9601035}
9611036const static_eval_while_number = staticWhileLoop1();
......@@ -968,8 +1043,9 @@ fn staticWhileLoop2() -> i32 {
9681043 }
9691044}
9701045
971#attribute("test")
9721046fn staticEvalListInit() {
1047 @setFnTest(this, true);
1048
9731049 assert(static_vec3.data[2] == 1.0);
9741050}
9751051const static_vec3 = vec3(0.0, 0.0, 1.0);
......@@ -983,8 +1059,9 @@ pub fn vec3(x: f32, y: f32, z: f32) -> Vec3 {
9831059}
9841060
9851061
986#attribute("test")
9871062fn genericFnWithImplicitCast() {
1063 @setFnTest(this, true);
1064
9881065 assert(getFirstByte(u8, []u8 {13}) == 13);
9891066 assert(getFirstByte(u16, []u16 {0, 13}) == 0);
9901067}
......@@ -993,8 +1070,9 @@ fn getFirstByte(inline T: type, mem: []T) -> u8 {
9931070 getByte((&u8)(&mem[0]))
9941071}
9951072
996#attribute("test")
9971073fn continueAndBreak() {
1074 @setFnTest(this, true);
1075
9981076 runContinueAndBreakTest();
9991077 assert(continue_and_break_counter == 8);
10001078}
......@@ -1013,8 +1091,9 @@ fn runContinueAndBreakTest() {
10131091}
10141092
10151093
1016#attribute("test")
10171094fn pointerDereferencing() {
1095 @setFnTest(this, true);
1096
10181097 var x = i32(3);
10191098 const y = &x;
10201099
......@@ -1024,16 +1103,18 @@ fn pointerDereferencing() {
10241103 assert(*y == 4);
10251104}
10261105
1027#attribute("test")
10281106fn constantExpressions() {
1107 @setFnTest(this, true);
1108
10291109 var array : [array_size]u8 = undefined;
10301110 assert(@sizeOf(@typeOf(array)) == 20);
10311111}
10321112const array_size : u8 = 20;
10331113
10341114
1035#attribute("test")
10361115fn minValueAndMaxValue() {
1116 @setFnTest(this, true);
1117
10371118 assert(@maxValue(u8) == 255);
10381119 assert(@maxValue(u16) == 65535);
10391120 assert(@maxValue(u32) == 4294967295);
......@@ -1055,8 +1136,9 @@ fn minValueAndMaxValue() {
10551136 assert(@minValue(i64) == -9223372036854775808);
10561137}
10571138
1058#attribute("test")
10591139fn overflowIntrinsics() {
1140 @setFnTest(this, true);
1141
10601142 var result: u8 = undefined;
10611143 assert(@addWithOverflow(u8, 250, 100, &result));
10621144 assert(!@addWithOverflow(u8, 100, 150, &result));
......@@ -1064,8 +1146,9 @@ fn overflowIntrinsics() {
10641146}
10651147
10661148
1067#attribute("test")
10681149fn nestedArrays() {
1150 @setFnTest(this, true);
1151
10691152 const array_of_strings = [][]u8 {"hello", "this", "is", "my", "thing"};
10701153 for (array_of_strings) |s, i| {
10711154 if (i == 0) assert(str.eql(s, "hello"));
......@@ -1076,21 +1159,24 @@ fn nestedArrays() {
10761159 }
10771160}
10781161
1079#attribute("test")
10801162fn intToPtrCast() {
1163 @setFnTest(this, true);
1164
10811165 const x = isize(13);
10821166 const y = (&u8)(x);
10831167 const z = usize(y);
10841168 assert(z == 13);
10851169}
10861170
1087#attribute("test")
10881171fn stringConcatenation() {
1172 @setFnTest(this, true);
1173
10891174 assert(str.eql("OK" ++ " IT " ++ "WORKED", "OK IT WORKED"));
10901175}
10911176
1092#attribute("test")
10931177fn constantStructWithNegation() {
1178 @setFnTest(this, true);
1179
10941180 assert(vertices[0].x == -0.6);
10951181}
10961182struct Vertex {
......@@ -1107,8 +1193,9 @@ const vertices = []Vertex {
11071193};
11081194
11091195
1110#attribute("test")
11111196fn returnWithImplicitCastFromWhileLoop() {
1197 @setFnTest(this, true);
1198
11121199 %%returnWithImplicitCastFromWhileLoopTest();
11131200}
11141201fn returnWithImplicitCastFromWhileLoopTest() -> %void {
......@@ -1117,8 +1204,9 @@ fn returnWithImplicitCastFromWhileLoopTest() -> %void {
11171204 }
11181205}
11191206
1120#attribute("test")
11211207fn returnStructByvalFromFunction() {
1208 @setFnTest(this, true);
1209
11221210 const bar = makeBar(1234, 5678);
11231211 assert(bar.y == 5678);
11241212}
......@@ -1133,8 +1221,9 @@ fn makeBar(x: i32, y: i32) -> Bar {
11331221 }
11341222}
11351223
1136#attribute("test")
11371224fn functionPointers() {
1225 @setFnTest(this, true);
1226
11381227 const fns = []@typeOf(fn1) { fn1, fn2, fn3, fn4, };
11391228 for (fns) |f, i| {
11401229 assert(f() == u32(i) + 5);
......@@ -1147,8 +1236,9 @@ fn fn4() -> u32 {8}
11471236
11481237
11491238
1150#attribute("test")
11511239fn staticallyInitalizedStruct() {
1240 @setFnTest(this, true);
1241
11521242 st_init_str_foo.x += 1;
11531243 assert(st_init_str_foo.x == 14);
11541244}
......@@ -1158,8 +1248,9 @@ struct StInitStrFoo {
11581248}
11591249var st_init_str_foo = StInitStrFoo { .x = 13, .y = true, };
11601250
1161#attribute("test")
11621251fn staticallyInitializedArrayLiteral() {
1252 @setFnTest(this, true);
1253
11631254 const y : [4]u8 = st_init_arr_lit_x;
11641255 assert(y[3] == 4);
11651256}
......@@ -1167,8 +1258,9 @@ const st_init_arr_lit_x = []u8{1,2,3,4};
11671258
11681259
11691260
1170#attribute("test")
11711261fn pointerToVoidReturnType() {
1262 @setFnTest(this, true);
1263
11721264 %%testPointerToVoidReturnType();
11731265}
11741266fn testPointerToVoidReturnType() -> %void {
......@@ -1181,8 +1273,9 @@ fn testPointerToVoidReturnType2() -> &void {
11811273}
11821274
11831275
1184#attribute("test")
11851276fn callResultOfIfElseExpression() {
1277 @setFnTest(this, true);
1278
11861279 assert(str.eql(f2(true), "a"));
11871280 assert(str.eql(f2(false), "b"));
11881281}
......@@ -1193,8 +1286,9 @@ fn fA() -> []u8 { "a" }
11931286fn fB() -> []u8 { "b" }
11941287
11951288
1196#attribute("test")
11971289fn constExpressionEvalHandlingOfVariables() {
1290 @setFnTest(this, true);
1291
11981292 var x = true;
11991293 while (x) {
12001294 x = false;
......@@ -1203,8 +1297,9 @@ fn constExpressionEvalHandlingOfVariables() {
12031297
12041298
12051299
1206#attribute("test")
12071300fn constantEnumInitializationWithDifferingSizes() {
1301 @setFnTest(this, true);
1302
12081303 test3_1(test3_foo);
12091304 test3_2(test3_bar);
12101305}
......@@ -1219,8 +1314,9 @@ struct Test3Point {
12191314}
12201315const test3_foo = Test3Foo.Three{Test3Point {.x = 3, .y = 4}};
12211316const test3_bar = Test3Foo.Two{13};
1222#static_eval_enable(false)
12231317fn test3_1(f: Test3Foo) {
1318 @setFnStaticEval(this, false);
1319
12241320 switch (f) {
12251321 Three => |pt| {
12261322 assert(pt.x == 3);
......@@ -1229,8 +1325,9 @@ fn test3_1(f: Test3Foo) {
12291325 else => @unreachable(),
12301326 }
12311327}
1232#static_eval_enable(false)
12331328fn test3_2(f: Test3Foo) {
1329 @setFnStaticEval(this, false);
1330
12341331 switch (f) {
12351332 Two => |x| {
12361333 assert(x == 13);
......@@ -1241,8 +1338,9 @@ fn test3_2(f: Test3Foo) {
12411338
12421339
12431340
1244#attribute("test")
12451341fn whileWithContinueExpr() {
1342 @setFnTest(this, true);
1343
12461344 var sum: i32 = 0;
12471345 {var i: i32 = 0; while (i < 10; i += 1) {
12481346 if (i == 5) continue;
......@@ -1252,38 +1350,47 @@ fn whileWithContinueExpr() {
12521350}
12531351
12541352
1255#attribute("test")
12561353fn forLoopWithPointerElemVar() {
1354 @setFnTest(this, true);
1355
12571356 const source = "abcdefg";
12581357 var target: [source.len]u8 = undefined;
12591358 @memcpy(&target[0], &source[0], source.len);
12601359 mangleString(target);
12611360 assert(str.eql(target, "bcdefgh"));
12621361}
1263#static_eval_enable(false)
12641362fn mangleString(s: []u8) {
1363 @setFnStaticEval(this, false);
1364
12651365 for (s) |*c| {
12661366 *c += 1;
12671367 }
12681368}
12691369
1270#attribute("test")
12711370fn emptyStructMethodCall() {
1371 @setFnTest(this, true);
1372
12721373 const es = EmptyStruct{};
12731374 assert(es.method() == 1234);
12741375}
12751376struct EmptyStruct {
1276 #static_eval_enable(false)
1277 fn method(es: EmptyStruct) -> i32 { 1234 }
1377 fn method(es: EmptyStruct) -> i32 {
1378 @setFnStaticEval(this, false);
1379 1234
1380 }
1381
12781382}
12791383
12801384
1281#attribute("test")
1282fn @"weird function name"() { }
1385fn @"weird function name"() {
1386 @setFnTest(this, true);
1387}
1388
12831389
12841390
1285#attribute("test")
12861391fn returnEmptyStructFromFn() {
1392 @setFnTest(this, true);
1393
12871394 testReturnEmptyStructFromFn();
12881395 testReturnEmptyStructFromFnNoeval();
12891396}
......@@ -1291,13 +1398,15 @@ struct EmptyStruct2 {}
12911398fn testReturnEmptyStructFromFn() -> EmptyStruct2 {
12921399 EmptyStruct2 {}
12931400}
1294#static_eval_enable(false)
12951401fn testReturnEmptyStructFromFnNoeval() -> EmptyStruct2 {
1402 @setFnStaticEval(this, false);
1403
12961404 EmptyStruct2 {}
12971405}
12981406
1299#attribute("test")
13001407fn passSliceOfEmptyStructToFn() {
1408 @setFnTest(this, true);
1409
13011410 assert(testPassSliceOfEmptyStructToFn([]EmptyStruct2{ EmptyStruct2{} }) == 1);
13021411}
13031412fn testPassSliceOfEmptyStructToFn(slice: []EmptyStruct2) -> usize {
......@@ -1305,8 +1414,9 @@ fn testPassSliceOfEmptyStructToFn(slice: []EmptyStruct2) -> usize {
13051414}
13061415
13071416
1308#attribute("test")
13091417fn pointerComparison() {
1418 @setFnTest(this, true);
1419
13101420 const a = ([]u8)("a");
13111421 const b = &a;
13121422 assert(ptrEql(b, b));
......@@ -1315,15 +1425,17 @@ fn ptrEql(a: &[]u8, b: &[]u8) -> bool {
13151425 a == b
13161426}
13171427
1318#attribute("test")
13191428fn characterLiterals() {
1429 @setFnTest(this, true);
1430
13201431 assert('\'' == single_quote);
13211432}
13221433const single_quote = '\'';
13231434
13241435
1325#attribute("test")
13261436fn switchWithMultipleExpressions() {
1437 @setFnTest(this, true);
1438
13271439 const x: i32 = switch (returnsFive()) {
13281440 1, 2, 3 => 1,
13291441 4, 5, 6 => 2,
......@@ -1331,12 +1443,16 @@ fn switchWithMultipleExpressions() {
13311443 };
13321444 assert(x == 2);
13331445}
1334#static_eval_enable(false)
1335fn returnsFive() -> i32 { 5 }
1446fn returnsFive() -> i32 {
1447 @setFnStaticEval(this, false);
1448 5
1449}
1450
13361451
13371452
1338#attribute("test")
13391453fn switchOnErrorUnion() {
1454 @setFnTest(this, true);
1455
13401456 const x = switch (returnsTen()) {
13411457 Ok => |val| val + 1,
13421458 ItBroke, NoMem => 1,
......@@ -1347,20 +1463,28 @@ fn switchOnErrorUnion() {
13471463error ItBroke;
13481464error NoMem;
13491465error CrappedOut;
1350#static_eval_enable(false)
1351fn returnsTen() -> %i32 { 10 }
1466fn returnsTen() -> %i32 {
1467 @setFnStaticEval(this, false);
1468 10
1469}
1470
13521471
13531472
1354#attribute("test")
13551473fn boolCmp() {
1474 @setFnTest(this, true);
1475
13561476 assert(testBoolCmp(true, false) == false);
13571477}
1358#static_eval_enable(false)
1359fn testBoolCmp(a: bool, b: bool) -> bool { a == b }
1478fn testBoolCmp(a: bool, b: bool) -> bool {
1479 @setFnStaticEval(this, false);
1480 a == b
1481}
1482
13601483
13611484
1362#attribute("test")
13631485fn takeAddressOfParameter() {
1486 @setFnTest(this, true);
1487
13641488 testTakeAddressOfParameter(12.34);
13651489 testTakeAddressOfParameterNoeval(12.34);
13661490}
......@@ -1368,20 +1492,23 @@ fn testTakeAddressOfParameter(f: f32) {
13681492 const f_ptr = &f;
13691493 assert(*f_ptr == 12.34);
13701494}
1371#static_eval_enable(false)
13721495fn testTakeAddressOfParameterNoeval(f: f32) {
1496 @setFnStaticEval(this, false);
1497
13731498 const f_ptr = &f;
13741499 assert(*f_ptr == 12.34);
13751500}
13761501
13771502
1378#attribute("test")
13791503fn arrayMultOperator() {
1504 @setFnTest(this, true);
1505
13801506 assert(str.eql("ab" ** 5, "ababababab"));
13811507}
13821508
1383#attribute("test")
13841509fn stringEscapes() {
1510 @setFnTest(this, true);
1511
13851512 assert(str.eql("\"", "\x22"));
13861513 assert(str.eql("\'", "\x27"));
13871514 assert(str.eql("\n", "\x0a"));
......@@ -1391,12 +1518,14 @@ fn stringEscapes() {
13911518 assert(str.eql("\u1234\u0069", "\xe1\x88\xb4\x69"));
13921519}
13931520
1394#attribute("test")
13951521fn ifVarMaybePointer() {
1522 @setFnTest(this, true);
1523
13961524 assert(shouldBeAPlus1(Particle {.a = 14, .b = 1, .c = 1, .d = 1}) == 15);
13971525}
1398#static_eval_enable(false)
13991526fn shouldBeAPlus1(p: Particle) -> u64 {
1527 @setFnStaticEval(this, false);
1528
14001529 var maybe_particle: ?Particle = p;
14011530 if (const *particle ?= maybe_particle) {
14021531 particle.a += 1;
......@@ -1413,8 +1542,9 @@ struct Particle {
14131542 d: u64,
14141543}
14151544
1416#attribute("test")
14171545fn assignToIfVarPtr() {
1546 @setFnTest(this, true);
1547
14181548 var maybe_bool: ?bool = true;
14191549
14201550 if (const *b ?= maybe_bool) {
......@@ -1424,22 +1554,25 @@ fn assignToIfVarPtr() {
14241554 assert(??maybe_bool == false);
14251555}
14261556
1427#attribute("test")
14281557fn cmpxchg() {
1558 @setFnTest(this, true);
1559
14291560 var x: i32 = 1234;
14301561 while (!@cmpxchg(&x, 1234, 5678, AtomicOrder.SeqCst, AtomicOrder.SeqCst)) {}
14311562 assert(x == 5678);
14321563}
14331564
1434#attribute("test")
14351565fn fence() {
1566 @setFnTest(this, true);
1567
14361568 var x: i32 = 1234;
14371569 @fence(AtomicOrder.SeqCst);
14381570 x = 5678;
14391571}
14401572
1441#attribute("test")
14421573fn unsignedWrapping() {
1574 @setFnTest(this, true);
1575
14431576 testUnsignedWrappingEval(@maxValue(u32));
14441577 testUnsignedWrappingNoeval(@maxValue(u32));
14451578}
......@@ -1449,16 +1582,18 @@ fn testUnsignedWrappingEval(x: u32) {
14491582 const orig = zero -% 1;
14501583 assert(orig == @maxValue(u32));
14511584}
1452#static_eval_enable(false)
14531585fn testUnsignedWrappingNoeval(x: u32) {
1586 @setFnStaticEval(this, false);
1587
14541588 const zero = x +% 1;
14551589 assert(zero == 0);
14561590 const orig = zero -% 1;
14571591 assert(orig == @maxValue(u32));
14581592}
14591593
1460#attribute("test")
14611594fn signedWrapping() {
1595 @setFnTest(this, true);
1596
14621597 testSignedWrappingEval(@maxValue(i32));
14631598 testSignedWrappingNoeval(@maxValue(i32));
14641599}
......@@ -1468,16 +1603,18 @@ fn testSignedWrappingEval(x: i32) {
14681603 const max_val = min_val -% 1;
14691604 assert(max_val == @maxValue(i32));
14701605}
1471#static_eval_enable(false)
14721606fn testSignedWrappingNoeval(x: i32) {
1607 @setFnStaticEval(this, false);
1608
14731609 const min_val = x +% 1;
14741610 assert(min_val == @minValue(i32));
14751611 const max_val = min_val -% 1;
14761612 assert(max_val == @maxValue(i32));
14771613}
14781614
1479#attribute("test")
14801615fn negationWrapping() {
1616 @setFnTest(this, true);
1617
14811618 testNegationWrappingEval(@minValue(i16));
14821619 testNegationWrappingNoeval(@minValue(i16));
14831620}
......@@ -1486,15 +1623,17 @@ fn testNegationWrappingEval(x: i16) {
14861623 const neg = -%x;
14871624 assert(neg == -32768);
14881625}
1489#static_eval_enable(false)
14901626fn testNegationWrappingNoeval(x: i16) {
1627 @setFnStaticEval(this, false);
1628
14911629 assert(x == -32768);
14921630 const neg = -%x;
14931631 assert(neg == -32768);
14941632}
14951633
1496#attribute("test")
14971634fn shlWrapping() {
1635 @setFnTest(this, true);
1636
14981637 testShlWrappingEval(@maxValue(u16));
14991638 testShlWrappingNoeval(@maxValue(u16));
15001639}
......@@ -1502,22 +1641,25 @@ fn testShlWrappingEval(x: u16) {
15021641 const shifted = x <<% 1;
15031642 assert(shifted == 65534);
15041643}
1505#static_eval_enable(false)
15061644fn testShlWrappingNoeval(x: u16) {
1645 @setFnStaticEval(this, false);
1646
15071647 const shifted = x <<% 1;
15081648 assert(shifted == 65534);
15091649}
15101650
1511#attribute("test")
15121651fn shlWithOverflow() {
1652 @setFnTest(this, true);
1653
15131654 var result: u16 = undefined;
15141655 assert(@shlWithOverflow(u16, 0b0010111111111111, 3, &result));
15151656 assert(!@shlWithOverflow(u16, 0b0010111111111111, 2, &result));
15161657 assert(result == 0b1011111111111100);
15171658}
15181659
1519#attribute("test")
15201660fn cStringConcatenation() {
1661 @setFnTest(this, true);
1662
15211663 const a = c"OK" ++ c" IT " ++ c"WORKED";
15221664 const b = c"OK IT WORKED";
15231665
......@@ -1530,8 +1672,9 @@ fn cStringConcatenation() {
15301672 assert(b[len] == 0);
15311673}
15321674
1533#attribute("test")
15341675fn genericStruct() {
1676 @setFnTest(this, true);
1677
15351678 var a1 = GenNode(i32) {.value = 13, .next = null,};
15361679 var b1 = GenNode(bool) {.value = true, .next = null,};
15371680 assert(a1.value == 13);
......@@ -1544,8 +1687,9 @@ struct GenNode(T: type) {
15441687 fn getVal(n: &const GenNode(T)) -> T { n.value }
15451688}
15461689
1547#attribute("test")
15481690fn castSliceToU8Slice() {
1691 @setFnTest(this, true);
1692
15491693 assert(@sizeOf(i32) == 4);
15501694 var big_thing_array = []i32{1, 2, 3, 4};
15511695 const big_thing_slice: []i32 = big_thing_array;
......@@ -1565,26 +1709,31 @@ fn castSliceToU8Slice() {
15651709 assert(bytes[11] == @maxValue(u8));
15661710}
15671711
1568#attribute("test")
15691712fn floatDivision() {
1713 @setFnTest(this, true);
1714
15701715 assert(fdiv32(12.0, 3.0) == 4.0);
15711716}
1572#static_eval_enable(false)
15731717fn fdiv32(a: f32, b: f32) -> f32 {
1718 @setFnStaticEval(this, false);
1719
15741720 a / b
15751721}
15761722
1577#attribute("test")
15781723fn exactDivision() {
1724 @setFnTest(this, true);
1725
15791726 assert(divExact(55, 11) == 5);
15801727}
1581#static_eval_enable(false)
15821728fn divExact(a: u32, b: u32) -> u32 {
1729 @setFnStaticEval(this, false);
1730
15831731 @divExact(a, b)
15841732}
15851733
1586#attribute("test")
15871734fn nullLiteralOutsideFunction() {
1735 @setFnTest(this, true);
1736
15881737 const is_null = if (const _ ?= here_is_a_null_literal.context) false else true;
15891738 assert(is_null);
15901739}
......@@ -1595,25 +1744,29 @@ const here_is_a_null_literal = SillyStruct {
15951744 .context = null,
15961745};
15971746
1598#attribute("test")
15991747fn truncate() {
1748 @setFnTest(this, true);
1749
16001750 assert(testTruncate(0x10fd) == 0xfd);
16011751}
1602#static_eval_enable(false)
16031752fn testTruncate(x: u32) -> u8 {
1753 @setFnStaticEval(this, false);
1754
16041755 @truncate(u8, x)
16051756}
16061757
1607#attribute("test")
16081758fn constDeclsInStruct() {
1759 @setFnTest(this, true);
1760
16091761 assert(GenericDataThing(3).count_plus_one == 4);
16101762}
16111763struct GenericDataThing(count: isize) {
16121764 const count_plus_one = count + 1;
16131765}
16141766
1615#attribute("test")
16161767fn useGenericParamInGenericParam() {
1768 @setFnTest(this, true);
1769
16171770 assert(aGenericFn(i32, 3, 4) == 7);
16181771}
16191772fn aGenericFn(inline T: type, inline a: T, b: T) -> T {
......@@ -1621,14 +1774,16 @@ fn aGenericFn(inline T: type, inline a: T, b: T) -> T {
16211774}
16221775
16231776
1624#attribute("test")
16251777fn unsigned64BitDivision() {
1778 @setFnTest(this, true);
1779
16261780 const result = div(1152921504606846976, 34359738365);
16271781 assert(result.quotient == 33554432);
16281782 assert(result.remainder == 100663296);
16291783}
1630#static_eval_enable(false)
16311784fn div(a: u64, b: u64) -> DivResult {
1785 @setFnStaticEval(this, false);
1786
16321787 DivResult {
16331788 .quotient = a / b,
16341789 .remainder = a % b,
......@@ -1639,8 +1794,9 @@ struct DivResult {
16391794 remainder: u64,
16401795}
16411796
1642#attribute("test")
16431797fn intTypeBuiltin() {
1798 @setFnTest(this, true);
1799
16441800 assert(@intType(true, 8) == i8);
16451801 assert(@intType(true, 16) == i16);
16461802 assert(@intType(true, 32) == i32);
......@@ -1670,16 +1826,18 @@ fn intTypeBuiltin() {
16701826
16711827}
16721828
1673#attribute("test")
16741829fn intToEnum() {
1830 @setFnTest(this, true);
1831
16751832 testIntToEnumEval(3);
16761833 testIntToEnumNoeval(3);
16771834}
16781835fn testIntToEnumEval(x: i32) {
16791836 assert(IntToEnumNumber(x) == IntToEnumNumber.Three);
16801837}
1681#static_eval_enable(false)
16821838fn testIntToEnumNoeval(x: i32) {
1839 @setFnStaticEval(this, false);
1840
16831841 assert(IntToEnumNumber(x) == IntToEnumNumber.Three);
16841842}
16851843enum IntToEnumNumber {