aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/LoopUtils.cpp
diff options
context:
space:
mode:
authorWei Wang <apollo.mobility@gmail.com>2021-11-19 13:14:41 -0800
committerWei Wang <apollo.mobility@gmail.com>2021-11-19 13:22:07 -0800
commita075d67222832c234296ffd605f19e33023e6060 (patch)
treeed7cf4103640261287654470c5d24429b35bf395 /llvm/lib/Transforms/Utils/LoopUtils.cpp
parent491efa7f31cbc39fe0aaad261a840cc5311346fb (diff)
downloadllvm-a075d67222832c234296ffd605f19e33023e6060.zip
llvm-a075d67222832c234296ffd605f19e33023e6060.tar.gz
llvm-a075d67222832c234296ffd605f19e33023e6060.tar.bz2
[Sema] fix nondeterminism in ASTContext::getDeducedTemplateSpecializationType
`DeducedTemplateSpecializationTypes` is a `llvm::FoldingSet<DeducedTemplateSpecializationType>` [1], where `FoldingSetNodeID` is based on the values: {`TemplateName`, `QualType`, `IsDeducedAsDependent`}, those values are also used as `DeducedTemplateSpecializationType` constructor arguments. A `FoldingSetNodeID` created by the static `DeducedTemplateSpecializationType::Profile` may not be equal to`FoldingSetNodeID` created by a member `DeducedTemplateSpecializationType::Profile` of an instance created with the same {`TemplateName`, `QualType`, `IsDeducedAsDependent`}, which makes `DeducedTemplateSpecializationTypes` lookups nondeterministic. Specifically, while `IsDeducedAsDependent` value is passes to the constructor, `IsDependent()` method on the created instance may return a different value, because `IsDependent` is not saved as is: ```name=clang/include/clang/AST/Type.h DeducedTemplateSpecializationType(TemplateName Template, QualType DeducedAsType, bool IsDeducedAsDependent) : DeducedType(DeducedTemplateSpecialization, DeducedAsType, toTypeDependence(Template.getDependence()) | // <~ also considers `TemplateName` parameter (IsDeducedAsDependent ? TypeDependence::DependentInstantiation : TypeDependence::None)), ``` For example, if an instance A with key `FoldingSetNodeID {A, B, false}` is inserted. Then a key `FoldingSetNodeID {A, B, true}` is probed: If it happens to correspond to the same bucket in `FoldingSet` as the first key, and `A.Profile()` returns `FoldingSetNodeID {A, B, true}`, then it's a hit. If the bucket for the second key is different from the first key, instance A is not considered at all, and it's a no hit, even if `A.Profile()` returns `FoldingSetNodeID {A, B, true}`. Since `TemplateName`, `QualType` parameter values involve memory pointers, the lookup result depend on allocator, and may differ from run to run. When this is used as part of modules compilation, it may result in "module out of date" errors, if imported modules are built on different machines. This makes `ASTContext::getDeducedTemplateSpecializationType` consider `Template.isDependent()` similar `DeducedTemplateSpecializationType` constructor. Tested on a very big codebase, by running modules compilations from directories with varied path length (seem to affect allocator seed). 1. https://llvm.org/docs/ProgrammersManual.html#llvm-adt-foldingset-h Patch by Wei Wang and Igor Sugak! Reviewed By: bruno Differential Revision: https://reviews.llvm.org/D112481
Diffstat (limited to 'llvm/lib/Transforms/Utils/LoopUtils.cpp')
0 files changed, 0 insertions, 0 deletions