[cfe-dev] Out of date IdentifierInfo instances associated with macro expansions loaded from AST files
Tom Honermann
thonermann at coverity.com
Thu Sep 19 07:34:52 PDT 2013
Could someone please review/comment/commit this patch?
Tom.
On 08/30/2013 03:32 PM, Tom Honermann wrote:
> Attached is a patch against Clang trunk to correct IdentifierInfo
> associations for macro definitions and expansions read from AST files
> when the name of the macro matches the name of another identifier (such
> as a keyword).
>
> I'm not particularly confident that the patch represents the best way to
> correct this issue, so further review and comments would be appreciated.
> No regressions occurred when running the Clang test suite with this
> change in place.
>
> For testing, I've been using this code that defines a macro with the
> same name as a keyword.
>
> $ cat t.c
> #define register
> void f(void) {
> register int i;
> }
>
> The code is then compiled and emitted to a .ast file with a detailed
> preprocessing record. An in-house utility is then used to read it.
>
> $ clang -emit-ast -Xclang -detailed-preprocessing-record t.c
>
> The problem occurs when attempting to retrieve macro information
> associated with macro expansions within a source range. I don't have a
> standalone test case I can share, but the relevant code looks similar to
> this:
>
> void f(Preprocessor &preprocessor, const SourceRange &range) {
> PreprocessingRecord *preprocessing_record
> = preprocessor.getPreprocessingRecord();
>
> std::pair<
> PreprocessingRecord::iterator,
> PreprocessingRecord::iterator> preproc_range
> = preprocessing_record->getPreprocessedEntitiesInRange(range));
>
> PreprocessingRecord::iterator preproc_current = preproc_range.first;
> PreprocessingRecord::iterator preproc_end = preproc_range.second;
> for (; preproc_current != preproc_end; ++preproc_current) {
> MacroExpansion* macro_expansion
> = dyn_cast<MacroExpansion>(*preproc_current));
> if (!macro_expansion)
> continue;
>
> const IdentifierInfo *macro_id = macro_expansion->getName();
> const MacroInfo *macro_info = preprocessor.getMacroInfo(
> const_cast<IdentifierInfo*>(macro_id));
> if (!macro_info && macro_id->hadMacroDefinition()) {
> // The identifier does not correspond to a currently
> // (at end of TU) defined macro. Get the most recently
> // #undef'd definition.
> macro_info = preprocessor.getMacroInfoHistory(
> const_cast<IdentifierInfo*>(macro_id));
> }
> assert(macro_info &&
> "Encountered a macro expansion with no definition history");
> }
> }
>
> The assert at the end fails for the test case above. The reason is that
> the IdentifierInfo instance retrieved from the MacroExpansion instance
> is an out of date instance (macro_id->OutOfDate == true) corresponding
> to the "register" keyword and neither hasMacroDefinition() nor
> hadMacroDefinition() return true for it (Preprocessor::getMacroInfo()
> return NULL because macro_id->hasMacroDefinition() returns false).
>
> The patch corrects this by changing ASTReader::DecodeIdentifierInfo() to
> check if calls to IdentifierTable::get() return an out of date
> IdentifierInfo instance and, if so, to explicitly retrieve an
> IdentifierInfo instance from the external identifier lookup instance
> associated with the PP.getIdentifierTable() IdentifierTable instance.
> This causes MacroExpansion (and MacroDefinition) instances to be
> deserialized with the correctly preserved IdentifierInfo associations.
>
> I had also tried updating IdentifierTable::get() to check if it is about
> to return an out of date IdentifierInfo instance and, if so, to check
> for an external instance and preferentially return that. This change
> also resolved the problem for me, but triggered a single regression in
> the Clang test suite (test/PCH/pch__VA_ARGS__.c). I did not research
> further why that test case failed and moved on to a more localized
> solution.
>
> Tom.
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: clang-module-identifier-out-of-date.patch
Type: text/x-patch
Size: 1027 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20130919/36a38171/attachment.bin>
More information about the cfe-dev
mailing list