diff options
author | Eli Friedman <efriedma@quicinc.com> | 2020-04-28 16:04:26 -0700 |
---|---|---|
committer | Eli Friedman <efriedma@quicinc.com> | 2020-06-23 17:16:17 -0700 |
commit | bf8b63ed296c1ecad03c83b798ffbfa039cbceb4 (patch) | |
tree | 2eca510af14338be3a0647892d63f6a2c24b87b8 /clang/lib/CodeGen/CodeGenModule.cpp | |
parent | d1446017f3fdc2f6a9efba222008d20afa1e26cc (diff) | |
download | llvm-bf8b63ed296c1ecad03c83b798ffbfa039cbceb4.zip llvm-bf8b63ed296c1ecad03c83b798ffbfa039cbceb4.tar.gz llvm-bf8b63ed296c1ecad03c83b798ffbfa039cbceb4.tar.bz2 |
[clang codegen] Fix alignment of "Address" for incomplete array pointer.
The code was assuming all incomplete types don't have meaningful
alignment, but incomplete arrays do have meaningful alignment.
Fixes https://bugs.llvm.org/show_bug.cgi?id=45710
Differential Revision: https://reviews.llvm.org/D79052
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 7a9df70..f0ab516 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -5990,6 +5990,9 @@ CharUnits CodeGenModule::getNaturalTypeAlignment(QualType T, if (TBAAInfo) *TBAAInfo = getTBAAAccessInfo(T); + // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown. But + // that doesn't return the information we need to compute BaseInfo. + // Honor alignment typedef attributes even on incomplete types. // We also honor them straight for C++ class types, even as pointees; // there's an expressivity gap here. @@ -6001,32 +6004,46 @@ CharUnits CodeGenModule::getNaturalTypeAlignment(QualType T, } } + bool AlignForArray = T->isArrayType(); + + // Analyze the base element type, so we don't get confused by incomplete + // array types. + T = getContext().getBaseElementType(T); + + if (T->isIncompleteType()) { + // We could try to replicate the logic from + // ASTContext::getTypeAlignIfKnown, but nothing uses the alignment if the + // type is incomplete, so it's impossible to test. We could try to reuse + // getTypeAlignIfKnown, but that doesn't return the information we need + // to set BaseInfo. So just ignore the possibility that the alignment is + // greater than one. + if (BaseInfo) + *BaseInfo = LValueBaseInfo(AlignmentSource::Type); + return CharUnits::One(); + } + if (BaseInfo) *BaseInfo = LValueBaseInfo(AlignmentSource::Type); CharUnits Alignment; - if (T->isIncompleteType()) { - Alignment = CharUnits::One(); // Shouldn't be used, but pessimistic is best. + // For C++ class pointees, we don't know whether we're pointing at a + // base or a complete object, so we generally need to use the + // non-virtual alignment. + const CXXRecordDecl *RD; + if (forPointeeType && !AlignForArray && (RD = T->getAsCXXRecordDecl())) { + Alignment = getClassPointerAlignment(RD); } else { - // For C++ class pointees, we don't know whether we're pointing at a - // base or a complete object, so we generally need to use the - // non-virtual alignment. - const CXXRecordDecl *RD; - if (forPointeeType && (RD = T->getAsCXXRecordDecl())) { - Alignment = getClassPointerAlignment(RD); - } else { - Alignment = getContext().getTypeAlignInChars(T); - if (T.getQualifiers().hasUnaligned()) - Alignment = CharUnits::One(); - } + Alignment = getContext().getTypeAlignInChars(T); + if (T.getQualifiers().hasUnaligned()) + Alignment = CharUnits::One(); + } - // Cap to the global maximum type alignment unless the alignment - // was somehow explicit on the type. - if (unsigned MaxAlign = getLangOpts().MaxTypeAlign) { - if (Alignment.getQuantity() > MaxAlign && - !getContext().isAlignmentRequired(T)) - Alignment = CharUnits::fromQuantity(MaxAlign); - } + // Cap to the global maximum type alignment unless the alignment + // was somehow explicit on the type. + if (unsigned MaxAlign = getLangOpts().MaxTypeAlign) { + if (Alignment.getQuantity() > MaxAlign && + !getContext().isAlignmentRequired(T)) + Alignment = CharUnits::fromQuantity(MaxAlign); } return Alignment; } |