Skip to content

Commit

Permalink
move checkPrintfScanfSignature to funcsem.d make private (#16951)
Browse files Browse the repository at this point in the history
  • Loading branch information
thewilsonator authored Oct 6, 2024
1 parent c28e356 commit 08ffd15
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 61 deletions.
61 changes: 0 additions & 61 deletions compiler/src/dmd/dsymbolsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -5928,67 +5928,6 @@ private void writeMixin(const(char)[] s, ref const Loc loc, ref int lines, ref O
++lines;
}

/**
* Check signature of `pragma(printf)` function, print error if invalid.
*
* printf/scanf-like functions must be of the form:
* extern (C/C++) T printf([parameters...], const(char)* format, ...);
* or:
* extern (C/C++) T vprintf([parameters...], const(char)* format, va_list);
*
* Params:
* funcdecl = function to check
* f = function type
* sc = scope
*/
void checkPrintfScanfSignature(FuncDeclaration funcdecl, TypeFunction f, Scope* sc)
{
static bool isPointerToChar(Parameter p)
{
if (auto tptr = p.type.isTypePointer())
{
return tptr.next.ty == Tchar;
}
return false;
}

bool isVa_list(Parameter p)
{
return p.type.equals(target.va_listType(funcdecl.loc, sc));
}

const nparams = f.parameterList.length;
const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars();
if (!(f.linkage == LINK.c || f.linkage == LINK.cpp))
{
.error(funcdecl.loc, "`pragma(%s)` function `%s` must have `extern(C)` or `extern(C++)` linkage,"
~" not `extern(%s)`",
p, funcdecl.toChars(), f.linkage.linkageToChars());
}
if (f.parameterList.varargs == VarArg.variadic)
{
if (!(nparams >= 1 && isPointerToChar(f.parameterList[nparams - 1])))
{
.error(funcdecl.loc, "`pragma(%s)` function `%s` must have"
~ " signature `%s %s([parameters...], const(char)*, ...)` not `%s`",
p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars());
}
}
else if (f.parameterList.varargs == VarArg.none)
{
if(!(nparams >= 2 && isPointerToChar(f.parameterList[nparams - 2]) &&
isVa_list(f.parameterList[nparams - 1])))
.error(funcdecl.loc, "`pragma(%s)` function `%s` must have"~
" signature `%s %s([parameters...], const(char)*, va_list)`",
p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars());
}
else
{
.error(funcdecl.loc, "`pragma(%s)` function `%s` must have C-style variadic `...` or `va_list` parameter",
p, funcdecl.toChars());
}
}

/*********************************************
* Search for ident as member of d.
* Params:
Expand Down
61 changes: 61 additions & 0 deletions compiler/src/dmd/funcsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -3339,3 +3339,64 @@ extern (D) bool isTypeIsolated(FuncDeclaration fd, Type t, ref StringTable!Type
return true;
}
}

/**
* Check signature of `pragma(printf)` function, print error if invalid.
*
* printf/scanf-like functions must be of the form:
* extern (C/C++) T printf([parameters...], const(char)* format, ...);
* or:
* extern (C/C++) T vprintf([parameters...], const(char)* format, va_list);
*
* Params:
* funcdecl = function to check
* f = function type
* sc = scope
*/
private void checkPrintfScanfSignature(FuncDeclaration funcdecl, TypeFunction f, Scope* sc)
{
static bool isPointerToChar(Parameter p)
{
if (auto tptr = p.type.isTypePointer())
{
return tptr.next.ty == Tchar;
}
return false;
}

bool isVa_list(Parameter p)
{
return p.type.equals(target.va_listType(funcdecl.loc, sc));
}

const nparams = f.parameterList.length;
const p = (funcdecl.printf ? Id.printf : Id.scanf).toChars();
if (!(f.linkage == LINK.c || f.linkage == LINK.cpp))
{
.error(funcdecl.loc, "`pragma(%s)` function `%s` must have `extern(C)` or `extern(C++)` linkage,"
~" not `extern(%s)`",
p, funcdecl.toChars(), f.linkage.linkageToChars());
}
if (f.parameterList.varargs == VarArg.variadic)
{
if (!(nparams >= 1 && isPointerToChar(f.parameterList[nparams - 1])))
{
.error(funcdecl.loc, "`pragma(%s)` function `%s` must have"
~ " signature `%s %s([parameters...], const(char)*, ...)` not `%s`",
p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars(), funcdecl.type.toChars());
}
}
else if (f.parameterList.varargs == VarArg.none)
{
if(!(nparams >= 2 && isPointerToChar(f.parameterList[nparams - 2]) &&
isVa_list(f.parameterList[nparams - 1])))
.error(funcdecl.loc, "`pragma(%s)` function `%s` must have"~
" signature `%s %s([parameters...], const(char)*, va_list)`",
p, funcdecl.toChars(), f.next.toChars(), funcdecl.toChars());
}
else
{
.error(funcdecl.loc, "`pragma(%s)` function `%s` must have C-style variadic `...` or `va_list` parameter",
p, funcdecl.toChars());
}
}

0 comments on commit 08ffd15

Please sign in to comment.