Hi,

This patch adds checks for semanticRun in the Declaration visitor
passes.  While it shouldn't happen during normal traversal of the AST
provided from the front-end, there are some cases where declarations
need to be visited out of order, such as what is being done in PR
d/89017, it then becomes necessary to guard against this.

Regression tested on x86_64-linux-gnu.

Committed to trunk as r270478.

-- 
Iain
---
gcc/d/ChangeLog:

2019-04-21  Iain Buclaw  <ibuc...@gdcproject.org>

        * decl.cc (DeclVisitor::visit(Import)): Set semanticRun after
        completion, guard against being called more than once.
        (DeclVisitor::visit(StructDeclaration)): Likewise.
        (DeclVisitor::visit(ClassDeclaration)): Likewise.
        (DeclVisitor::visit(InterfaceDeclaration)): Likewise.
        (DeclVisitor::visit(VarDeclaration)): Likewise.
        (DeclVisitor::visit(TypeInfoDeclaration)): Likewise.

---
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index fffed97727f..84c17ab36f7 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -147,6 +147,9 @@ public:
 
   void visit (Import *d)
   {
+    if (d->semanticRun >= PASSobj)
+      return;
+
     /* Implements import declarations by telling the debug back-end we are
        importing the NAMESPACE_DECL of the module or IMPORTED_DECL of the
        declaration into the current lexical scope CONTEXT.  NAME is set if
@@ -188,6 +191,8 @@ public:
 	debug_hooks->imported_module_or_decl (decl, name, context,
 					      false, false);
       }
+
+    d->semanticRun = PASSobj;
   }
 
   /* Expand any local variables found in tuples.  */
@@ -325,6 +330,9 @@ public:
 
   void visit (StructDeclaration *d)
   {
+    if (d->semanticRun >= PASSobj)
+      return;
+
     if (d->type->ty == Terror)
       {
 	error_at (make_location_t (d->loc),
@@ -376,6 +384,8 @@ public:
 
     if (d->xhash)
       d->xhash->accept (this);
+
+    d->semanticRun = PASSobj;
   }
 
   /* Finish semantic analysis of functions in vtbl for class CD.  */
@@ -453,6 +463,9 @@ public:
 
   void visit (ClassDeclaration *d)
   {
+    if (d->semanticRun >= PASSobj)
+      return;
+
     if (d->type->ty == Terror)
       {
 	error_at (make_location_t (d->loc),
@@ -518,6 +531,8 @@ public:
     tree ctype = TREE_TYPE (build_ctype (d->type));
     if (TYPE_NAME (ctype))
       d_pushdecl (TYPE_NAME (ctype));
+
+    d->semanticRun = PASSobj;
   }
 
   /* Write out compiler generated TypeInfo and vtables for the given interface
@@ -525,6 +540,9 @@ public:
 
   void visit (InterfaceDeclaration *d)
   {
+    if (d->semanticRun >= PASSobj)
+      return;
+
     if (d->type->ty == Terror)
       {
 	error_at (make_location_t (d->loc),
@@ -557,6 +575,8 @@ public:
     tree ctype = TREE_TYPE (build_ctype (d->type));
     if (TYPE_NAME (ctype))
       d_pushdecl (TYPE_NAME (ctype));
+
+    d->semanticRun = PASSobj;
   }
 
   /* Write out compiler generated TypeInfo and initializer for the given
@@ -606,6 +626,9 @@ public:
 
   void visit (VarDeclaration *d)
   {
+    if (d->semanticRun >= PASSobj)
+      return;
+
     if (d->type->ty == Terror)
       {
 	error_at (make_location_t (d->loc),
@@ -731,6 +754,8 @@ public:
 	      }
 	  }
       }
+
+    d->semanticRun = PASSobj;
   }
 
   /* Generate and compile a static TypeInfo declaration, but only if it is
@@ -738,12 +763,16 @@ public:
 
   void visit (TypeInfoDeclaration *d)
   {
+    if (d->semanticRun >= PASSobj)
+      return;
+
     if (speculative_type_p (d->tinfo))
       return;
 
     tree t = get_typeinfo_decl (d);
     DECL_INITIAL (t) = layout_typeinfo (d);
     d_finish_decl (t);
+    d->semanticRun = PASSobj;
   }
 
   /* Finish up a function declaration and compile it all the way

Reply via email to