Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/dmd/dscope.d
Original file line number Diff line number Diff line change
Expand Up @@ -807,4 +807,28 @@ struct Scope
else
return STRUCTALIGN_DEFAULT;
}

/**********************************
* Checks whether the current scope (or any of its parents) is deprecated.
*
* Returns: `true` if this or any parent scope is deprecated, `false` otherwise`
*/
extern(C++) bool isDeprecated()
{
for (Dsymbol sp = this.parent; sp; sp = sp.parent)
{
if (sp.isDeprecated())
return true;
}
for (Scope* sc2 = &this; sc2; sc2 = sc2.enclosing)
{
if (sc2.scopesym && sc2.scopesym.isDeprecated())
return true;

// If inside a StorageClassDeclaration that is deprecated
if (sc2.stc & STC.deprecated_)
return true;
}
return false;
}
}
15 changes: 2 additions & 13 deletions src/dmd/dsymbol.d
Original file line number Diff line number Diff line change
Expand Up @@ -310,20 +310,9 @@ extern (C++) class Dsymbol : RootObject
if (global.params.useDeprecated != 1 && isDeprecated())
{
// Don't complain if we're inside a deprecated symbol's scope
for (Dsymbol sp = sc.parent; sp; sp = sp.parent)
{
if (sp.isDeprecated())
return false;
}
for (Scope* sc2 = sc; sc2; sc2 = sc2.enclosing)
{
if (sc2.scopesym && sc2.scopesym.isDeprecated())
return false;
if (sc.isDeprecated())
return false;

// If inside a StorageClassDeclaration that is deprecated
if (sc2.stc & STC.deprecated_)
return false;
}
const(char)* message = null;
for (Dsymbol p = this; p; p = p.parent)
{
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
//printf("storage_class = x%x\n", storage_class);

if (global.params.vcomplex)
dsym.type.checkComplexTransition(dsym.loc);
dsym.type.checkComplexTransition(dsym.loc, sc);

// Calculate type size + safety checks
if (sc.func && !sc.intypeof)
Expand Down
4 changes: 2 additions & 2 deletions src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1856,7 +1856,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
assert(0);

if (global.params.vcomplex)
exp.type.checkComplexTransition(exp.loc);
exp.type.checkComplexTransition(exp.loc, sc);

result = e;
}
Expand Down Expand Up @@ -3774,7 +3774,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}

if (global.params.vcomplex)
ta.checkComplexTransition(exp.loc);
ta.checkComplexTransition(exp.loc, sc);

Expression e;
if (ea && ta.toBasetype().ty == Tclass)
Expand Down
11 changes: 9 additions & 2 deletions src/dmd/mtype.d
Original file line number Diff line number Diff line change
Expand Up @@ -3009,16 +3009,20 @@ extern (C++) abstract class Type : RootObject
* Should only give alerts when set to emit transitional messages.
* Params:
* loc = The source location.
* sc = scope of the type
*/
final void checkComplexTransition(Loc loc)
final bool checkComplexTransition(Loc loc, Scope* sc)
{
if (sc.isDeprecated())
return false;

Type t = baseElemOf();
while (t.ty == Tpointer || t.ty == Tarray)
t = t.nextOf().baseElemOf();

// Basetype is an opaque enum, nothing to check.
if (t.ty == Tenum && !(cast(TypeEnum)t).sym.memtype)
return;
return false;

if (t.isimaginary() || t.iscomplex())
{
Expand Down Expand Up @@ -3047,13 +3051,16 @@ extern (C++) abstract class Type : RootObject
{
deprecation(loc, "use of complex type `%s` is deprecated, use `std.complex.Complex!(%s)` instead",
toChars(), rt.toChars());
return true;
}
else
{
deprecation(loc, "use of imaginary type `%s` is deprecated, use `%s` instead",
toChars(), rt.toChars());
return true;
}
}
return false;
}

static void error(Loc loc, const(char)* format, ...)
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ class Type : public RootObject
uinteger_t sizemask();
virtual bool needsDestruction();
virtual bool needsNested();
void checkComplexTransition(Loc loc);
bool checkComplexTransition(Loc loc, Scope *sc);

static void error(Loc loc, const char *format, ...);
static void warning(Loc loc, const char *format, ...);
Expand Down
2 changes: 2 additions & 0 deletions src/dmd/scope.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,8 @@ struct Scope
void setNoFree();

structalign_t alignment();

bool isDeprecated();
};

#endif /* DMD_SCOPE_H */
2 changes: 1 addition & 1 deletion src/dmd/semantic3.d
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
funcdecl.fbody = new ErrorStatement();
}
if (global.params.vcomplex && f.next !is null)
f.next.checkComplexTransition(funcdecl.loc);
f.next.checkComplexTransition(funcdecl.loc, sc);

if (funcdecl.returns && !funcdecl.fbody.isErrorStatement())
{
Expand Down
13 changes: 13 additions & 0 deletions test/compilable/sw_transition_complex.d
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,16 @@ struct S;
void test14488c(E *e, S *s)
{
}

// Issue 18212 - Usage of cfloat,cdouble,cfloat,ifloat,idouble,ireal shouldn't trigger an error in deprecated code
deprecated void test18212(creal c){}
deprecated unittest
{
ireal = 2i;
creal = 2 + 3i;
}
deprecated struct Foo
{
ifloat a = 2i;
cfloat b = 2f + 2i;
}