[cfe-dev] [ASTImporter][CrossTU] inconsistent enumerators

Rafael·Stahl via cfe-dev cfe-dev at lists.llvm.org
Fri Nov 17 06:33:45 PST 2017


Hello Gábor,

thank you for the fix! I can confirm that this is working for me.

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.

Should I file a bug to make sure this is not forgotten?

Best regards
Rafael


On 16/11/17 17:42, Gábor Horváth wrote:
> Hi Rafael!
>
> Yeah, the cross TU patch is a great way to detect issues with the 
> ASTImporter and unfortunately, those issues are extremely hard to debug.
>
> 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.
> A dirty quick fix for this particular case:
>
> @@ -1782,6 +1807,11 @@ Decl 
> *ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
>    DeclarationName Name;
>    SourceLocation Loc;
>    NamedDecl *ToD;
> +  auto *ED = cast<EnumDecl>(D->getDeclContext());
> +  if (auto *TND = ED->getTypedefNameForAnonDecl()) {
> +    if (!Importer.Import(TND))
> +      return nullptr;
> +  }
>    if (ImportDeclParts(D, DC, LexicalDC, Name, ToD, Loc))
>      return nullptr;
>    if (ToD)
>
> 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?
>
> Regards,
> Gábor
>
> On 13 November 2017 at 12:16, Rafael·Stahl via cfe-dev 
> <cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>> wrote:
>
>     Deal all
>
>     While using the static analyzer with cross translation unit
>     support ( https://reviews.llvm.org/D30691
>     <https://reviews.llvm.org/D30691> ), I stumbled upon an issue that
>     is most likely related to the ASTImporter.
>
>     I'm using a custom checker, but this should be reproduced by just
>     running the scan-build tool.
>
>     A simple reproducing example:
>
>     main.c:
>
>     ---------------------------------------
>     void foo();
>     void moo();
>
>     int main()
>     {
>         foo();
>         moo();
>     }
>     ---------------------------------------
>
>     foo.c:
>
>     ---------------------------------------
>     #include "thing.h"
>
>     void foo()
>     {
>         (void)THING_VALUE;
>     }
>
>     void conflict(thing_t type)
>     {
>     }
>     ---------------------------------------
>
>     moo.c:
>
>     ---------------------------------------
>     #include "thing.h"
>
>     void moo()
>     {
>         conflict(THING_VALUE);
>     }
>     ---------------------------------------
>
>     thing.h:
>
>     ---------------------------------------
>     typedef enum {
>         THING_VALUE
>     } thing_t;
>
>     void conflict(thing_t type);
>     ---------------------------------------
>
>     Notes on particularities of this example:
>
>     - main.c needs to NOT include the header
>     - main() needs to call the functions in this order
>     - foo() needs to reference the enumerator
>     - the enum needs to be typedef'd
>
>     If any of the above points do not apply, the issue does not appear.
>
>     The issue:
>
>     ---------------------------------------
>     In file included from moo.c:1:
>     thing.h:1:9: warning: type 'thing_t' has incompatible
>           definitions in different translation units [-Wodr]
>     typedef enum {
>             ^
>     thing.h:2:5: note: enumerator 'THING_VALUE' with value 0 here
>         THING_VALUE
>         ^
>     thing.h:1:9: note: no corresponding enumerator here
>     foo.c:8:6: error: external function 'conflict' declared
>           with incompatible types in different translation units
>     ('void (thing_t)' vs. 'void (thing_t)')
>     void conflict(thing_t type)
>          ^
>     thing.h:5:6: note: declared here with type
>           'void (thing_t)'
>     void conflict(thing_t type);
>          ^
>     ---------------------------------------
>
>     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.
>
>     In my real code, not this example, I was unable to dump the
>     imported EnumDecl, because it eventually calls
>     SourceManager::isBeforeInTranslationUnit with two SourceLocations
>     from different files. Not sure if this is related.
>
>     I have tried adding:
>
>     for (const auto Enumerator : D->enumerators())
>         D2->addDecl(Importer.Import(Enumerator));
>
>     before completing the definition in
>     ASTNodeImporter::VisitEnumDecl(), but that results in:
>
>     exe: tools/clang/lib/AST/DeclBase.cpp:1374: void
>     clang::DeclContext::addHiddenDecl(clang::Decl*): Assertion
>     `!D->getNextDeclInContext() && D != LastDecl && "Decl already
>     inserted into a DeclContext"' failed.
>
>     I'm not familiar enough with the ASTImporter to help myself
>     further here. Does anyone know what could be the issue?
>
>     Best regards
>     Rafael Stahl
>
>
>
>     _______________________________________________
>     cfe-dev mailing list
>     cfe-dev at lists.llvm.org <mailto:cfe-dev at lists.llvm.org>
>     http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>     <http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171117/ccc86c74/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5449 bytes
Desc: S/MIME Cryptographic Signature
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171117/ccc86c74/attachment.bin>


More information about the cfe-dev mailing list