diff --git a/compiler/src/dmd/cparse.d b/compiler/src/dmd/cparse.d index fd5074f5bf..cb066e1997 100644 --- a/compiler/src/dmd/cparse.d +++ b/compiler/src/dmd/cparse.d @@ -6057,6 +6057,8 @@ final class CParser(AST) : Parser!AST //printf("addSym() %s\n", s.toChars()); if (auto v = s.isVarDeclaration()) v.isCmacro(true); // mark it as coming from a C #define + if (auto td = s.isTemplateDeclaration()) + td.isCmacro = true; // mark as coming from a C #define /* If it's already defined, replace the earlier * definition */ diff --git a/compiler/src/dmd/dtemplate.d b/compiler/src/dmd/dtemplate.d index af225cca4f..fe398d6696 100644 --- a/compiler/src/dmd/dtemplate.d +++ b/compiler/src/dmd/dtemplate.d @@ -593,6 +593,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol bool isTrivialAliasSeq; /// matches pattern `template AliasSeq(T...) { alias AliasSeq = T; }` bool isTrivialAlias; /// matches pattern `template Alias(T) { alias Alias = qualifiers(T); }` bool deprecated_; /// this template declaration is deprecated + bool isCmacro; /// Whether this template is a translation of a C macro Visibility visibility; // threaded list of previous instantiation attempts on stack diff --git a/compiler/src/dmd/frontend.h b/compiler/src/dmd/frontend.h index caff0d3310..af5c773999 100644 --- a/compiler/src/dmd/frontend.h +++ b/compiler/src/dmd/frontend.h @@ -1749,6 +1749,7 @@ public: bool isTrivialAliasSeq; bool isTrivialAlias; bool deprecated_; + bool isCmacro; Visibility visibility; TemplatePrevious* previous; Expression* lastConstraint; diff --git a/compiler/src/dmd/importc.d b/compiler/src/dmd/importc.d index d3381dc858..059de62b1f 100644 --- a/compiler/src/dmd/importc.d +++ b/compiler/src/dmd/importc.d @@ -544,6 +544,12 @@ Dsymbol handleSymbolRedeclarations(ref Scope sc, Dsymbol s, Dsymbol s2, ScopeDsy } } + // Don't let macros shadow real symbols + if (auto td = s.isTemplateDeclaration()) + { + if (td.isCmacro) return s2; + } + auto vd = s.isVarDeclaration(); // new declaration auto vd2 = s2.isVarDeclaration(); // existing declaration diff --git a/compiler/src/dmd/template.h b/compiler/src/dmd/template.h index da754e8a7d..bfc4151480 100644 --- a/compiler/src/dmd/template.h +++ b/compiler/src/dmd/template.h @@ -71,6 +71,7 @@ public: d_bool isTrivialAliasSeq; // matches `template AliasSeq(T...) { alias AliasSeq = T; } d_bool isTrivialAlias; // matches pattern `template Alias(T) { alias Alias = qualifiers(T); }` d_bool deprecated_; // this template declaration is deprecated + d_bool isCmacro; // Whether this template is a translation of a C macro Visibility visibility; TemplatePrevious *previous; // threaded list of previous instantiation attempts on stack diff --git a/compiler/test/compilable/test20502.c b/compiler/test/compilable/test20502.c new file mode 100644 index 0000000000..c3a44fb4cc --- /dev/null +++ b/compiler/test/compilable/test20502.c @@ -0,0 +1,10 @@ +// https://github.com/dlang/dmd/issues/20502 +struct mg_str { + +}; + +void mg_str_s() { + +} + +#define mg_str(s) mg_str_s(s)