Remove string literals.

This commit is contained in:
Christoffer Lerno
2021-12-09 02:15:05 +01:00
parent 4bc47a195b
commit e54679c01e
23 changed files with 113 additions and 116 deletions

View File

@@ -210,7 +210,6 @@ bool type_is_homogenous_aggregate(Type *type, Type **base, unsigned *elements)
case TYPE_VOID:
case TYPE_TYPEID:
case TYPE_FUNC:
case TYPE_STRLIT:
case TYPE_SUBARRAY:
case CT_TYPES:
case TYPE_FAILABLE_ANY:

View File

@@ -148,7 +148,7 @@ typedef struct
struct
{
const char *chars;
uint32_t len;
ArraySize len;
} string;
Decl *enum_val;
Decl *err_val;
@@ -1526,7 +1526,7 @@ extern Type *poisoned_type;
extern TypeInfo *poisoned_type_info;
extern Type *type_bool, *type_void, *type_compstr, *type_voidptr;
extern Type *type_bool, *type_void, *type_voidptr;
extern Type *type_half, *type_float, *type_double, *type_quad;
extern Type *type_ichar, *type_short, *type_int, *type_long, *type_isize;
extern Type *type_char, *type_ushort, *type_uint, *type_ulong, *type_usize;

View File

@@ -549,7 +549,6 @@ typedef enum
TYPE_BITSTRUCT,
TYPE_ERRTYPE,
TYPE_TYPEDEF,
TYPE_STRLIT,
TYPE_DISTINCT,
TYPE_ARRAY,
TYPE_SUBARRAY,

View File

@@ -112,8 +112,6 @@ static void header_print_type(FILE *file, Type *type)
break;
case TYPE_TYPEDEF:
break;
case TYPE_STRLIT:
UNREACHABLE
case TYPE_ARRAY:
break;
case TYPE_ANY:

View File

@@ -339,8 +339,6 @@ void llvm_emit_ptr_from_array(GenContext *c, BEValue *value)
llvm_value_set_address_align(value, member.value, type_get_ptr(value->type->array.base), type_abi_alignment(value->type->array.base));
return;
}
case TYPE_STRLIT:
return;
default:
UNREACHABLE
}

View File

