Bug 418533 - order of significantMacros and internallyModified is lost during propagation
Summary: order of significantMacros and internallyModified is lost during propagation
Status: NEW
Alias: None
Product: CDT
Classification: Tools
Component: cdt-indexer (show other bugs)
Version: Next   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Jonah Graham CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-02 12:34 EDT by Andrew Eidsness CLA
Modified: 2020-09-04 15:19 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrew Eidsness CLA 2013-10-02 12:34:13 EDT
There are two features of the CDT scanner which interact to cause this problem.  The definitions of the features are:

1) Significant macro:  Macros that modify the code that is visible within that file.  E.g., in header.h:

      #ifdef MACRO
      extern void func();
      #endif

   In this code, MACRO is significant because it controls whether the func declaration is visible.

2) Internal modifications: The scanner also records the macros that are modified within a file.  E.g.,

   #define MACRO

   In this code MACRO is internallyModified.  The possible modifications are to define the macro (in this example), to undefine it (#undef MACRO), or to change its value (#define MACRO value).

The simplest use is during resolution of #include directives, e.g., in a.h:

   #include "header.h"

During processing of header.h, MACRO will be marked as signifcant.  This state will then be propagated to the parent context so that MACRO will also be significant in a.h.  If other files include a.h, they will also get MACRO as significant when the context is propagated up to that file.

In a slightly more complex case, consider b.h:

   #define MACRO
   #include "header.h"

In this case MACRO will be marked as internally modified, and then header.h will be processed.  That will mark MACRO as significant (as before).  However, there will be a change when this is propagated to b.h.  Since MACRO is already marked as internally modified, it is no longer considered significant.

The state of MACRO when b.h is include is no longer important, b.h will change that value before header.h is included.

Now consider the include guard pattern in c.h:

   #ifndef C_H
   #define C_H

In this case the #ifndef will mark C_H as significant.  The #define will then mark it as internally modified.

At this point an error will be introduced when this state is propagated to the file that includes c.h.  That context should consider C_H to be significant because changes in that value will decide what code is visible to files that include this code.  However, the macro is in the list of internally modified macros, to the state is not propagated.

For a while I thought the problem was a side effect of marking the value as having an include guard (which activates some better performing code in the scanner).  However, the traces that I now have (as described above) show that it is just this interaction.

The problem seems to be that only some sequencing information is maintained when these two features interact.  During propagation internal modifications always take precedence over significant macros.  However, for that to work properly I think that the code for marking a macro as internally modified should first check if it has already been marked as significant.

If the macro is significant before it is modified, then it should still be significant when the file is included.

I'll attach a test project shortly.