fix infinite recursion in type_has_one_possible_value

closes #2006
This commit is contained in:
Andrew Kelley 2019-02-25 16:28:23 -05:00
parent 33cbb29def
commit 7b8c5578c6
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
5 changed files with 36 additions and 10 deletions

View File

@ -1240,6 +1240,12 @@ enum ZigTypeId {
ZigTypeIdVector,
};
enum OnePossibleValue {
OnePossibleValueInvalid,
OnePossibleValueNo,
OnePossibleValueYes,
};
struct ZigType {
ZigTypeId id;
Buf name;
@ -1247,9 +1253,6 @@ struct ZigType {
LLVMTypeRef type_ref;
ZigLLVMDIType *di_type;
bool zero_bits; // this is denormalized data
bool gen_h_loop_flag;
union {
ZigTypePointer pointer;
ZigTypeInt integral;
@ -1275,6 +1278,11 @@ struct ZigType {
// If we generate a constant name value for this type, we memoize it here.
// The type of this is array
ConstExprValue *cached_const_name_val;
OnePossibleValue one_possible_value;
bool zero_bits; // this is denormalized data
bool gen_h_loop_flag;
};
struct PackageTableEntry {

View File

@ -5129,6 +5129,10 @@ bool type_has_bits(ZigType *type_entry) {
// Whether you can infer the value based solely on the type.
OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
assert(type_entry != nullptr);
if (type_entry->one_possible_value != OnePossibleValueInvalid)
return type_entry->one_possible_value;
Error err;
if ((err = type_resolve(g, type_entry, ResolveStatusZeroBitsKnown)))
return OnePossibleValueInvalid;
@ -5176,8 +5180,14 @@ OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry) {
case ZigTypeIdInt:
case ZigTypeIdVector:
return type_has_bits(type_entry) ? OnePossibleValueNo : OnePossibleValueYes;
case ZigTypeIdPointer:
return type_has_one_possible_value(g, type_entry->data.pointer.child_type);
case ZigTypeIdPointer: {
ZigType *elem_type = type_entry->data.pointer.child_type;
// If the recursive function call asks, then we are not one possible value.
type_entry->one_possible_value = OnePossibleValueNo;
// Now update it to be the value of the recursive call.
type_entry->one_possible_value = type_has_one_possible_value(g, elem_type);
return type_entry->one_possible_value;
}
case ZigTypeIdUnion:
if (type_entry->data.unionation.src_field_count > 1)
return OnePossibleValueNo;

View File

@ -226,11 +226,6 @@ enum ReqCompTime {
};
ReqCompTime type_requires_comptime(CodeGen *g, ZigType *type_entry);
enum OnePossibleValue {
OnePossibleValueInvalid,
OnePossibleValueNo,
OnePossibleValueYes,
};
OnePossibleValue type_has_one_possible_value(CodeGen *g, ZigType *type_entry);
Error ensure_const_val_repr(IrAnalyze *ira, CodeGen *codegen, AstNode *source_node,

View File

@ -19,6 +19,7 @@ comptime {
_ = @import("behavior/bugs/1442.zig");
_ = @import("behavior/bugs/1486.zig");
_ = @import("behavior/bugs/1851.zig");
_ = @import("behavior/bugs/2006.zig");
_ = @import("behavior/bugs/394.zig");
_ = @import("behavior/bugs/421.zig");
_ = @import("behavior/bugs/655.zig");

View File

@ -0,0 +1,12 @@
const std = @import("std");
const expect = std.testing.expect;
const S = struct {
p: *S,
};
test "bug 2006" {
var a: S = undefined;
a = S{ .p = undefined };
expect(@sizeOf(S) != 0);
expect(@sizeOf(*void) == 0);
}