@@ -398,7 +398,6 @@ static void x64_classify(Type *type, ByteSize offset_base, X64Class *lo_class, X
case TYPE_TYPEID:
case TYPE_FUNC:
case TYPE_DISTINCT:
case TYPE_STRLIT:
case TYPE_ANYERR:
case TYPE_ERRTYPE:
case TYPE_BITSTRUCT:
@@ -588,7 +587,6 @@ AbiType *x64_get_int_type_at_offset(Type *type, unsigned offset, Type *source_ty
case TYPE_FUNC:
case TYPE_TYPEDEF:
case TYPE_DISTINCT:
case TYPE_STRLIT:
case TYPE_ANYERR:
case TYPE_ERRTYPE:
case TYPE_BITSTRUCT:

View File

@@ -113,7 +113,6 @@ static bool x86_should_return_type_in_reg(Type *type)
case TYPE_TYPEDEF:
case TYPE_DISTINCT:
case TYPE_ENUM:
case TYPE_STRLIT:
case TYPE_ERRTYPE:
case TYPE_TYPEID:
case TYPE_ANYERR:
@@ -595,7 +594,6 @@ static ABIArgInfo *x86_classify_argument(CallABI call, Regs *regs, Type *type)
case TYPE_FUNC:
case TYPE_TYPEID:
case TYPE_BITSTRUCT:
case TYPE_STRLIT:
case TYPE_FAILABLE:
case TYPE_FAILABLE_ANY:
case CT_TYPES:

View File

@@ -495,7 +495,6 @@ static inline LLVMMetadataRef llvm_get_debug_type_internal(GenContext *c, Type *
switch (type->type_kind)
{
case TYPE_TYPEID:
case TYPE_STRLIT:
case CT_TYPES:
UNREACHABLE
case TYPE_FAILABLE:

View File

@@ -514,11 +514,6 @@ static inline void llvm_emit_subscript_addr_with_base(GenContext *c, BEValue *re
llvm_value_set_address_align(result, ptr, type->array.base, type_abi_alignment(type->array.base));
}
return;
case TYPE_STRLIT:
// TODO insert trap on overflow.
llvm_value_set_address_align(result, llvm_emit_pointer_inbounds_gep_raw(c, llvm_get_type(c, type_char), parent->value, index->value),
type_char, type_abi_alignment(type_char));
return;
default:
UNREACHABLE
@@ -2131,9 +2126,6 @@ void llvm_emit_len_for_expr(GenContext *c, BEValue *be_value, BEValue *expr_to_l
case TYPE_ARRAY:
llvm_value_set(be_value, llvm_const_int(c, type_usize, expr_to_len->type->array.len), type_usize);
break;
case TYPE_STRLIT:
TODO
break;
default:
UNREACHABLE
}
@@ -2206,8 +2198,6 @@ static void llvm_emit_slice_values(GenContext *c, Expr *slice, BEValue *parent_r
case TYPE_ARRAY:
parent_base = parent_addr;
break;
case TYPE_STRLIT:
TODO
default:
UNREACHABLE
}
@@ -2236,8 +2226,6 @@ static void llvm_emit_slice_values(GenContext *c, Expr *slice, BEValue *parent_r
case TYPE_ARRAY:
llvm_value_set_int(c, &len, type_usize, parent_type->array.len);
break;
case TYPE_STRLIT:
TODO
default:
UNREACHABLE
}
@@ -3129,7 +3117,6 @@ void llvm_emit_derived_backend_type(GenContext *c, Type *type)
case TYPE_TYPEDEF:
original_type = original_type->canonical;
continue;
case TYPE_STRLIT:
case TYPE_INFERRED_ARRAY:
case TYPE_UNTYPED_LIST:
case TYPE_FAILABLE_ANY:
@@ -3787,7 +3774,7 @@ static void llvm_emit_const_expr(GenContext *c, BEValue *be_value, Expr *expr)
expr->const_expr.string.len,
0));
llvm_set_alignment(global_name, 1);
global_name = LLVMConstBitCast(global_name, LLVMPointerType(llvm_get_type(c, type_char), 0));
global_name = LLVMConstBitCast(global_name, llvm_get_ptr_type(c, type_get_array(type_char, expr->const_expr.string.len)));
llvm_value_set(be_value, global_name, type);
return;
}
@@ -3867,7 +3854,6 @@ static void llvm_expand_type_to_args(GenContext *context, Type *param_type, LLVM
case TYPE_TYPEID:
case TYPE_FUNC:
case TYPE_DISTINCT:
case TYPE_STRLIT:
case TYPE_ENUM:
case TYPE_ERRTYPE:
case TYPE_ANYERR:

View File

@@ -351,8 +351,6 @@ LLVMTypeRef llvm_get_type(GenContext *c, Type *any_type)
return any_type->backend_type = LLVMIntTypeInContext(c->context, 8U);
case TYPE_POINTER:
return any_type->backend_type = llvm_type_from_ptr(c, any_type);
case TYPE_STRLIT:
return any_type->backend_type = LLVMPointerType(llvm_get_type(c, type_char), 0);
case TYPE_ARRAY:
return any_type->backend_type = llvm_type_from_array(c, any_type);
case TYPE_SUBARRAY:

View File

@@ -1425,7 +1425,6 @@ static Expr *parse_string_literal(Context *context, Expr *left)
{
assert(!left && "Had left hand side");
Expr *expr_string = EXPR_NEW_TOKEN(EXPR_CONST, context->tok);
expr_string->type = type_compstr;
TokenData *data = TOKDATA(context->tok);
const char *str = data->string;
@@ -1454,7 +1453,7 @@ static Expr *parse_string_literal(Context *context, Expr *left)
assert(str);
expr_string->const_expr.string.chars = str;
expr_string->const_expr.string.len = (uint32_t)len;
expr_string->type = type_compstr;
expr_string->type = type_get_ptr(type_get_array(type_char, len));
expr_string->const_expr.const_kind = CONST_STRING;
return expr_string;
}

View File

@@ -67,6 +67,10 @@ bool pointer_to_pointer(Expr* expr, Type *type)
{
if (insert_runtime_cast_unless_const(expr, CAST_PTRPTR, type)) return true;
if (expr->const_expr.const_kind == CONST_STRING)
{
return insert_cast(expr, CAST_PTRPTR, type);
}
// Must have been a null
expr->type = type;
expr->const_expr.narrowable = false;
@@ -374,7 +378,6 @@ CastKind cast_to_bool_kind(Type *type)
case TYPE_VOID:
case TYPE_STRUCT:
case TYPE_UNION:
case TYPE_STRLIT:
case TYPE_ENUM:
case TYPE_FUNC:
case TYPE_ARRAY:
@@ -492,10 +495,6 @@ bool cast_may_explicit(Type *from_type, Type *to_type, bool ignore_failability,
FALLTHROUGH;
case TYPE_UNION:
return type_is_structurally_equivalent(from_type, to_type);
case TYPE_STRLIT:
if (to_kind == TYPE_POINTER) return true;
if (to_kind == TYPE_SUBARRAY && (to_type->array.base == type_char || to_type->array.base == type_ichar)) return true;
return false;
case TYPE_SUBARRAY:
return to_kind == TYPE_POINTER;
case TYPE_VECTOR:
@@ -604,9 +603,6 @@ bool cast_may_implicit(Type *from_type, Type *to_type, bool is_simple_expr, bool
return type_is_subtype(to->pointer, from->pointer);
}
// 4c. Assigning a compile time string to char* is fine. TODO fix correct later
if (from->type_kind == TYPE_STRLIT && to->pointer == type_char) return true;
return false;
}
@@ -621,10 +617,6 @@ bool cast_may_implicit(Type *from_type, Type *to_type, bool is_simple_expr, bool
{
// 5a. char[] foo = "test"
Type *base = to->array.base;
if (from->type_kind == TYPE_STRLIT && (base->type_kind == TYPE_I8 || base->type_kind == TYPE_U8))
{
return true;
}
// 5b. Assign sized array pointer int[] = int[4]*
if (type_is_pointer(from))
@@ -635,15 +627,6 @@ bool cast_may_implicit(Type *from_type, Type *to_type, bool is_simple_expr, bool
}
// 7. In the case of distinct types, we allow implicit conversion from literal types.
if (to->type_kind == TYPE_DISTINCT)
{
if (from->type_kind == TYPE_STRLIT)
{
return cast_may_implicit(from, type_flatten(to), is_simple_expr, failable_allowed);
}
}
// 8. Check if we may cast this to bool. It is safe for many types.
if (to->type_kind == TYPE_BOOL)
@@ -1016,12 +999,30 @@ static void sema_error_const_int_out_of_range(Expr *expr, Expr *problem, Type *t
SEMA_ERROR(problem, "The value '%s' is out of range for %s, so you need an explicit cast to truncate the value.", error_value,
type_quoted_error_string(to_type));
}
static inline bool cast_maybe_string_lit_to_char_array(Expr *expr, Type *expr_canonical, Type *to_canonical)
{
if (expr->expr_kind != EXPR_CONST || expr->const_expr.const_kind != CONST_STRING) return false;
if (expr_canonical->type_kind != TYPE_POINTER) return false;
if (to_canonical->type_kind != TYPE_ARRAY && to_canonical->type_kind != TYPE_INFERRED_ARRAY) return false;
if (to_canonical->array.base != type_char) return false;
Type *pointer = expr_canonical->pointer;
if (pointer->type_kind != TYPE_ARRAY) return false;
if (pointer->array.base != type_char) return false;
expr_insert_deref(expr);
return true;
}
bool cast_implicit(Expr *expr, Type *to_type)
{
assert(!type_is_failable(to_type));
Type *expr_type = expr->type;
Type *expr_canonical = expr_type->canonical;
Type *to_canonical = to_type->canonical;
if (cast_maybe_string_lit_to_char_array(expr, expr_canonical, to_canonical))
{
expr_type = expr->type;
expr_canonical = expr_type->canonical;
}
if (expr_canonical == to_canonical) return true;
bool is_simple = expr_is_simple(expr);
if (!cast_may_implicit(expr_canonical, to_canonical, is_simple, true))
@@ -1268,11 +1269,6 @@ static bool cast_inner(Expr *expr, Type *from_type, Type *to, Type *to_type)
return insert_cast(expr, CAST_STST, to_type);
} // Starting in a little while...
break;
case TYPE_STRLIT:
to = type_flatten(to);
if (to->type_kind == TYPE_POINTER) return insert_cast(expr, CAST_STRPTR, to_type);
if (to->type_kind == TYPE_SUBARRAY) return string_literal_to_subarray(expr, to_type);
break;
case TYPE_SUBARRAY:
if (to->type_kind == TYPE_POINTER) return insert_cast(expr, CAST_SAPTR, to);
if (to->type_kind == TYPE_BOOL) return subarray_to_bool(expr);

View File

@@ -683,7 +683,6 @@ static inline bool sema_analyse_distinct(Context *context, Decl *decl)
decl->distinct_decl.base_type = base;
switch (base->type_kind)
{
case TYPE_STRLIT:
case TYPE_FUNC:
case TYPE_TYPEDEF:
case TYPE_DISTINCT:
@@ -1166,7 +1165,7 @@ AttributeType sema_analyse_attribute(Context *context, Attr *attr, AttributeDoma
return ATTRIBUTE_NONE;
}
if (!sema_analyse_expr(context, attr->expr)) return false;
if (attr->expr->expr_kind != EXPR_CONST || attr->expr->type->canonical != type_compstr)
if (attr->expr->expr_kind != EXPR_CONST || attr->expr->const_expr.const_kind != CONST_STRING)
{
SEMA_ERROR(attr->expr, "Expected a constant string value as argument.");
return ATTRIBUTE_NONE;

View File

@@ -2326,7 +2326,6 @@ static bool expr_check_index_in_range(Context *context, Type *type, Expr *index_
}
break;
}
case TYPE_STRLIT:
case TYPE_SUBARRAY:
// If not from end, just check the negative values.
if (!from_end) break;
@@ -2610,9 +2609,10 @@ static inline void expr_rewrite_to_string(Expr *expr_to_rewrite, const char *str
expr_to_rewrite->expr_kind = EXPR_CONST;
expr_to_rewrite->const_expr.const_kind = CONST_STRING;
expr_to_rewrite->const_expr.string.chars = (char *)string;
expr_to_rewrite->const_expr.string.len = (uint32_t)strlen(string);
ArraySize len = (ArraySize)strlen(string);
expr_to_rewrite->const_expr.string.len = len;
expr_to_rewrite->resolve_status = RESOLVE_DONE;
expr_to_rewrite->type = type_compstr;
expr_to_rewrite->type = type_get_ptr(type_get_array(type_char, len));
}
@@ -2972,11 +2972,6 @@ CHECK_DEEPER:
// 9. Fix hard coded function `len` on subarrays and arrays
if (!is_macro && kw == kw_len)
{
if (flat_type->type_kind == TYPE_STRLIT)
{
expr_rewrite_to_int_const(expr, type_isize, parent->const_expr.string.len, true);
return true;
}
if (flat_type->type_kind == TYPE_SUBARRAY)
{
expr->expr_kind = EXPR_LEN;

View File

@@ -2099,7 +2099,7 @@ bool sema_analyse_ct_assert_stmt(Context *context, Ast *statement)
if (message)
{
if (!sema_analyse_expr(context, message)) return false;
if (message->type->type_kind != TYPE_STRLIT)
if (message->expr_kind != EXPR_CONST || message->const_expr.const_kind != CONST_STRING)
{
SEMA_ERROR(message, "Expected a string as the error message.");
}
@@ -2175,7 +2175,7 @@ bool sema_analyse_assert_stmt(Context *context, Ast *statement)
if (message)
{
if (!sema_analyse_expr(context, message)) return false;
if (message->type->type_kind != TYPE_STRLIT)
if (message->expr_kind != EXPR_CONST || message->const_expr.const_kind != CONST_STRING)
{
SEMA_ERROR(message, "Expected a string as the error message.");
}

View File

@@ -193,7 +193,6 @@ bool sema_resolve_type(Context *context, Type *type)
case TYPE_TYPEID:
case TYPE_ANY:
case TYPE_ANYERR:
case TYPE_STRLIT:
case TYPE_VECTOR:
case TYPE_TYPEINFO:
case TYPE_UNTYPED_LIST:

View File

@@ -12,7 +12,7 @@ static struct
Type f16, f32, f64, f128, fxx;
Type usz, isz, uptr, iptr, uptrdiff, iptrdiff;
Type voidstar, typeid, anyerr, typeinfo, ctlist;
Type str, any, anyfail;
Type any, anyfail;
} t;
Type *type_bool = &t.u1;
@@ -41,7 +41,6 @@ Type *type_u128 = &t.u128;
Type *type_uptr = &t.uptr;
Type *type_uptrdiff = &t.uptrdiff;
Type *type_usize = &t.usz;
Type *type_compstr = &t.str;
Type *type_anyerr = &t.anyerr;
Type *type_complist = &t.ctlist;
Type *type_anyfail = &t.anyfail;
@@ -146,8 +145,6 @@ const char *type_to_error_string(Type *type)
if (!type->failable) return "void!";
asprintf(&buffer, "%s!", type_to_error_string(type->failable));
return buffer;
case TYPE_STRLIT:
return "string literal";
case TYPE_ARRAY:
asprintf(&buffer, "%s[%llu]", type_to_error_string(type->array.base), (unsigned long long)type->array.len);
return buffer;
@@ -235,7 +232,6 @@ RETRY:
case TYPE_ANYERR:
case TYPE_ANY:
return type->builtin.bytesize;
case TYPE_STRLIT:
case TYPE_FUNC:
case TYPE_POINTER:
return t.iptr.canonical->builtin.bytesize;
@@ -306,7 +302,6 @@ bool type_is_abi_aggregate(Type *type)
case TYPE_POINTER:
case TYPE_ENUM:
case TYPE_FUNC:
case TYPE_STRLIT:
case TYPE_VECTOR:
case TYPE_ANYERR:
case TYPE_ERRTYPE:
@@ -447,7 +442,6 @@ AlignSize type_abi_alignment(Type *type)
return type->builtin.abi_alignment;
case TYPE_FUNC:
case TYPE_POINTER:
case TYPE_STRLIT:
case TYPE_TYPEID:
return t.iptr.canonical->builtin.abi_alignment;
case TYPE_ARRAY:
@@ -724,8 +718,6 @@ Type *type_get_indexed_type(Type *type)
case TYPE_INFERRED_ARRAY:
case TYPE_VECTOR:
return type->array.base;
case TYPE_STRLIT:
return type_char;
case TYPE_DISTINCT:
type = type->decl->distinct_decl.base_type;
goto RETRY;
@@ -925,7 +917,6 @@ static void type_append_name_to_scratch(Type *type)
case TYPE_VECTOR:
scratch_buffer_append(type->name);
break;
case TYPE_STRLIT:
case TYPE_UNTYPED_LIST:
case TYPE_INFERRED_ARRAY:
case TYPE_TYPEINFO:
@@ -1017,7 +1008,6 @@ void type_setup(PlatformTarget *target)
type_init_int("void", &t.u0, TYPE_VOID, BITS8);
type_init("string", &t.str, TYPE_STRLIT, target->width_pointer, target->align_pointer);
type_create("typeinfo", &t.typeinfo, TYPE_TYPEINFO, 1, 1, 1);
@@ -1092,7 +1082,6 @@ bool type_is_scalar(Type *type)
case TYPE_BOOL:
case ALL_INTS:
case ALL_FLOATS:
case TYPE_STRLIT:
case TYPE_TYPEID:
case TYPE_POINTER:
case TYPE_ENUM:
@@ -1314,6 +1303,20 @@ static inline Type *type_find_max_ptr_type(Type *type, Type *other)
}
Type *type_decay_array_pointer(Type *type)
{
assert(type->type_kind == TYPE_POINTER);
Type *ptr = type->pointer;
switch (ptr->type_kind)
{
case TYPE_ARRAY:
return type_get_ptr(ptr->array.base->canonical);
case TYPE_VECTOR:
return type_get_ptr(ptr->vector.base->canonical);
default:
return type;
}
}
Type *type_find_max_type(Type *type, Type *other)
{
if (type == type_anyfail)
@@ -1361,6 +1364,28 @@ Type *type_find_max_type(Type *type, Type *other)
if (other->type_kind == TYPE_DISTINCT && type_is_float(other->decl->distinct_decl.base_type)) return other;
return type_find_max_num_type(type, other);
case TYPE_POINTER:
if (type->pointer->type_kind == TYPE_ARRAY)
{
Type *array_base = type->pointer->array.base->canonical;
if (other->type_kind == TYPE_SUBARRAY &&
array_base == other->array.base->canonical)
{
return other;
}
}
if (type->pointer->type_kind == TYPE_VECTOR)
{
Type *vector_base = type->pointer->vector.base->canonical;
if (other->type_kind == TYPE_SUBARRAY && vector_base == other->array.base->canonical)
{
return other;
}
}
// We need to decay the pointer
type = type_decay_array_pointer(type);
// And possibly the other pointer as well
if (other->type_kind == TYPE_POINTER) other = type_decay_array_pointer(other);
return type_find_max_ptr_type(type, other);
case TYPE_ENUM:
// IMPROVE: should there be implicit conversion between one enum and the other in
@@ -1378,17 +1403,6 @@ Type *type_find_max_type(Type *type, Type *other)
TODO
case TYPE_TYPEDEF:
UNREACHABLE
case TYPE_STRLIT:
if (other->type_kind == TYPE_DISTINCT)
{
// In this case we only react to the flattened type.
Type *flatten_other = type_flatten(other);
if (flatten_other->type_kind == TYPE_SUBARRAY && flatten_other->array.base->type_kind == TYPE_U8) return other;
if (flatten_other->type_kind == TYPE_POINTER && flatten_other->pointer->type_kind == TYPE_U8) return other;
}
if (other->type_kind == TYPE_SUBARRAY && other->array.base->type_kind == TYPE_U8) return other;
if (other->type_kind == TYPE_POINTER && other->pointer->type_kind == TYPE_U8) return other;
return NULL;
case TYPE_DISTINCT:
return NULL;
case TYPE_ARRAY:

View File

@@ -49,17 +49,15 @@ fn void main()
@.str.7 = private constant [14 x i8] c"donnowifprime\00", align 1
@.str.8 = private constant [4 x i8] c"%s\0A\00", align 1
@.str.9 = private constant [14 x i8] c"donnowifprime\00", align 1
; Function Attrs: nounwind
declare void @printf(i8*, ...) #0
; Function Attrs: nounwind
define void @main() #0 {
entry:
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.3, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.5, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.7, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.9, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), [5 x i8]* bitcast ([6 x i8]* @.str.1 to [5 x i8]*))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), [9 x i8]* bitcast ([10 x i8]* @.str.3 to [9 x i8]*))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i32 0, i32 0), [9 x i8]* bitcast ([10 x i8]* @.str.5 to [9 x i8]*))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.6, i32 0, i32 0), [13 x i8]* bitcast ([14 x i8]* @.str.7 to [13 x i8]*))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.8, i32 0, i32 0), [13 x i8]* bitcast ([14 x i8]* @.str.9 to [13 x i8]*))
ret void
}
}

