Skip to content

Commit

Permalink
Fix 18472: betterC cannot use format at compile time.
Browse files Browse the repository at this point in the history
  • Loading branch information
Etienne Cimon committed Dec 7, 2022
1 parent 0629537 commit fb14d42
Show file tree
Hide file tree
Showing 8 changed files with 57 additions and 7 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dmd/backend/util2.d
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ void file_progress()
/****************************
* Clean up and exit program.
*/

@trusted
void err_exit()
{
util_exit(EXIT_FAILURE);
Expand Down
9 changes: 9 additions & 0 deletions compiler/src/dmd/dinterpret.d
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,12 @@ public Expression ctfeInterpret(Expression e)

auto rgnpos = ctfeGlobals.region.savePos();

ctfeGlobals.active = true;

Expression result = interpret(e, null);

ctfeGlobals.active = false;

// Report an error if the expression contained a `ThrowException` and
// hence generated an uncaught exception
if (auto tee = result.isThrownExceptionExp())
Expand Down Expand Up @@ -206,6 +210,10 @@ void incArrayAllocs()
++ctfeGlobals.numArrayAllocs;
}

bool isInterpreting() {
return ctfeGlobals.active;
}

/* ================================================ Implementation ======================================= */

private:
Expand All @@ -227,6 +235,7 @@ struct CtfeGlobals
int maxCallDepth = 0; // highest number of recursive calls
int numArrayAllocs = 0; // Number of allocated arrays
int numAssignments = 0; // total number of assignments executed
bool active; // whether we are interpreting a ctfe function
}

__gshared CtfeGlobals ctfeGlobals;
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dmd/s2ir.d
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ private extern (C++) class S2irVisitor : Visitor
block_next(blx, BCiftrue, null);

bcond.appendSucc(blx.curblock);
if (s.ifbody)
if (s.ifbody && !(s.condition.isVarExp() && s.condition.isVarExp().var.ident == Id.ctfe))
Statement_toIR(s.ifbody, irs, &mystate);
blx.curblock.appendSucc(bexit);

Expand Down
7 changes: 5 additions & 2 deletions compiler/src/dmd/statementsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1888,7 +1888,6 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor
{
/* https://dlang.org/spec/statement.html#IfStatement
*/

// check in syntax level
ifs.condition = checkAssignmentAsCondition(ifs.condition, sc);

Expand Down Expand Up @@ -1953,8 +1952,12 @@ package (dmd) extern (C++) final class StatementSemanticVisitor : Visitor

// Save 'root' of two branches (then and else) at the point where it forks
CtorFlow ctorflow_root = scd.ctorflow.clone();

bool needsCtfe = !global.params.useTypeInfo && !isInterpreting() && ifs.condition.isVarExp() && ifs.condition.isVarExp().var.ident == Id.ctfe;
if (needsCtfe)
scd = scd.startCTFE();
ifs.ifbody = ifs.ifbody.semanticNoScope(scd);
if (needsCtfe)
scd = scd.endCTFE();
scd.pop();

CtorFlow ctorflow_then = sc.ctorflow; // move flow results
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dmd/toobj.d
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,8 @@ void toObjFile(Dsymbol ds, bool multiobj)

override void visit(TypeInfoDeclaration tid)
{
if (isSpeculativeType(tid.tinfo))
import dmd.globals : global;
if (isSpeculativeType(tid.tinfo) || global.params.betterC)
{
//printf("-speculative '%s'\n", tid.toPrettyChars());
return;
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dmd/typinf.d
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import dmd.declaration;
import dmd.dmodule;
import dmd.dscope;
import dmd.dclass;
import dmd.dinterpret;
import dmd.dstruct;
import dmd.errors;
import dmd.expression;
Expand All @@ -41,7 +42,7 @@ extern (C++) void genTypeInfo(Expression e, const ref Loc loc, Type torig, Scope
// Even when compiling without `useTypeInfo` (e.g. -betterC) we should
// still be able to evaluate `TypeInfo` at compile-time, just not at runtime.
// https://issues.dlang.org/show_bug.cgi?id=18472
if (!sc || !(sc.flags & SCOPE.ctfe))
if (!sc || (!(sc.flags & SCOPE.ctfe) && !isInterpreting()))
{
if (!global.params.useTypeInfo)
{
Expand Down
2 changes: 1 addition & 1 deletion druntime/test/betterc/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include ../common.mak

TESTS:=test18828 test19416 test19421 test19561 test20088 test20613 test19924 test22336 test19933
TESTS:=test18472 test18828 test19416 test19421 test19561 test20088 test20613 test19924 test22336 test19933

.PHONY: all clean
all: $(addprefix $(ROOT)/,$(addsuffix ,$(TESTS))) $(addprefix $(ROOT)/,test19924.done)
Expand Down
36 changes: 36 additions & 0 deletions druntime/test/betterc/src/test18472.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*******************************************/
// https://issues.dlang.org/show_bug.cgi?id=18472
@nogc nothrow pure:
immutable(Char)[] format(Char, Args...)(in Char[] fmt, Args args)
{
if (__ctfe) {
auto data2 = new char[5];
auto data = new Data2;
data2 = cast(char[]) "test2";
return data2;
} else {
return "test";
}
}

extern(C) void main()
{
static assert("%s %s".format("test", "test") == "test2", "Not working");
assert("%s %s".format("test", "test") == "test", "%s %s".format("test", "test"));
assert(getData() == "test2", getData());
}

string getData() {
if (__ctfe) {
auto data2 = new ubyte[5];
auto data = new Data2;
return "test";
} else {
return "test2";
}
}

private struct Data2
{
size_t capacity;
}

0 comments on commit fb14d42

Please sign in to comment.