fix Issue 22960 - importC: K&R-style functions assume variadic calling convention (#15107)

This commit is contained in:
Walter Bright 2023-04-19 00:51:31 -07:00 committed by GitHub
parent a4220358ec
commit 3981bdcd15
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 28 additions and 9 deletions

View file

@ -3951,7 +3951,7 @@ struct ASTBase
extern (D) this(ParameterList pl, Type treturn, LINK linkage, StorageClass stc = 0)
{
super(Tfunction, treturn);
assert(VarArg.none <= pl.varargs && pl.varargs <= VarArg.typesafe);
assert(VarArg.none <= pl.varargs && pl.varargs <= VarArg.max);
this.parameterList = pl;
this.linkage = linkage;

View file

@ -327,6 +327,7 @@ enum VarArg : ubyte
variadic = 1, /// (T t, ...) can be C-style (core.stdc.stdarg) or D-style (core.vararg)
typesafe = 2, /// (T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions
/// or https://dlang.org/spec/function.html#typesafe_variadic_functions
KRvariadic = 3, /// K+R C style variadics (no function prototype)
}
/*************************

View file

@ -2081,8 +2081,7 @@ final class CParser(AST) : Parser!AST
auto pl = ft.parameterList;
if (pl.varargs != AST.VarArg.none && pl.length)
error("function identifier-list cannot end with `...`");
ft.parameterList.varargs = AST.VarArg.variadic; // but C11 allows extra arguments
importBuiltins = true; // will need __va_list_tag
ft.parameterList.varargs = AST.VarArg.KRvariadic; // but C11 allows extra arguments
auto plLength = pl.length;
if (symbols.length != plLength)
error(token.loc, "%d identifiers does not match %d declarations", cast(int)plLength, cast(int)symbols.length);
@ -3046,8 +3045,7 @@ final class CParser(AST) : Parser!AST
if (token.value == TOK.rightParenthesis) // func()
{
nextToken();
importBuiltins = true; // will need __va_list_tag
return AST.ParameterList(parameters, AST.VarArg.variadic, varargsStc);
return AST.ParameterList(parameters, AST.VarArg.KRvariadic, varargsStc);
}
/* Create function prototype scope

View file

@ -2265,7 +2265,8 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
default:
break;
}
if (tf.parameterList.varargs == VarArg.variadic)
if (tf.parameterList.varargs == VarArg.variadic ||
tf.parameterList.varargs == VarArg.KRvariadic)
{
const(char)* p = tf.linkage == LINK.c ? "extern(C)" : "extern(C++)";
if (arg.type.ty == Tarray)

View file

@ -2405,6 +2405,7 @@ enum class VarArg : uint8_t
none = 0u,
variadic = 1u,
typesafe = 2u,
KRvariadic = 3u,
};
struct ParameterList final
@ -8873,7 +8874,9 @@ struct Id final
static Identifier* naked;
static Identifier* thread;
static Identifier* vector_size;
static Identifier* noinline;
static Identifier* noreturn;
static Identifier* _deprecated;
static Identifier* _align;
static Identifier* aligned;
static Identifier* builtins;

View file

@ -1520,7 +1520,8 @@ tym_t totym(Type tx)
case LINK.windows:
if (target.is64bit)
goto case LINK.c;
t = (tf.parameterList.varargs == VarArg.variadic) ? TYnfunc : TYnsfunc;
t = (tf.parameterList.varargs == VarArg.variadic ||
tf.parameterList.varargs == VarArg.KRvariadic) ? TYnfunc : TYnsfunc;
break;
case LINK.c:

View file

@ -3229,6 +3229,7 @@ private void parametersToBuffer(ParameterList pl, OutBuffer* buf, HdrGenState* h
final switch (pl.varargs)
{
case VarArg.none:
case VarArg.KRvariadic:
break;
case VarArg.variadic:

View file

@ -1722,7 +1722,8 @@ private bool canInline(FuncDeclaration fd, bool hasthis, bool hdrscan, bool stat
TypeFunction tf = fd.type.isTypeFunction();
// no variadic parameter lists
if (tf.parameterList.varargs == VarArg.variadic)
if (tf.parameterList.varargs == VarArg.variadic ||
tf.parameterList.varargs == VarArg.KRvariadic)
goto Lno;
/* No lazy parameters when inlining by statement, as the inliner tries to

View file

@ -4267,7 +4267,7 @@ extern (C++) final class TypeFunction : TypeNext
super(Tfunction, treturn);
//if (!treturn) *(char*)0=0;
// assert(treturn);
assert(VarArg.none <= pl.varargs && pl.varargs <= VarArg.typesafe);
assert(VarArg.none <= pl.varargs && pl.varargs <= VarArg.max);
this.parameterList = pl;
this.linkage = linkage;

View file

@ -1316,6 +1316,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
* "argptr" extern(D) void dstyle(...), use `__argptr` and `__arguments`
* "stdarg" extern(C) void cstyle(int, ...), use core.stdc.stdarg
* "typesafe" void typesafe(T[] ...)
* "KR" old K+R style
*/
// get symbol linkage as a string
if (dim != 1)
@ -1350,6 +1351,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
case VarArg.variadic: style = (link == LINK.d)
? "argptr"
: "stdarg"; break;
case VarArg.KRvariadic: style = "KR"; break;
case VarArg.typesafe: style = "typesafe"; break;
}
auto se = new StringExp(e.loc, style);

View file

@ -0,0 +1,11 @@
int abc() { return 1; }
int def(const char *p, ...) { return 2; }
int ghi(const char *p, int i) { return 3; }
int main()
{
abc("hello world %d\n", 1);
def("hello world %d\n", 2);
ghi("hello world %d\n", 3);
return 0;
}