View File

@@ -37,8 +37,8 @@ declare void @printf(i8*, ...) #0
; Function Attrs: nounwind
define void @main() #0 {
entry:
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.3, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.5, i32 0, i32 0))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), [3 x i8]* bitcast ([4 x i8]* @.str.1 to [3 x i8]*))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.2, i32 0, i32 0), [6 x i8]* bitcast ([7 x i8]* @.str.3 to [6 x i8]*))
call void (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.4, i32 0, i32 0), [9 x i8]* bitcast ([10 x i8]* @.str.5 to [9 x i8]*))
ret void
}

View File

@@ -43,13 +43,13 @@ fn void main()
define void @main()
%help = alloca i32, align 4
store i32 0, i32* %help, align 4
%0 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.1, i32 0, i32 0))
%1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i32 0, i32 0), i8* getelementptr inbounds ([18 x i8], [18 x i8]* @.str.3, i32 0, i32 0))
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.4, i32 0, i32 0), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.5, i32 0, i32 0))
%3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.6, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.7, i32 0, i32 0))
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.8, i32 0, i32 0), i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.9, i32 0, i32 0))
%5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.10, i32 0, i32 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.11, i32 0, i32 0))
%6 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.12, i32 0, i32 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.13, i32 0, i32 0))
%7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.14, i32 0, i32 0), i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.15, i32 0, i32 0))
%8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.16, i32 0, i32 0), i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.17, i32 0, i32 0))
%0 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([12 x i8], [12 x i8]* @.str, i32 0, i32 0), [6 x i8]* bitcast ([7 x i8]* @.str.1 to [6 x i8]*))
%1 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str.2, i32 0, i32 0), [17 x i8]* bitcast ([18 x i8]* @.str.3 to [17 x i8]*))
%2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.4, i32 0, i32 0), [15 x i8]* bitcast ([16 x i8]* @.str.5 to [15 x i8]*))
%3 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.6, i32 0, i32 0), [4 x i8]* bitcast ([5 x i8]* @.str.7 to [4 x i8]*))
%4 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.8, i32 0, i32 0), [12 x i8]* bitcast ([13 x i8]* @.str.9 to [12 x i8]*))
%5 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.10, i32 0, i32 0), [1 x i8]* bitcast ([2 x i8]* @.str.11 to [1 x i8]*))
%6 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.12, i32 0, i32 0), [4 x i8]* bitcast ([5 x i8]* @.str.13 to [4 x i8]*))
%7 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.14, i32 0, i32 0), [15 x i8]* bitcast ([16 x i8]* @.str.15 to [15 x i8]*))
%8 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.16, i32 0, i32 0), [9 x i8]* bitcast ([10 x i8]* @.str.17 to [9 x i8]*))
ret void

