mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 03:51:18 +00:00
- Empty enums would return the values as zero sized arrays #2838
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<*
|
||||
@require Enum.kindof == TypeKind.ENUM : "Only enums may be used with an enummap"
|
||||
@require Enum.values.len > 0 : "Only non-empty enums may be used with enummap"
|
||||
*>
|
||||
module std::collections::enummap <Enum, ValueType>;
|
||||
import std::io;
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
// Copyright (c) 2025 Zack Puhl <github@xmit.xyz>. All rights reserved.
|
||||
// Use of this source code is governed by the MIT license
|
||||
// a copy of which can be found in the LICENSE_STDLIB file.
|
||||
<*
|
||||
@require @in(DIGEST_BITS, ...PERMISSIBLE_SIZES_BITS) : "Invalid DIGEST_BITS; must be one of {128, 160, 256, 320}."
|
||||
*>
|
||||
module std::hash::ripemd <DIGEST_BITS>;
|
||||
|
||||
module std::hash::ripemd;
|
||||
const usz[4] PERMISSIBLE_SIZES_BITS = { 128, 160, 256, 320 };
|
||||
|
||||
<* Unchanging block size. *>
|
||||
const BLOCK_SIZE = 64;
|
||||
|
||||
const usz[4] PERMISSIBLE_SIZES_BITS = { 128, 160, 256, 320 };
|
||||
|
||||
<* RIPE-MD initial values. *>
|
||||
const uint[10] H = {
|
||||
@@ -24,6 +21,11 @@ const uint[9] K = {
|
||||
0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9
|
||||
};
|
||||
|
||||
<*
|
||||
@require @in(DIGEST_BITS, ...PERMISSIBLE_SIZES_BITS) : "Invalid DIGEST_BITS; must be one of {128, 160, 256, 320}."
|
||||
*>
|
||||
module std::hash::ripemd <DIGEST_BITS>;
|
||||
|
||||
<* Ultimate digest's size in bytes. *>
|
||||
const DIGEST_BYTES = DIGEST_BITS / 8;
|
||||
|
||||
|
||||
@@ -124,6 +124,7 @@
|
||||
- Constant deref of subscript had inserted checks #2818
|
||||
- Raw vaargs with optional return not lowered correctly #2819
|
||||
- Early exit in macro call crashes codegen #2820
|
||||
- Empty enums would return the values as zero sized arrays #2838
|
||||
|
||||
### Stdlib changes
|
||||
- Add `ThreadPool` join function to wait for all threads to finish in the pool without destroying the threads.
|
||||
|
||||
@@ -5293,14 +5293,6 @@ FOUND:;
|
||||
vec_add(generic->generic_decl.instances, instance);
|
||||
AnalysisStage stage = module->stage;
|
||||
ASSERT(stage > ANALYSIS_IMPORTS);
|
||||
// Add all the normal top level declarations
|
||||
FOREACH(Decl *, decl, copied) unit_register_global_decl(decl->unit, decl);
|
||||
// Add all the conditional declarations
|
||||
FOREACH(Decl *, decl, copied_cond)
|
||||
{
|
||||
unit_register_optional_global_decl(decl->unit, decl);
|
||||
if (decl->decl_kind != DECL_ERASED) vec_add(copied, decl);
|
||||
}
|
||||
if (compiler.context.errors_found) return poisoned_decl;
|
||||
|
||||
// Check contracts
|
||||
@@ -5316,11 +5308,22 @@ FOUND:;
|
||||
SourceSpan param_span = extend_span_with_token(params[0]->span, VECLAST(params)->span);
|
||||
if (!sema_analyse_generic_module_contracts(context, module, instance, contracts, param_span, invocation_span))
|
||||
{
|
||||
return poisoned_decl;
|
||||
decl_poison(instance);
|
||||
decl_poison(alias);
|
||||
return alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add all the normal top level declarations
|
||||
FOREACH(Decl *, decl, copied) unit_register_global_decl(decl->unit, decl);
|
||||
// Add all the conditional declarations
|
||||
FOREACH(Decl *, decl, copied_cond)
|
||||
{
|
||||
unit_register_optional_global_decl(decl->unit, decl);
|
||||
if (decl->decl_kind != DECL_ERASED) vec_add(copied, decl);
|
||||
}
|
||||
|
||||
if (stage < ANALYSIS_METHODS_REGISTER) goto EXIT;
|
||||
FOREACH(Decl *, decl, copied)
|
||||
{
|
||||
|
||||
@@ -4962,7 +4962,7 @@ static inline bool sema_expr_replace_with_enum_array(SemaContext *context, Expr
|
||||
initializer->initializer_list = element_values;
|
||||
enum_array_expr->expr_kind = EXPR_COMPOUND_LITERAL;
|
||||
enum_array_expr->expr_compound_literal.initializer = initializer;
|
||||
enum_array_expr->expr_compound_literal.type_info = type_info_new_base(type_get_array(kind, elements), span);
|
||||
enum_array_expr->expr_compound_literal.type_info = type_info_new_base(type_get_slice(kind), span);
|
||||
enum_array_expr->resolve_status = RESOLVE_NOT_DONE;
|
||||
return sema_analyse_expr_rvalue(context, enum_array_expr);
|
||||
}
|
||||
@@ -4985,7 +4985,7 @@ static inline bool sema_expr_replace_with_const_enum_array(SemaContext *context,
|
||||
initializer->initializer_list = element_values;
|
||||
enum_array_expr->expr_kind = EXPR_COMPOUND_LITERAL;
|
||||
enum_array_expr->expr_compound_literal.initializer = initializer;
|
||||
enum_array_expr->expr_compound_literal.type_info = type_info_new_base(type_get_array(kind, elements), span);
|
||||
enum_array_expr->expr_compound_literal.type_info = type_info_new_base(type_get_slice(kind), span);
|
||||
enum_array_expr->resolve_status = RESOLVE_NOT_DONE;
|
||||
return sema_analyse_expr_rvalue(context, enum_array_expr);
|
||||
}
|
||||
|
||||
6
test/test_suite/enumerations/empty_enum_reflection.c3
Normal file
6
test/test_suite/enumerations/empty_enum_reflection.c3
Normal file
@@ -0,0 +1,6 @@
|
||||
import std;
|
||||
enum Foo
|
||||
{
|
||||
}
|
||||
EnumMap{Foo, int} map; // #error: Parameter(s) would violate constraint: @require "Enum.values.len > 0" violated
|
||||
fn int main() => 1;
|
||||
@@ -9,7 +9,7 @@ enum Foo
|
||||
}
|
||||
|
||||
Foo zfok = Foo.values[0];
|
||||
Foo[] zw = &&Foo.values;
|
||||
Foo[] zw = Foo.values;
|
||||
|
||||
fn void test(int x)
|
||||
{
|
||||
@@ -19,17 +19,21 @@ fn void test(int x)
|
||||
/* #expect: test.ll
|
||||
|
||||
@test.zfok = local_unnamed_addr global i32 0, align 4
|
||||
@.taddr = private unnamed_addr global [2 x i32] [i32 0, i32 1], align 4
|
||||
@test.zw = local_unnamed_addr global %"int[]" { ptr @.taddr, i64 2 }, align 8
|
||||
@.__const_slice = private unnamed_addr global [2 x i32] [i32 0, i32 1], align 4
|
||||
@test.zw = local_unnamed_addr global %"int[]" { ptr @.__const_slice, i64 2 }, align 8
|
||||
@.__const = private unnamed_addr constant [2 x i32] [i32 0, i32 1], align 4
|
||||
|
||||
define void @test.test(i32 %0) #0 {
|
||||
entry:
|
||||
%zonk = alloca i32, align 4
|
||||
%literal = alloca [2 x i32], align 4
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 4 %literal, ptr align 4 @.__const, i32 8, i1 false)
|
||||
%1 = insertvalue %"int[]" undef, ptr %literal, 0
|
||||
%2 = insertvalue %"int[]" %1, i64 2, 1
|
||||
%3 = extractvalue %"int[]" %2, 0
|
||||
%sext = sext i32 %0 to i64
|
||||
%ptroffset = getelementptr inbounds [4 x i8], ptr %literal, i64 %sext
|
||||
%1 = load i32, ptr %ptroffset, align 4
|
||||
store i32 %1, ptr %zonk, align 4
|
||||
%ptroffset = getelementptr inbounds [4 x i8], ptr %3, i64 %sext
|
||||
%4 = load i32, ptr %ptroffset, align 4
|
||||
store i32 %4, ptr %zonk, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ fn void basic_streamed()
|
||||
x'e7660e67549435c62141e51c9ab1dcc3b1ee9f65c0b3e561ae8f58c5dba3d21997781cd1cc6fbc34'
|
||||
};
|
||||
char[] phrase = "The quick brown fox jumps over the lazy dog";
|
||||
$foreach $i, $bits : ripemd::PERMISSIBLE_SIZES_BITS{128}:
|
||||
$foreach $i, $bits : ripemd::PERMISSIBLE_SIZES_BITS:
|
||||
{ // le scope
|
||||
RipeMd{$bits} r @noinit;
|
||||
r.init();
|
||||
@@ -83,7 +83,7 @@ fn void large_input_streamed()
|
||||
};
|
||||
char[] one_mb = mem::talloc_array(char, 1024*1024);
|
||||
one_mb[..] = 0xA5;
|
||||
$foreach $i, $bits : ripemd::PERMISSIBLE_SIZES_BITS{128}:
|
||||
$foreach $i, $bits : ripemd::PERMISSIBLE_SIZES_BITS:
|
||||
{
|
||||
RipeMd{$bits} r @noinit;
|
||||
r.init();
|
||||
@@ -106,7 +106,7 @@ fn void large_input_streamed_per_byte()
|
||||
};
|
||||
char[] one_mb = mem::talloc_array(char, 1024*1024);
|
||||
one_mb[..] = 0xA5;
|
||||
$foreach $i, $bits : ripemd::PERMISSIBLE_SIZES_BITS{128}:
|
||||
$foreach $i, $bits : ripemd::PERMISSIBLE_SIZES_BITS:
|
||||
{
|
||||
RipeMd{$bits} r @noinit;
|
||||
r.init();
|
||||
@@ -132,7 +132,7 @@ fn void walk_lengths_streamed()
|
||||
{
|
||||
foreach (arr : CALCULATED_HASHES)
|
||||
{
|
||||
$foreach $i, $bits : ripemd::PERMISSIBLE_SIZES_BITS{128}:
|
||||
$foreach $i, $bits : ripemd::PERMISSIBLE_SIZES_BITS:
|
||||
{
|
||||
RipeMd{$bits} r @noinit;
|
||||
r.init();
|
||||
|
||||
Reference in New Issue
Block a user