Currently there are several issues with the import of class template
specializations. (1) Different TUs may have class template specializations
with the same template arguments, but with different set of instantiated
MethodDecls and FieldDecls. In this patch we provide a fix to merge these
methods and fields. (2) Currently, we search the partial template
specializations in the set of simple specializations and we add partial
specializations as simple specializations. This is bad, this patch fixes it.
Details
Diff Detail
- Repository
- rC Clang
- Build Status
Buildable 21720 Build 21720: arc lint + arc unit
Event Timeline
Hi Gabor,
While importing methods looks harmless, importing fields can be a breaking change. Do you have any test results on this?
lib/AST/ASTImporter.cpp | ||
---|---|---|
2880 | Honestly speaking, I wonder about this behaviour because it doesn't look similar to instantiation of only methods that are used. Is it a common rule? | |
4560 | Importing additional fields can change the layout of the specialization. For CSA, this usually results in strange assertions hard to debug. Could you please share the results of testing of this change? | |
4561 | The result of import is unchecked here and below. Is it intentional? | |
unittests/AST/ASTImporterTest.cpp | ||
2730 | 3-space indentation. | |
2771 | Broken indent. |
lib/AST/ASTImporter.cpp | ||
---|---|---|
2880 | Yes, this is a common rule. The instantiation of an initializer is similar to the instantiation of default arguments in a sense that both are instantated only if they are being used. To be more precise, quoting from Vandevoorde - C++ Templates The Complete Guide / 14.2.2 Instantiated Components: ... Default function call arguments are considered separately when instantiating | |
4560 | TLDR; We will not create additional fields. By the time when we import the field, we already know that the existing specialization is structurally equivalent with the new one. For the record, I added a new test to make sure that a new FieldDecl will not be created during the merge. | |
4561 | Yes, that is intentional. We plan to refactor all ASTImporter functions to provide a proper error handling mechanism, and in that change we would like to enforce the check of all import functions. |
lib/AST/ASTImporter.cpp | ||
---|---|---|
4561 | Actually, having proper error handling is just one thing, the other more important reason why we don't check the result of the import here, because we don't want to stop merging other fields/functions if one merge failed. If one merge failed, other merge operations still could be successful. |
lib/AST/ASTImporter.cpp | ||
---|---|---|
4560 | This is the new test: ODRViolationOfClassTemplateSpecializationsShouldBeReported. It checks that it is not possible to add new fields to a specialization, rather an ODR violation is diagnosed. |
lib/AST/ASTImporter.cpp | ||
---|---|---|
4560 | Thank you for the explanation. However, I find the comment very misleading. It tells: // Check and merge those fields which have been instantiated // in the "From" context, but not in the "To" context. Would it be correct to change it to "Import field initializers that are still not instantiated", or do I still misunderstand something? |
lib/AST/ASTImporter.cpp | ||
---|---|---|
4560 | Yes, I agree that this comment is not precise and could be misleading, thank you for pointing this out. I changed this comment and others too. |
Honestly speaking, I wonder about this behaviour because it doesn't look similar to instantiation of only methods that are used. Is it a common rule?