View File

@@ -0,0 +1,24 @@
// #target: x64-darwin
module foo;
fn void main()
{
char[2] x = "ab";
char[*] y = "abc";
}
/* #expect: foo.ll
@.str = private constant [3 x i8] c"ab\00", align 1
@.str.1 = private constant [4 x i8] c"abc\00", align 1
define void @main() #0 {
entry:
%x = alloca [2 x i8], align 1
%y = alloca [3 x i8], align 1
%0 = bitcast [2 x i8]* %x to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %0, i8* align 8 getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i32 0, i32 0), i32 2, i1 false)
%1 = bitcast [3 x i8]* %y to i8*
call void @llvm.memcpy.p0i8.p0i8.i32(i8* align 1 %1, i8* align 8 getelementptr inbounds ([4 x i8], [4 x i8]* @.str.1, i32 0, i32 0), i32 3, i1 false)
ret void
}

View File

@@ -125,7 +125,7 @@ fn void test16()
fn void test17()
{
int a = "test"; // #error: 'string literal' into 'int'
int a = "test"; // #error: 'char[4]*' into 'int'
}
fn void test18()

View File

@@ -12,6 +12,6 @@ fn int foo()
enum State
{
A = foo(), // #error: Expected a constant expression for enum
B = "hello", // #error: 'string literal' into 'int'
B = "hello", // #error: 'char[5]*' into 'int'
C = true, // #error: 'bool' to 'int'
}