mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 05:00:16 +03:00
Fixes issues 20339, 24292: Calculate isPOD without information from semantic run
Issue 20339: isPOD returns true if sizeof is accessed inside struct declaration Issue 24292: Struct with destructor wrongly returned in register Function StructDeclaration.isPOD can be called before the semantic run for the struct is finished. It then uses incomplete information about destructors, postblits and copy constructors. The result of isPOD is cached, so later calls will also return the wrong result. This commit changes isPOD, so it uses variables, which are already filled before the semantic run.
This commit is contained in:
parent
48de81b063
commit
a4d6972c08
5 changed files with 146 additions and 2 deletions
|
@ -1571,7 +1571,7 @@ private Statement generateCopyCtorBody(StructDeclaration sd)
|
|||
* `true` if one needs to be generated
|
||||
* `false` otherwise
|
||||
*/
|
||||
private bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor)
|
||||
bool needCopyCtor(StructDeclaration sd, out bool hasCpCtor)
|
||||
{
|
||||
if (global.errors)
|
||||
return false;
|
||||
|
|
|
@ -434,7 +434,11 @@ extern (C++) class StructDeclaration : AggregateDeclaration
|
|||
|
||||
ispod = ThreeState.yes;
|
||||
|
||||
if (enclosing || postblit || dtor || hasCopyCtor)
|
||||
import dmd.clone;
|
||||
bool hasCpCtorLocal;
|
||||
needCopyCtor(this, hasCpCtorLocal);
|
||||
|
||||
if (enclosing || search(this, loc, Id.postblit) || search(this, loc, Id.dtor) || hasCpCtorLocal)
|
||||
{
|
||||
ispod = ThreeState.no;
|
||||
return false;
|
||||
|
|
44
compiler/test/compilable/issue20339.d
Normal file
44
compiler/test/compilable/issue20339.d
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
TEST_OUTPUT:
|
||||
---
|
||||
4
|
||||
false
|
||||
false
|
||||
---
|
||||
*/
|
||||
|
||||
// https://issues.dlang.org/show_bug.cgi?id=20339
|
||||
|
||||
struct S
|
||||
{
|
||||
pragma(msg, cast(int)S.sizeof);
|
||||
|
||||
this(this){}
|
||||
~this(){}
|
||||
|
||||
int f;
|
||||
}
|
||||
|
||||
static assert(__traits(isPOD, S) == false);
|
||||
|
||||
|
||||
pragma(msg, __traits(isPOD, T));
|
||||
|
||||
struct T
|
||||
{
|
||||
this(this){}
|
||||
~this(){}
|
||||
}
|
||||
|
||||
static assert(__traits(isPOD, T) == false);
|
||||
|
||||
|
||||
struct U
|
||||
{
|
||||
pragma(msg, __traits(isPOD, U));
|
||||
|
||||
this(this){}
|
||||
~this(){}
|
||||
}
|
||||
|
||||
static assert(__traits(isPOD, U) == false);
|
46
compiler/test/runnable_cxx/extra-files/test24292.cpp
Normal file
46
compiler/test/runnable_cxx/extra-files/test24292.cpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
template<class T>
|
||||
struct List
|
||||
{
|
||||
T* begin;
|
||||
};
|
||||
|
||||
struct StructWithDestructor
|
||||
{
|
||||
~StructWithDestructor();
|
||||
|
||||
int i;
|
||||
};
|
||||
|
||||
struct StructWithCopyCtor
|
||||
{
|
||||
StructWithCopyCtor();
|
||||
StructWithCopyCtor(const StructWithCopyCtor &other);
|
||||
|
||||
int i;
|
||||
};
|
||||
|
||||
StructWithDestructor::~StructWithDestructor()
|
||||
{
|
||||
}
|
||||
|
||||
StructWithCopyCtor::StructWithCopyCtor()
|
||||
{
|
||||
}
|
||||
|
||||
StructWithCopyCtor::StructWithCopyCtor(const StructWithCopyCtor &other) : i(other.i)
|
||||
{
|
||||
}
|
||||
|
||||
StructWithDestructor getStructWithDestructor()
|
||||
{
|
||||
StructWithDestructor r;
|
||||
r.i = 12345;
|
||||
return r;
|
||||
}
|
||||
|
||||
StructWithCopyCtor getStructWithCopyCtor()
|
||||
{
|
||||
StructWithCopyCtor r;
|
||||
r.i = 54321;
|
||||
return r;
|
||||
}
|
50
compiler/test/runnable_cxx/test24292.d
Normal file
50
compiler/test/runnable_cxx/test24292.d
Normal file
|
@ -0,0 +1,50 @@
|
|||
// EXTRA_CPP_SOURCES: test24292.cpp
|
||||
|
||||
extern(C++) struct List(T)
|
||||
{
|
||||
// Any of the following static ifs can trigger the problem.
|
||||
static if (T.sizeof > 4) {}
|
||||
static if (__traits(isZeroInit, T)) {}
|
||||
static if (__traits(isPOD, T)) {}
|
||||
|
||||
T* begin;
|
||||
}
|
||||
|
||||
extern(C++) struct StructWithDestructor
|
||||
{
|
||||
~this();
|
||||
|
||||
alias L = List!StructWithDestructor;
|
||||
int i;
|
||||
}
|
||||
|
||||
extern(C++) struct StructWithCopyCtor
|
||||
{
|
||||
this(ref const(StructWithCopyCtor));
|
||||
|
||||
alias L = List!StructWithCopyCtor;
|
||||
int i;
|
||||
}
|
||||
|
||||
extern(D) struct StructWithPostblit
|
||||
{
|
||||
this(this) {}
|
||||
|
||||
alias L = List!StructWithPostblit;
|
||||
int i;
|
||||
}
|
||||
|
||||
static assert(!__traits(isPOD, StructWithDestructor));
|
||||
static assert(!__traits(isPOD, StructWithCopyCtor));
|
||||
static assert(!__traits(isPOD, StructWithPostblit));
|
||||
|
||||
extern(C++) StructWithDestructor getStructWithDestructor();
|
||||
extern(C++) StructWithCopyCtor getStructWithCopyCtor();
|
||||
|
||||
void main()
|
||||
{
|
||||
StructWithDestructor structWithDestructor = getStructWithDestructor();
|
||||
assert(structWithDestructor.i == 12345);
|
||||
StructWithCopyCtor structWithCopyCtor = getStructWithCopyCtor();
|
||||
assert(structWithCopyCtor.i == 54321);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue