ImportC: improve error message for size_t (#21187)

Resolves: https://github.com/dlang/dmd/issues/20414

Add some hints for common missing includes.
This commit is contained in:
drpriver 2025-04-09 16:16:54 -07:00 committed by GitHub
parent ca2f90d1fc
commit 74cdfed9d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 83 additions and 21 deletions

View file

@ -4116,16 +4116,28 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
/* Look for what user might have meant
*/
if (const n = importHint(exp.ident.toString()))
error(exp.loc, "`%s` is not defined, perhaps `import %.*s;` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr);
else if (auto s2 = sc.search_correct(exp.ident))
error(exp.loc, "undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
else if (const p = Scope.search_correct_C(exp.ident))
error(exp.loc, "undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p);
else if (exp.ident == Id.dollar)
error(exp.loc, "undefined identifier `$`");
if (!(sc && sc.inCfile))
{
if (const n = importHint(exp.ident.toString()))
error(exp.loc, "`%s` is not defined, perhaps `import %.*s;` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr);
else if (auto s2 = sc.search_correct(exp.ident))
error(exp.loc, "undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
else if (const p = Scope.search_correct_C(exp.ident))
error(exp.loc, "undefined identifier `%s`, did you mean `%s`?", exp.ident.toChars(), p);
else if (exp.ident == Id.dollar)
error(exp.loc, "undefined identifier `$`");
else
error(exp.loc, "undefined identifier `%s`", exp.ident.toChars());
}
else
error(exp.loc, "undefined identifier `%s`", exp.ident.toChars());
{
if (const n = cIncludeHint(exp.ident.toString()))
error(exp.loc, "`%s` is not defined, perhaps `#include %.*s` is needed?", exp.ident.toChars(), cast(int)n.length, n.ptr);
else if (auto s2 = sc.search_correct(exp.ident))
error(exp.loc, "undefined identifier `%s`, did you mean %s `%s`?", exp.ident.toChars(), s2.kind(), s2.toChars());
else
error(exp.loc, "undefined identifier `%s`", exp.ident.toChars());
}
result = ErrorExp.get();
}

View file

@ -26,8 +26,15 @@ const(char)[] importHint(const(char)[] s) @safe
return *entry;
return null;
}
const(char)[] cIncludeHint(const(char)[] s) @safe
{
if (auto entry = s in cHints)
return *entry;
return null;
}
private immutable string[string] hints;
private immutable string[string] cHints;
shared static this()
{
@ -83,6 +90,23 @@ shared static this()
"InterpolationHeader": "core.interpolation",
"InterpolationFooter": "core.interpolation",
];
cHints = [
"NULL": "<stddef.h>",
"calloc": "<stdlib.h>",
"fopen": "<stdio.h>",
"fprintf": "<stdio.h>",
"free": "<stdlib.h>",
"malloc": "<stdlib.h>",
"memcpy": "<string.h>",
"memmove": "<string.h>",
"memset": "<string.h>",
"printf": "<stdio.h>",
"ptrdiff_t": "<stddef.h>",
"size_t": "<stddef.h>",
"stderr": "<stdio.h>",
"stdin": "<stdio.h>",
"stdout": "<stdio.h>",
];
}
unittest

View file

@ -169,17 +169,28 @@ private void resolveHelper(TypeQualified mt, Loc loc, Scope* sc, Dsymbol s, Dsym
*/
const p = mt.mutableOf().unSharedOf().toChars();
auto id = Identifier.idPool(p[0 .. strlen(p)]);
if (const n = importHint(id.toString()))
error(loc, "`%s` is not defined, perhaps `import %.*s;` ?", p, cast(int)n.length, n.ptr);
else if (auto s2 = sc.search_correct(id))
error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2.kind(), s2.toChars());
else if (const q = Scope.search_correct_C(id))
error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
else if ((id == Id.This && sc.getStructClassScope()) ||
(id == Id._super && sc.getClassScope()))
error(loc, "undefined identifier `%s`, did you mean `typeof(%s)`?", p, p);
else
error(loc, "undefined identifier `%s`", p);
if (!(sc && sc.inCfile))
{
if (const n = importHint(id.toString()))
error(loc, "`%s` is not defined, perhaps `import %.*s;` ?", p, cast(int)n.length, n.ptr);
else if (auto s2 = sc.search_correct(id))
error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2.kind(), s2.toChars());
else if (const q = Scope.search_correct_C(id))
error(loc, "undefined identifier `%s`, did you mean `%s`?", p, q);
else if ((id == Id.This && sc.getStructClassScope()) ||
(id == Id._super && sc.getClassScope()))
error(loc, "undefined identifier `%s`, did you mean `typeof(%s)`?", p, p);
else
error(loc, "undefined identifier `%s`", p);
}
else {
if (const n = cIncludeHint(id.toString()))
error(loc, "`%s` is not defined, perhaps `#include %.*s` ?", p, cast(int)n.length, n.ptr);
else if (auto s2 = sc.search_correct(id))
error(loc, "undefined identifier `%s`, did you mean %s `%s`?", p, s2.kind(), s2.toChars());
else
error(loc, "undefined identifier `%s`", p);
}
pt = Type.terror;
return;

View file

@ -0,0 +1,15 @@
/* TEST_OUTPUT:
---
fail_compilation/test20414.c(1): Error: `size_t` is not defined, perhaps `#include <stddef.h>` ?
fail_compilation/test20414.c(2): Error: `ptrdiff_t` is not defined, perhaps `#include <stddef.h>` ?
fail_compilation/test20414.c(3): Error: `NULL` is not defined, perhaps `#include <stddef.h>` is needed?
fail_compilation/test20414.c(5): Error: undefined identifier `fooo`, did you mean function `foo`?
---
*/
#line 1
size_t x;
ptrdiff_t pd;
void *p = NULL;
void foo(void);
void (*fp)(void) = &fooo;

View file

@ -1,6 +1,6 @@
/* TEST_OUTPUT:
---
fail_compilation/test23003.c(101): Error: undefined identifier `size_t`
fail_compilation/test23003.c(101): Error: `size_t` is not defined, perhaps `#include <stddef.h>` ?
fail_compilation/test23003.c(102): Error: undefined identifier `object`
---
*/