]> granicus.if.org Git - clang/commitdiff
[modules] Fix crash in complex class merging scenario.
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 15 Nov 2017 01:33:46 +0000 (01:33 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 15 Nov 2017 01:33:46 +0000 (01:33 +0000)
When we merge together class definitions, we can end up with the canonical
declaration of a field not being the one that was lexically within the
canonical definition of the class. Additionally, when we merge class
definitions via update records (eg, for a template specialization whose
declaration is instantiated in one module and whose definition is instantiated
in multiple others), we can end up with the list of lexical contents for the
class not including a particular declaration of a field whose lexical parent is
that class definition. In the worst case, we have a field whose canonical
declaration's lexical parent has no fields, and in that case this attempt to
number the fields by walking the fields in the declaration of the class that
contained one of the canonical fields will fail.

Instead, when numbering fields in a class, do the obvious thing: walk the
fields in the definition.

I'm still trying to reduce a testcase; the setup that leads to the above
scenario seems to be quite fragile.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@318245 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Decl.cpp

index 6d940c402614a9b028305da2d16bd675924b5ee2..ce9b46c070976049966b7874edd09509cece4c7b 100644 (file)
@@ -3630,7 +3630,8 @@ unsigned FieldDecl::getFieldIndex() const {
   if (CachedFieldIndex) return CachedFieldIndex - 1;
 
   unsigned Index = 0;
-  const RecordDecl *RD = getParent();
+  const RecordDecl *RD = getParent()->getDefinition();
+  assert(RD && "requested index for field of struct with no definition");
 
   for (auto *Field : RD->fields()) {
     Field->getCanonicalDecl()->CachedFieldIndex = Index + 1;