From ebf62d058e76e75bd526e3ab98cd9bde08b34f32 Mon Sep 17 00:00:00 2001 From: RazvanN7 Date: Wed, 30 Oct 2019 12:37:18 +0200 Subject: [PATCH 1/5] Fix Issue 20318 - Illegal instruction (core dumped) --- src/dmd/e2ir.d | 6 ++++++ test/compilable/test20318.d | 7 +++++++ 2 files changed, 13 insertions(+) create mode 100644 test/compilable/test20318.d diff --git a/src/dmd/e2ir.d b/src/dmd/e2ir.d index 9150995fbcfb..c32e4c4a6625 100644 --- a/src/dmd/e2ir.d +++ b/src/dmd/e2ir.d @@ -6197,6 +6197,12 @@ void toTraceGC(IRState *irs, elem *e, const ref Loc loc) assert(e1.Eoper == OPvar); auto s = e1.EV.Vsym; + /* In -dip1008 code the allocation of exceptions is no longer done by the + * gc, but by a manual reference counting mechanism implementend in druntime. + * If that is the case, then there is nothing to trace. + */ + if (s == getRtlsym(RTLSYM_NEWTHROW)) + return; foreach (ref m; map) { if (s == getRtlsym(m[0])) diff --git a/test/compilable/test20318.d b/test/compilable/test20318.d new file mode 100644 index 000000000000..58d396975152 --- /dev/null +++ b/test/compilable/test20318.d @@ -0,0 +1,7 @@ +// https://issues.dlang.org/show_bug.cgi?id=20318 +// REQUIRED_ARGS: -dip1008 -profile=gc + +void main() +{ + throw new Exception("msg"); +} From b4c260e8f1396e92c1cd80471a506cbe7c81b44f Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Fri, 2 Aug 2019 14:48:52 +0300 Subject: [PATCH 2/5] Add hasElaborateCopyConstructor trait --- src/dmd/id.d | 1 + src/dmd/traits.d | 13 +++++++++++-- test/compilable/traits.d | 42 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/dmd/id.d b/src/dmd/id.d index 8c66c4c15dfb..16395937d90b 100644 --- a/src/dmd/id.d +++ b/src/dmd/id.d @@ -431,6 +431,7 @@ immutable Msgtable[] msgtable = { "isZeroInit" }, { "getTargetInfo" }, { "getLocation" }, + { "hasElaborateCopyConstructor" }, // For C++ mangling { "allocator" }, diff --git a/src/dmd/traits.d b/src/dmd/traits.d index b033abd19aa6..8e9092914a59 100644 --- a/src/dmd/traits.d +++ b/src/dmd/traits.d @@ -144,6 +144,7 @@ shared static this() "isZeroInit", "getTargetInfo", "getLocation", + "hasElaborateCopyConstructor" ]; StringTable* stringTable = cast(StringTable*) &traitsStringTable; @@ -606,7 +607,8 @@ Expression semanticTraits(TraitsExp e, Scope* sc) sm => sm.isTemplateDeclaration() !is null) != 0; }); } - if (e.ident == Id.isPOD) + if (e.ident == Id.isPOD || + e.ident == Id.hasElaborateCopyConstructor) { if (dim != 1) return dimError(1); @@ -623,7 +625,14 @@ Expression semanticTraits(TraitsExp e, Scope* sc) Type tb = t.baseElemOf(); if (auto sd = tb.ty == Tstruct ? (cast(TypeStruct)tb).sym : null) { - return sd.isPOD() ? True() : False(); + if (e.ident == Id.isPOD) + { + return sd.isPOD() ? True() : False(); + } + else if (e.ident == Id.hasElaborateCopyConstructor) + { + return sd.hasCopyCtor ? True() : False(); + } } return True(); } diff --git a/test/compilable/traits.d b/test/compilable/traits.d index 27c9595ccd17..d02ef75dd21e 100644 --- a/test/compilable/traits.d +++ b/test/compilable/traits.d @@ -86,3 +86,45 @@ struct Outer static assert(__traits(getLocation, Outer.Nested)[1] == 82); static assert(__traits(getLocation, Outer.method)[1] == 84); +/******************************************/ +// https://issues.dlang.org/show_bug.cgi?id=19902 +// Define hasElaborateCopyConstructor trait + +struct S +{ + this (ref S rhs) {} +} + +struct OuterS +{ + struct S + { + this (ref S rhs) {} + } +} + +void foo(T)() +{ + struct S(U) + { + this (ref S rhs) {} + } + static assert (__traits(hasElaborateCopyConstructor, S!int)); +} + +struct U(T) { + this (ref U rhs) {} +} + +struct SPostblit { + this(this) {} +} + +static assert(__traits(hasElaborateCopyConstructor, S)); +static assert(__traits(hasElaborateCopyConstructor, OuterS.S)); +static assert(__traits(compiles, foo!int)); +static assert(__traits(compiles, foo!S)); +static assert(__traits(hasElaborateCopyConstructor, U!int)); +static assert(__traits(hasElaborateCopyConstructor, U!S)); + +static assert(!__traits(hasElaborateCopyConstructor, SPostblit)); From 8e3b4fb73dedf2fc75a7cd0f29a90ad959413283 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Fri, 2 Aug 2019 15:00:57 +0300 Subject: [PATCH 3/5] Postblit is still a form of copy constructor --- src/dmd/traits.d | 33 +++++++++++++++++++++++---------- test/compilable/traits.d | 17 ++++++++++++++--- 2 files changed, 37 insertions(+), 13 deletions(-) diff --git a/src/dmd/traits.d b/src/dmd/traits.d index 8e9092914a59..0fb916e426fb 100644 --- a/src/dmd/traits.d +++ b/src/dmd/traits.d @@ -607,8 +607,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) sm => sm.isTemplateDeclaration() !is null) != 0; }); } - if (e.ident == Id.isPOD || - e.ident == Id.hasElaborateCopyConstructor) + if (e.ident == Id.isPOD) { if (dim != 1) return dimError(1); @@ -625,17 +624,31 @@ Expression semanticTraits(TraitsExp e, Scope* sc) Type tb = t.baseElemOf(); if (auto sd = tb.ty == Tstruct ? (cast(TypeStruct)tb).sym : null) { - if (e.ident == Id.isPOD) - { - return sd.isPOD() ? True() : False(); - } - else if (e.ident == Id.hasElaborateCopyConstructor) - { - return sd.hasCopyCtor ? True() : False(); - } + return sd.isPOD() ? True() : False(); } return True(); } + if (e.ident == Id.hasElaborateCopyConstructor) + { + if (dim != 1) + return dimError(1); + + auto o = (*e.args)[0]; + auto t = isType(o); + if (!t) + { + e.error("type expected as second argument of __traits `%s` instead of `%s`", + e.ident.toChars(), o.toChars()); + return new ErrorExp(); + } + + Type tb = t.baseElemOf(); + if (auto sd = tb.ty == Tstruct ? (cast(TypeStruct)tb).sym : null) + { + return sd.hasCopyCtor || sd.postblit ? True() : False(); + } + return False(); + } if (e.ident == Id.isNested) { if (dim != 1) diff --git a/test/compilable/traits.d b/test/compilable/traits.d index d02ef75dd21e..36dacf4fa2b4 100644 --- a/test/compilable/traits.d +++ b/test/compilable/traits.d @@ -101,6 +101,8 @@ struct OuterS { this (ref S rhs) {} } + + S s; } void foo(T)() @@ -112,19 +114,28 @@ void foo(T)() static assert (__traits(hasElaborateCopyConstructor, S!int)); } -struct U(T) { +struct U(T) +{ this (ref U rhs) {} } -struct SPostblit { +struct SPostblit +{ this(this) {} } +struct NoCpCtor { } +class C19902 { } + static assert(__traits(hasElaborateCopyConstructor, S)); static assert(__traits(hasElaborateCopyConstructor, OuterS.S)); +static assert(__traits(hasElaborateCopyConstructor, OuterS)); static assert(__traits(compiles, foo!int)); static assert(__traits(compiles, foo!S)); static assert(__traits(hasElaborateCopyConstructor, U!int)); static assert(__traits(hasElaborateCopyConstructor, U!S)); +static assert(__traits(hasElaborateCopyConstructor, SPostblit)); -static assert(!__traits(hasElaborateCopyConstructor, SPostblit)); +static assert(!__traits(hasElaborateCopyConstructor, NoCpCtor)); +static assert(!__traits(hasElaborateCopyConstructor, C19902)); +static assert(!__traits(hasElaborateCopyConstructor, int)); From dacc5a766306c08df71dcf353efbfef56bb73d54 Mon Sep 17 00:00:00 2001 From: Eduard Staniloiu Date: Mon, 5 Aug 2019 15:37:26 +0300 Subject: [PATCH 4/5] Increase codecov --- test/compilable/traits.d | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/compilable/traits.d b/test/compilable/traits.d index 36dacf4fa2b4..0240cf44a0df 100644 --- a/test/compilable/traits.d +++ b/test/compilable/traits.d @@ -139,3 +139,7 @@ static assert(__traits(hasElaborateCopyConstructor, SPostblit)); static assert(!__traits(hasElaborateCopyConstructor, NoCpCtor)); static assert(!__traits(hasElaborateCopyConstructor, C19902)); static assert(!__traits(hasElaborateCopyConstructor, int)); + +// Check that invalid use cases don't compile +static assert(!__traits(compiles, __traits(hasElaborateCopyConstructor))); +static assert(!__traits(compiles, __traits(hasElaborateCopyConstructor, S()))); From 436f01073919d544af7bd4c0cf203d014354f491 Mon Sep 17 00:00:00 2001 From: "Adam D. Ruppe" Date: Fri, 1 Nov 2019 09:50:19 -0400 Subject: [PATCH 5/5] Split hasElaborateCopyConstructor into independent traits --- src/dmd/id.d | 3 ++- src/dmd/traits.d | 9 ++++++--- test/compilable/traits.d | 35 ++++++++++++++++++++++------------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src/dmd/id.d b/src/dmd/id.d index 16395937d90b..889aa48fd9c3 100644 --- a/src/dmd/id.d +++ b/src/dmd/id.d @@ -431,7 +431,8 @@ immutable Msgtable[] msgtable = { "isZeroInit" }, { "getTargetInfo" }, { "getLocation" }, - { "hasElaborateCopyConstructor" }, + { "hasPostblit" }, + { "hasCopyConstructor" }, // For C++ mangling { "allocator" }, diff --git a/src/dmd/traits.d b/src/dmd/traits.d index 0fb916e426fb..8c20dedb362b 100644 --- a/src/dmd/traits.d +++ b/src/dmd/traits.d @@ -144,7 +144,8 @@ shared static this() "isZeroInit", "getTargetInfo", "getLocation", - "hasElaborateCopyConstructor" + "hasPostblit", + "hasCopyConstructor", ]; StringTable* stringTable = cast(StringTable*) &traitsStringTable; @@ -628,7 +629,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc) } return True(); } - if (e.ident == Id.hasElaborateCopyConstructor) + if (e.ident == Id.hasCopyConstructor || e.ident == Id.hasPostblit) { if (dim != 1) return dimError(1); @@ -645,10 +646,12 @@ Expression semanticTraits(TraitsExp e, Scope* sc) Type tb = t.baseElemOf(); if (auto sd = tb.ty == Tstruct ? (cast(TypeStruct)tb).sym : null) { - return sd.hasCopyCtor || sd.postblit ? True() : False(); + return (e.ident == Id.hasPostblit) ? (sd.postblit ? True() : False()) + : (sd.hasCopyCtor ? True() : False()); } return False(); } + if (e.ident == Id.isNested) { if (dim != 1) diff --git a/test/compilable/traits.d b/test/compilable/traits.d index 0240cf44a0df..2f5258064c5f 100644 --- a/test/compilable/traits.d +++ b/test/compilable/traits.d @@ -89,6 +89,8 @@ static assert(__traits(getLocation, Outer.method)[1] == 84); /******************************************/ // https://issues.dlang.org/show_bug.cgi?id=19902 // Define hasElaborateCopyConstructor trait +// but done as two independent traits per conversation +// in https://github.com/dlang/dmd/pull/10265 struct S { @@ -111,7 +113,7 @@ void foo(T)() { this (ref S rhs) {} } - static assert (__traits(hasElaborateCopyConstructor, S!int)); + static assert (__traits(hasCopyConstructor, S!int)); } struct U(T) @@ -127,19 +129,26 @@ struct SPostblit struct NoCpCtor { } class C19902 { } -static assert(__traits(hasElaborateCopyConstructor, S)); -static assert(__traits(hasElaborateCopyConstructor, OuterS.S)); -static assert(__traits(hasElaborateCopyConstructor, OuterS)); +static assert(__traits(hasCopyConstructor, S)); +static assert(__traits(hasCopyConstructor, OuterS.S)); +static assert(__traits(hasCopyConstructor, OuterS)); static assert(__traits(compiles, foo!int)); static assert(__traits(compiles, foo!S)); -static assert(__traits(hasElaborateCopyConstructor, U!int)); -static assert(__traits(hasElaborateCopyConstructor, U!S)); -static assert(__traits(hasElaborateCopyConstructor, SPostblit)); - -static assert(!__traits(hasElaborateCopyConstructor, NoCpCtor)); -static assert(!__traits(hasElaborateCopyConstructor, C19902)); -static assert(!__traits(hasElaborateCopyConstructor, int)); +static assert(__traits(hasCopyConstructor, U!int)); +static assert(__traits(hasCopyConstructor, U!S)); +static assert(!__traits(hasPostblit, U!S)); +static assert(__traits(hasPostblit, SPostblit)); +static assert(!__traits(hasCopyConstructor, SPostblit)); + +static assert(!__traits(hasCopyConstructor, NoCpCtor)); +static assert(!__traits(hasCopyConstructor, C19902)); +static assert(!__traits(hasCopyConstructor, int)); +static assert(!__traits(hasPostblit, NoCpCtor)); +static assert(!__traits(hasPostblit, C19902)); +static assert(!__traits(hasPostblit, int)); // Check that invalid use cases don't compile -static assert(!__traits(compiles, __traits(hasElaborateCopyConstructor))); -static assert(!__traits(compiles, __traits(hasElaborateCopyConstructor, S()))); +static assert(!__traits(compiles, __traits(hasCopyConstructor))); +static assert(!__traits(compiles, __traits(hasCopyConstructor, S()))); +static assert(!__traits(compiles, __traits(hasPostblit))); +static assert(!__traits(compiles, __traits(hasPostblit, S())));