mirror of
https://github.com/dlang/dmd.git
synced 2025-04-25 20:50:41 +03:00
Fix 20334: ImportC: enums created from string literal #defines don’t implicitly convert to const(char)* in D. (#21193)
Fixes: https://github.com/dlang/dmd/issues/20334 After preprocessing, #defines in C code that are just string literals are converted into D enums. As these are collected for use in D code, they should behave like D string literals and not C string literals.
This commit is contained in:
parent
81cd0b26ef
commit
e9984553e6
8 changed files with 31 additions and 7 deletions
|
@ -4954,6 +4954,8 @@ struct ASTBase
|
||||||
|
|
||||||
/// If the string is parsed from a hex string literal
|
/// If the string is parsed from a hex string literal
|
||||||
bool hexString = false;
|
bool hexString = false;
|
||||||
|
/// If the string is from a collected C macro
|
||||||
|
bool cMacro = false;
|
||||||
|
|
||||||
extern (D) this(Loc loc, const(void)[] string)
|
extern (D) this(Loc loc, const(void)[] string)
|
||||||
{
|
{
|
||||||
|
@ -4963,13 +4965,14 @@ struct ASTBase
|
||||||
this.sz = 1; // work around LDC bug #1286
|
this.sz = 1; // work around LDC bug #1286
|
||||||
}
|
}
|
||||||
|
|
||||||
extern (D) this(Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix = 0)
|
extern (D) this(Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix = 0, bool cMacro=false)
|
||||||
{
|
{
|
||||||
super(loc, EXP.string_, __traits(classInstanceSize, StringExp));
|
super(loc, EXP.string_, __traits(classInstanceSize, StringExp));
|
||||||
this.string = cast(char*)string;
|
this.string = cast(char*)string;
|
||||||
this.len = len;
|
this.len = len;
|
||||||
this.postfix = postfix;
|
this.postfix = postfix;
|
||||||
this.sz = 1; // work around LDC bug #1286
|
this.sz = 1; // work around LDC bug #1286
|
||||||
|
this.cMacro = cMacro;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**********************************************
|
/**********************************************
|
||||||
|
|
|
@ -6193,7 +6193,7 @@ final class CParser(AST) : Parser!AST
|
||||||
/* Declare manifest constant:
|
/* Declare manifest constant:
|
||||||
* enum id = "string";
|
* enum id = "string";
|
||||||
*/
|
*/
|
||||||
AST.Expression e = new AST.StringExp(scanloc, str[0 .. len], len, 1, postfix);
|
AST.Expression e = new AST.StringExp(scanloc, str[0 .. len], len, 1, postfix, true);
|
||||||
auto v = new AST.VarDeclaration(scanloc, null, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
|
auto v = new AST.VarDeclaration(scanloc, null, id, new AST.ExpInitializer(scanloc, e), STC.manifest);
|
||||||
addSym(v);
|
addSym(v);
|
||||||
++p;
|
++p;
|
||||||
|
|
|
@ -1406,6 +1406,8 @@ extern (C++) final class StringExp : Expression
|
||||||
|
|
||||||
/// If the string is parsed from a hex string literal
|
/// If the string is parsed from a hex string literal
|
||||||
bool hexString = false;
|
bool hexString = false;
|
||||||
|
/// If the string is from a collected C macro
|
||||||
|
bool cMacro = false;
|
||||||
|
|
||||||
enum char NoPostfix = 0;
|
enum char NoPostfix = 0;
|
||||||
|
|
||||||
|
@ -1417,13 +1419,14 @@ extern (C++) final class StringExp : Expression
|
||||||
this.sz = 1; // work around LDC bug #1286
|
this.sz = 1; // work around LDC bug #1286
|
||||||
}
|
}
|
||||||
|
|
||||||
extern (D) this(Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix = NoPostfix) scope
|
extern (D) this(Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix = NoPostfix, bool cMacro = false) scope
|
||||||
{
|
{
|
||||||
super(loc, EXP.string_);
|
super(loc, EXP.string_);
|
||||||
this.string = cast(char*)string.ptr; // note that this.string should be const
|
this.string = cast(char*)string.ptr; // note that this.string should be const
|
||||||
this.len = len;
|
this.len = len;
|
||||||
this.sz = sz;
|
this.sz = sz;
|
||||||
this.postfix = postfix;
|
this.postfix = postfix;
|
||||||
|
this.cMacro = cMacro;
|
||||||
}
|
}
|
||||||
|
|
||||||
static StringExp create(Loc loc, const(char)* s)
|
static StringExp create(Loc loc, const(char)* s)
|
||||||
|
|
|
@ -353,6 +353,7 @@ public:
|
||||||
unsigned char sz; // 1: char, 2: wchar, 4: dchar
|
unsigned char sz; // 1: char, 2: wchar, 4: dchar
|
||||||
d_bool committed; // if type is committed
|
d_bool committed; // if type is committed
|
||||||
d_bool hexString; // if string is parsed from a hex string literal
|
d_bool hexString; // if string is parsed from a hex string literal
|
||||||
|
d_bool cMacro; // If the string is from a collected C macro
|
||||||
|
|
||||||
static StringExp *create(Loc loc, const char *s);
|
static StringExp *create(Loc loc, const char *s);
|
||||||
static StringExp *create(Loc loc, const void *s, d_size_t len);
|
static StringExp *create(Loc loc, const void *s, d_size_t len);
|
||||||
|
|
|
@ -4429,7 +4429,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||||
}
|
}
|
||||||
buffer.write4(0);
|
buffer.write4(0);
|
||||||
e.setData(buffer.extractData(), newlen, 4);
|
e.setData(buffer.extractData(), newlen, 4);
|
||||||
if (sc && sc.inCfile)
|
if (!e.cMacro && sc && sc.inCfile)
|
||||||
e.type = Type.tuns32.sarrayOf(e.len + 1);
|
e.type = Type.tuns32.sarrayOf(e.len + 1);
|
||||||
else
|
else
|
||||||
e.type = Type.tdchar.immutableOf().arrayOf();
|
e.type = Type.tdchar.immutableOf().arrayOf();
|
||||||
|
@ -4454,7 +4454,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||||
}
|
}
|
||||||
buffer.writeUTF16(0);
|
buffer.writeUTF16(0);
|
||||||
e.setData(buffer.extractData(), newlen, 2);
|
e.setData(buffer.extractData(), newlen, 2);
|
||||||
if (sc && sc.inCfile)
|
if (!e.cMacro && sc && sc.inCfile)
|
||||||
e.type = Type.tuns16.sarrayOf(e.len + 1);
|
e.type = Type.tuns16.sarrayOf(e.len + 1);
|
||||||
else
|
else
|
||||||
e.type = Type.twchar.immutableOf().arrayOf();
|
e.type = Type.twchar.immutableOf().arrayOf();
|
||||||
|
@ -4466,7 +4466,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
|
||||||
goto default;
|
goto default;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (sc && sc.inCfile)
|
if (!e.cMacro && sc && sc.inCfile)
|
||||||
e.type = Type.tchar.sarrayOf(e.len + 1);
|
e.type = Type.tchar.sarrayOf(e.len + 1);
|
||||||
else
|
else
|
||||||
e.type = Type.tchar.immutableOf().arrayOf();
|
e.type = Type.tchar.immutableOf().arrayOf();
|
||||||
|
|
|
@ -3608,6 +3608,7 @@ public:
|
||||||
uint8_t sz;
|
uint8_t sz;
|
||||||
bool committed;
|
bool committed;
|
||||||
bool hexString;
|
bool hexString;
|
||||||
|
bool cMacro;
|
||||||
enum : char { NoPostfix = 0u };
|
enum : char { NoPostfix = 0u };
|
||||||
|
|
||||||
static StringExp* create(Loc loc, const char* s);
|
static StringExp* create(Loc loc, const char* s);
|
||||||
|
@ -5548,7 +5549,7 @@ private:
|
||||||
char realexp[48LLU];
|
char realexp[48LLU];
|
||||||
char complexexp[64LLU];
|
char complexexp[64LLU];
|
||||||
char symoffexp[56LLU];
|
char symoffexp[56LLU];
|
||||||
char stringexp[43LLU];
|
char stringexp[44LLU];
|
||||||
char arrayliteralexp[40LLU];
|
char arrayliteralexp[40LLU];
|
||||||
char assocarrayliteralexp[48LLU];
|
char assocarrayliteralexp[48LLU];
|
||||||
char structliteralexp[64LLU];
|
char structliteralexp[64LLU];
|
||||||
|
|
2
compiler/test/compilable/imports/imp20344.c
Normal file
2
compiler/test/compilable/imports/imp20344.c
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
// https://github.com/dlang/dmd/issues/20334
|
||||||
|
#define X "X"
|
14
compiler/test/compilable/test20344.d
Normal file
14
compiler/test/compilable/test20344.d
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
// https://github.com/dlang/dmd/issues/20334
|
||||||
|
// EXTRA_FILES: imports/imp20344.c
|
||||||
|
import imports.imp20344;
|
||||||
|
string s = X;
|
||||||
|
const(char)* p = X;
|
||||||
|
|
||||||
|
void takes_string(string){ }
|
||||||
|
void takes_char_star(const(char)*){ }
|
||||||
|
|
||||||
|
|
||||||
|
void test20344(){
|
||||||
|
takes_string(X);
|
||||||
|
takes_char_star(X);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue