[cfe-dev] [ASTImporter] Import order problems
Aleksei Sidorin via cfe-dev
cfe-dev at lists.llvm.org
Thu Sep 7 07:31:59 PDT 2017
Hello Gabor.
I'm aware of this issue. As a workaround, I reorder the fields of
imported structure after it is imported. There is no need to reorder
Decls inside other DeclContexts (at least, for analyzer; but this would
make sense if ASTImporter is used together with Parser).
Thank you also for this awesome repro. When I'll be at least a bit more
free, I'll put the patch on review.
07.09.2017 17:25, Gábor Horváth пишет:
> Hi!
>
> I stumbled upon a serious issue within the AST Importer. First I will
> walk you through a very synthetic example, then I will try to explain
> what is happening and finally, I will ask for help if you have a
> proper solution in mind.
>
> *The description of the problem*
>
> *1. *Let's have a simple struct (please ignore the UB in the struct)
> in a.cpp:
> struct A {
> int b = a + 2;
> int a = 5;
> };
>
> *2.* Let's also have an empty b.cpp.
> *3.* Let's dump the AST of a.cpp:
> clang -cc1 -emit-pch -o 1.ast a.cpp -std=c++11
> *4.* Let's merge the dumped AST with the empty file and print the AST:
> clang -cc1 -ast-merge 1.ast -ast-print b.cpp -std=c++11
>
> The output is:
> struct A {
> int a = 5;
> int b = this->a + 2;
> };
>
> Note that the order of the fields is changed. This is a serious
> problem since the imported type will not be equivalent to the original
> one and this can cause various problems during importing non-trivial
> AST. The same issue can be triggered without having UB in the code,
> but I wanted to keep the example as small as possible.
>
> This importing strategy also has further implications. Such as
> sometimes the ASTImporter ends up checking for equivalence of half
> done and full definitions. (And they are, of course, not equivalent.)
>
> *Possible explanation of the problem*
>
> During importing a DeclContext we will add each of the declarations to
> it. The order of the declarations will be the order in which we add
> the declarations. In case a declaration is also a definition, we might
> end up importing the definitions as well before finishing the import
> of the actual declaration. If a definition refers to a declaration
> that was not imported yet, we will start importing that declaration.
>
> In the example above the importer starts with importing A::b. During
> importing A::b it will encounter a DeclRefExpr to A::a, which is not
> imported yet. The importer will continue with importing A::a. After
> the import of A::a is finished, it will be added to the DeclContext
> before the import of A::b is finished, thus A::a end up before A::b in
> the imported class.
>
> *Possible solutions to the problem*
>
> One solution would be to emulate what the parser does, i.e.: first
> importing only the declarations and after all the declarations are
> imported continue with the definitions. Unfortunately, I do not see an
> easy way to implement this logic with the current structure of the
> ASTImporter, but hopefully, it is only because I am not very familiar
> with that part of clang.
>
> To circumvent this issue I ended up reordering the declarations within
> the DeclContext after finishing the import of the definition based on
> the original DeclContext. This feels like a hacky solution for this
> problem and also do not solve further implications described above.
>
> *Asking for help*
>
> What do you think? Did you observe similar anomalies? Do you have any
> comments or a solution in mind?
>
> Thanks in advance,
> Gábor Horváth
--
Best regards,
Aleksei Sidorin,
SRR, Samsung Electronics
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20170907/24dee4de/attachment.html>
More information about the cfe-dev
mailing list