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:
drpriver 2025-04-10 14:08:10 -07:00 committed by GitHub
parent 81cd0b26ef
commit e9984553e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 31 additions and 7 deletions

View file

@ -4954,6 +4954,8 @@ struct ASTBase
/// If the string is parsed from a hex string literal
bool hexString = false;
/// If the string is from a collected C macro
bool cMacro = false;
extern (D) this(Loc loc, const(void)[] string)
{
@ -4963,13 +4965,14 @@ struct ASTBase
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));
this.string = cast(char*)string;
this.len = len;
this.postfix = postfix;
this.sz = 1; // work around LDC bug #1286
this.cMacro = cMacro;
}
/**********************************************

View file

@ -6193,7 +6193,7 @@ final class CParser(AST) : Parser!AST
/* Declare manifest constant:
* 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);
addSym(v);
++p;

View file

@ -1406,6 +1406,8 @@ extern (C++) final class StringExp : Expression
/// If the string is parsed from a hex string literal
bool hexString = false;
/// If the string is from a collected C macro
bool cMacro = false;
enum char NoPostfix = 0;
@ -1417,13 +1419,14 @@ extern (C++) final class StringExp : Expression
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_);
this.string = cast(char*)string.ptr; // note that this.string should be const
this.len = len;
this.sz = sz;
this.postfix = postfix;
this.cMacro = cMacro;
}
static StringExp create(Loc loc, const(char)* s)

View file

@ -353,6 +353,7 @@ public:
unsigned char sz; // 1: char, 2: wchar, 4: dchar
d_bool committed; // if type is committed
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 void *s, d_size_t len);

View file

@ -4429,7 +4429,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
buffer.write4(0);
e.setData(buffer.extractData(), newlen, 4);
if (sc && sc.inCfile)
if (!e.cMacro && sc && sc.inCfile)
e.type = Type.tuns32.sarrayOf(e.len + 1);
else
e.type = Type.tdchar.immutableOf().arrayOf();
@ -4454,7 +4454,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
buffer.writeUTF16(0);
e.setData(buffer.extractData(), newlen, 2);
if (sc && sc.inCfile)
if (!e.cMacro && sc && sc.inCfile)
e.type = Type.tuns16.sarrayOf(e.len + 1);
else
e.type = Type.twchar.immutableOf().arrayOf();
@ -4466,7 +4466,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
goto default;
default:
if (sc && sc.inCfile)
if (!e.cMacro && sc && sc.inCfile)
e.type = Type.tchar.sarrayOf(e.len + 1);
else
e.type = Type.tchar.immutableOf().arrayOf();

View file

@ -3608,6 +3608,7 @@ public:
uint8_t sz;
bool committed;
bool hexString;
bool cMacro;
enum : char { NoPostfix = 0u };
static StringExp* create(Loc loc, const char* s);
@ -5548,7 +5549,7 @@ private:
char realexp[48LLU];
char complexexp[64LLU];
char symoffexp[56LLU];
char stringexp[43LLU];
char stringexp[44LLU];
char arrayliteralexp[40LLU];
char assocarrayliteralexp[48LLU];
char structliteralexp[64LLU];

View file

@ -0,0 +1,2 @@
// https://github.com/dlang/dmd/issues/20334
#define X "X"

View 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);
}