<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p>Hello Gábor,</p>
<p>thank you for the fix! I can confirm that this is working for me.</p>
<p>Unfortunately, I don't think I'd be able to properly fix this,
because it is unclear to me how the code distributes
responsibilities. For example I wouldn't be able to tell that your
fix is a dirty one and where else this should be handled.
Import(Decl*), VisitEnumDecl, VisitEnumConstantDecl, VisitEnumType
or a new VisitTagDecl all kind of touch this topic and
interconnect.<br>
</p>
<p>Should I file a bug to make sure this is not forgotten?</p>
<p>Best regards<br>
Rafael<br>
</p>
<br>
<div class="moz-cite-prefix">On 16/11/17 17:42, Gábor Horváth wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAPRL4a1NBKmCtER8XqCzsNtHJZiFWmBwXsGY9_qAAs8hFZNxyw@mail.gmail.com">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<div dir="ltr">
<div>
<div>
<div>Hi Rafael!<br>
<br>
</div>
Yeah, the cross TU patch is a great way to detect issues
with the ASTImporter and unfortunately, those issues are
extremely hard to debug.<br>
<br>
</div>
Here, it looks like the source of the problem is that, when we
import an EnumConstantDecl, we will import the EnumDecl
without the typdef part.</div>
<div>A dirty quick fix for this particular case:</div>
<div><br>
</div>
<div>@@ -1782,6 +1807,11 @@ Decl
*ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {<br>
DeclarationName Name;<br>
SourceLocation Loc;<br>
NamedDecl *ToD;<br>
+ auto *ED = cast<EnumDecl>(D->getDeclContext());<br>
+ if (auto *TND = ED->getTypedefNameForAnonDecl()) {<br>
+ if (!Importer.Import(TND))<br>
+ return nullptr;<br>
+ }<br>
if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))<br>
return nullptr;<br>
if (ToD)<br>
<br>
</div>
<div>I did not have time yet to deep dive into this and look at
what the proper solution would be. Are you willing to continue
to investigate this?</div>
<div><br>
</div>
<div>Regards,</div>
<div>Gábor<br>
</div>
</div>
<div class="gmail_extra"><br>
<div class="gmail_quote">On 13 November 2017 at 12:16,
Rafael·Stahl via cfe-dev <span dir="ltr"><<a
href="mailto:cfe-dev@lists.llvm.org" target="_blank"
moz-do-not-send="true">cfe-dev@lists.llvm.org</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">Deal all<br>
<br>
While using the static analyzer with cross translation unit
support ( <a href="https://reviews.llvm.org/D30691"
rel="noreferrer" target="_blank" moz-do-not-send="true">https://reviews.llvm.org/D3069<wbr>1</a>
), I stumbled upon an issue that is most likely related to
the ASTImporter.<br>
<br>
I'm using a custom checker, but this should be reproduced by
just running the scan-build tool.<br>
<br>
A simple reproducing example:<br>
<br>
main.c:<br>
<br>
------------------------------<wbr>---------<br>
void foo();<br>
void moo();<br>
<br>
int main()<br>
{<br>
foo();<br>
moo();<br>
}<br>
------------------------------<wbr>---------<br>
<br>
foo.c:<br>
<br>
------------------------------<wbr>---------<br>
#include "thing.h"<br>
<br>
void foo()<br>
{<br>
(void)THING_VALUE;<br>
}<br>
<br>
void conflict(thing_t type)<br>
{<br>
}<br>
------------------------------<wbr>---------<br>
<br>
moo.c:<br>
<br>
------------------------------<wbr>---------<br>
#include "thing.h"<br>
<br>
void moo()<br>
{<br>
conflict(THING_VALUE);<br>
}<br>
------------------------------<wbr>---------<br>
<br>
thing.h:<br>
<br>
------------------------------<wbr>---------<br>
typedef enum {<br>
THING_VALUE<br>
} thing_t;<br>
<br>
void conflict(thing_t type);<br>
------------------------------<wbr>---------<br>
<br>
Notes on particularities of this example:<br>
<br>
- main.c needs to NOT include the header<br>
- main() needs to call the functions in this order<br>
- foo() needs to reference the enumerator<br>
- the enum needs to be typedef'd<br>
<br>
If any of the above points do not apply, the issue does not
appear.<br>
<br>
The issue:<br>
<br>
------------------------------<wbr>---------<br>
In file included from moo.c:1:<br>
thing.h:1:9: warning: type 'thing_t' has incompatible<br>
definitions in different translation units [-Wodr]<br>
typedef enum {<br>
^<br>
thing.h:2:5: note: enumerator 'THING_VALUE' with value 0
here<br>
THING_VALUE<br>
^<br>
thing.h:1:9: note: no corresponding enumerator here<br>
foo.c:8:6: error: external function 'conflict' declared<br>
with incompatible types in different translation units
('void (thing_t)' vs. 'void (thing_t)')<br>
void conflict(thing_t type)<br>
^<br>
thing.h:5:6: note: declared here with type<br>
'void (thing_t)'<br>
void conflict(thing_t type);<br>
^<br>
------------------------------<wbr>---------<br>
<br>
After importing conflict(thing_t) the ASTImporter compared
the imported one with the original by structural
equivalence. This reveals that in the imported enum the
enumerators are missing, causing the above error.<br>
<br>
In my real code, not this example, I was unable to dump the
imported EnumDecl, because it eventually calls
SourceManager::isBeforeInTrans<wbr>lationUnit with two
SourceLocations from different files. Not sure if this is
related.<br>
<br>
I have tried adding:<br>
<br>
for (const auto Enumerator : D->enumerators())<br>
D2->addDecl(Importer.Import(En<wbr>umerator));<br>
<br>
before completing the definition in
ASTNodeImporter::VisitEnumDecl<wbr>(), but that results in:<br>
<br>
exe: tools/clang/lib/AST/DeclBase.c<wbr>pp:1374: void
clang::DeclContext::addHiddenD<wbr>ecl(clang::Decl*):
Assertion `!D->getNextDeclInContext() && D !=
LastDecl && "Decl already inserted into a
DeclContext"' failed.<br>
<br>
I'm not familiar enough with the ASTImporter to help myself
further here. Does anyone know what could be the issue?<br>
<br>
Best regards<span class="HOEnZb"><font color="#888888"><br>
Rafael Stahl<br>
<br>
<br>
</font></span><br>
______________________________<wbr>_________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org"
moz-do-not-send="true">cfe-dev@lists.llvm.org</a><br>
<a
href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev"
rel="noreferrer" target="_blank" moz-do-not-send="true">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/cfe-dev</a><br>
<br>
</blockquote>
</div>
<br>
</div>
</blockquote>
<br>
</body>
</html>