Skip to content

Commit a8057c9

Browse files
committed
fix Issue 24130 - ImportC: Windows headers use inline asm with different syntax
1 parent ad0b7ef commit a8057c9

File tree

12 files changed

+102
-21
lines changed

12 files changed

+102
-21
lines changed

compiler/src/dmd/cli.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ dmd -cov -unittest myprog.d
610610
Option("nothrow",
611611
"assume no Exceptions will be thrown",
612612
`Turns off generation of exception stack unwinding code, enables
613-
more efficient code for RAII objects.`,
613+
more efficient code for RAII objects.`,
614614
),
615615
Option("O",
616616
"optimize",

compiler/src/dmd/cparse.d

+1-1
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ final class CParser(AST) : Parser!AST
626626

627627
default:
628628
// ImportC extensions: parse as a D asm block.
629-
s = parseAsm();
629+
s = parseAsm(compileEnv.masm);
630630
break;
631631
}
632632
break;

compiler/src/dmd/dmodule.d

+2
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,9 @@ extern (C++) final class Module : Package
780780
{
781781
filetype = FileType.c;
782782

783+
global.compileEnv.masm = target.os == Target.OS.Windows && !target.omfobj; // Microsoft inline assembler format
783784
scope p = new CParser!AST(this, buf, cast(bool) docfile, global.errorSink, target.c, &defines, &global.compileEnv);
785+
global.compileEnv.masm = false;
784786
p.nextToken();
785787
checkCompiledImport();
786788
members = p.parseModule();

compiler/src/dmd/frontend.h

+7-3
Original file line numberDiff line numberDiff line change
@@ -3403,6 +3403,7 @@ struct CompileEnv final
34033403
bool ddocOutput;
34043404
bool shortenedMethods;
34053405
bool obsolete;
3406+
bool masm;
34063407
CompileEnv() :
34073408
versionNumber(),
34083409
date(),
@@ -3412,10 +3413,11 @@ struct CompileEnv final
34123413
previewIn(),
34133414
ddocOutput(),
34143415
shortenedMethods(true),
3415-
obsolete()
3416+
obsolete(),
3417+
masm()
34163418
{
34173419
}
3418-
CompileEnv(uint32_t versionNumber, _d_dynamicArray< const char > date = {}, _d_dynamicArray< const char > time = {}, _d_dynamicArray< const char > vendor = {}, _d_dynamicArray< const char > timestamp = {}, bool previewIn = false, bool ddocOutput = false, bool shortenedMethods = true, bool obsolete = false) :
3420+
CompileEnv(uint32_t versionNumber, _d_dynamicArray< const char > date = {}, _d_dynamicArray< const char > time = {}, _d_dynamicArray< const char > vendor = {}, _d_dynamicArray< const char > timestamp = {}, bool previewIn = false, bool ddocOutput = false, bool shortenedMethods = true, bool obsolete = false, bool masm = false) :
34193421
versionNumber(versionNumber),
34203422
date(date),
34213423
time(time),
@@ -3424,7 +3426,8 @@ struct CompileEnv final
34243426
previewIn(previewIn),
34253427
ddocOutput(ddocOutput),
34263428
shortenedMethods(shortenedMethods),
3427-
obsolete(obsolete)
3429+
obsolete(obsolete),
3430+
masm(masm)
34283431
{}
34293432
};
34303433

@@ -4237,6 +4240,7 @@ class AsmStatement : public Statement
42374240
{
42384241
public:
42394242
Token* tokens;
4243+
bool caseSensitive;
42404244
AsmStatement* syntaxCopy() override;
42414245
void accept(Visitor* v) override;
42424246
};

compiler/src/dmd/glue.d

+4-4
Original file line numberDiff line numberDiff line change
@@ -565,10 +565,10 @@ private void genObjFile(Module m, bool multiobj)
565565

566566
outdata(m.cov);
567567

568-
size_t sz = m.covb[0].sizeof;
569-
size_t n = (m.numlines + sz * 8) / (sz * 8);
570-
uint* p = cast(uint*)Mem.check(calloc(n, sz));
571-
m.covb = p[0 .. n];
568+
size_t sz = m.covb[0].sizeof;
569+
size_t n = (m.numlines + sz * 8) / (sz * 8);
570+
uint* p = cast(uint*)Mem.check(calloc(n, sz));
571+
m.covb = p[0 .. n];
572572
}
573573

574574
for (int i = 0; i < m.members.length; i++)

compiler/src/dmd/iasm.d

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ extern(C++) Statement asmSemantic(AsmStatement s, Scope *sc)
6464
return statementSemantic(se, sc);
6565
}
6666
auto ias = new InlineAsmStatement(s.loc, s.tokens);
67+
ias.caseSensitive = s.caseSensitive;
6768
return inlineAsmSemantic(ias, sc);
6869
}
6970
else version (IN_GCC)

compiler/src/dmd/iasmdmd.d

+52-9
Original file line numberDiff line numberDiff line change
@@ -344,14 +344,15 @@ immutable:
344344
ubyte val;
345345
opflag_t ty;
346346

347-
bool isSIL_DIL_BPL_SPL() const @safe
347+
bool isSIL_DIL_BPL_SPL() const @trusted
348348
{
349+
bool caseSensitive = asmstate.statement.caseSensitive;
349350
// Be careful as these have the same val's as AH CH DH BH
350351
return ty == _r8 &&
351-
((val == _SIL && regstr == "SIL") ||
352-
(val == _DIL && regstr == "DIL") ||
353-
(val == _BPL && regstr == "BPL") ||
354-
(val == _SPL && regstr == "SPL"));
352+
((val == _SIL && stringEq(regstr, "SIL", caseSensitive)) ||
353+
(val == _DIL && stringEq(regstr, "DIL", caseSensitive)) ||
354+
(val == _BPL && stringEq(regstr, "BPL", caseSensitive)) ||
355+
(val == _SPL && stringEq(regstr, "SPL", caseSensitive)));
355356
}
356357
}
357358

@@ -2161,9 +2162,9 @@ private @safe pure bool asm_isNonZeroInt(const ref OPND o)
21612162
/*******************************
21622163
*/
21632164

2164-
private @safe pure bool asm_is_fpreg(const(char)[] szReg)
2165+
private @trusted bool asm_is_fpreg(const(char)[] szReg)
21652166
{
2166-
return szReg == "ST";
2167+
return stringEq(szReg, "ST", asmstate.statement.caseSensitive);
21672168
}
21682169

21692170
/*******************************
@@ -3395,9 +3396,10 @@ immutable(REG)* asm_reg_lookup(const(char)[] s)
33953396
{
33963397
//dbg_printf("asm_reg_lookup('%s')\n",s);
33973398

3399+
bool caseSensitive = asmstate.statement.caseSensitive;
33983400
for (int i = 0; i < regtab.length; i++)
33993401
{
3400-
if (s == regtab[i].regstr)
3402+
if (stringEq(s, regtab[i].regstr, caseSensitive))
34013403
{
34023404
return &regtab[i];
34033405
}
@@ -3406,7 +3408,7 @@ immutable(REG)* asm_reg_lookup(const(char)[] s)
34063408
{
34073409
for (int i = 0; i < regtab64.length; i++)
34083410
{
3409-
if (s == regtab64[i].regstr)
3411+
if (stringEq(s, regtab64[i].regstr, caseSensitive))
34103412
{
34113413
return &regtab64[i];
34123414
}
@@ -4648,3 +4650,44 @@ unittest
46484650
assert( isOneOf(_8, _anysize));
46494651
}
46504652
}
4653+
4654+
/**********************************
4655+
* Case insensitive string compare
4656+
* Returns: true if equal
4657+
*/
4658+
4659+
bool stringEq(const(char)[] s1, const(char)[] s2, bool caseSensitive)
4660+
{
4661+
if (caseSensitive)
4662+
return s1 == s2;
4663+
4664+
if (s1.length != s2.length)
4665+
return false;
4666+
foreach (i, c; s1)
4667+
{
4668+
char c1 = c;
4669+
if ('A' <= c1 && c1 <= 'Z')
4670+
c1 |= 0x20;
4671+
char c2 = s2[i];
4672+
if ('A' <= c2 && c2 <= 'Z')
4673+
c2 |= 0x20;
4674+
4675+
if (c1 != c2)
4676+
return false;
4677+
}
4678+
return true;
4679+
}
4680+
4681+
unittest
4682+
{
4683+
assert(!stringEq("ABZ", "ABZX", true));
4684+
4685+
assert( stringEq("ABZ", "ABZ", true));
4686+
assert(!stringEq("aBz", "ABZ", true));
4687+
assert(!stringEq("ABZ", "ABz", true));
4688+
4689+
assert( stringEq("aBZ", "ABZ", false));
4690+
assert( stringEq("aBz", "AbZ", false));
4691+
assert( stringEq("ABZ", "ABz", false));
4692+
assert(!stringEq("3BZ", "ABz", false));
4693+
}

compiler/src/dmd/lexer.d

+1
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ struct CompileEnv
5252
bool ddocOutput; /// collect embedded documentation comments
5353
bool shortenedMethods = true; /// allow => in normal function declarations
5454
bool obsolete; /// warn on use of legacy code
55+
bool masm; /// use MASM inline asm syntax
5556
}
5657

5758
/***********************************************************

compiler/src/dmd/parse.d

+15-3
Original file line numberDiff line numberDiff line change
@@ -6601,7 +6601,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
66016601
}
66026602

66036603
case TOK.asm_:
6604-
s = parseAsm();
6604+
s = parseAsm(false);
66056605
break;
66066606

66076607
case TOK.import_:
@@ -6972,10 +6972,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
69726972
* AsmInstruction ;
69736973
* AsmInstruction ; AsmInstruction
69746974
*
6975+
* Params:
6976+
* endOfLine = true if EOL means end of asm statement
69756977
* Returns:
69766978
* inline assembler block as a Statement
69776979
*/
6978-
AST.Statement parseAsm()
6980+
AST.Statement parseAsm(bool endOfLine)
69796981
{
69806982
// Parse the asm block into a sequence of AsmStatements,
69816983
// each AsmStatement is one instruction.
@@ -6998,6 +7000,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
69987000
size_t nestlevel = 0;
69997001
while (1)
70007002
{
7003+
if (endOfLine)
7004+
nextDefineLine();
70017005
switch (token.value)
70027006
{
70037007
case TOK.identifier:
@@ -7032,14 +7036,20 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
70327036
}
70337037
break;
70347038

7039+
case TOK.endOfLine:
7040+
nextDefineLine();
7041+
goto case;
7042+
70357043
case TOK.semicolon:
70367044
if (nestlevel != 0)
70377045
error("mismatched number of curly brackets");
70387046

70397047
if (toklist || label)
70407048
{
70417049
// Create AsmStatement from list of tokens we've saved
7042-
AST.Statement s = new AST.AsmStatement(token.loc, toklist);
7050+
AST.AsmStatement as = new AST.AsmStatement(token.loc, toklist);
7051+
as.caseSensitive = !endOfLine;
7052+
AST.Statement s = as;
70437053
toklist = null;
70447054
ptoklist = &toklist;
70457055
if (label)
@@ -7083,6 +7093,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
70837093
break;
70847094
}
70857095
nextToken();
7096+
if (token.value == TOK.endOfLine)
7097+
nextToken();
70867098
auto s = new AST.CompoundAsmStatement(loc, statements, stc);
70877099
return s;
70887100
}

compiler/src/dmd/statement.d

+1
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,7 @@ extern (C++) final class LabelDsymbol : Dsymbol
19581958
extern (C++) class AsmStatement : Statement
19591959
{
19601960
Token* tokens;
1961+
bool caseSensitive; // for register names
19611962

19621963
extern (D) this(const ref Loc loc, Token* tokens) @safe
19631964
{

compiler/src/dmd/statement.h

+1
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,7 @@ class AsmStatement : public Statement
712712
{
713713
public:
714714
Token *tokens;
715+
bool caseSensitive; // for register names
715716

716717
AsmStatement *syntaxCopy() override;
717718
void accept(Visitor *v) override { v->visit(this); }

compiler/test/compilable/test24130.c

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/* REQUIRED_ARGS: -m32mscoff
2+
* DISABLED: freebsd32 freebsd64 linux32 linux64 osx32 osx64 win64 dragonflybsd openbsd
3+
*/
4+
5+
// https://issues.dlang.org/show_bug.cgi?id=24130
6+
7+
void test(int ShiftCount, int Value)
8+
{
9+
__asm {
10+
mov ecx, ShiftCount
11+
mov eax, dword ptr [Value]
12+
mov edx, dword ptr [Value+4]
13+
shrd eax, edx, cl
14+
shr edx, cl
15+
}
16+
}

0 commit comments

Comments
 (0)