[PATCH] D79052: [clang codegen] Fix alignment of "Address" for incomplete array pointer.
Eli Friedman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 2 14:50:34 PDT 2020
efriedma updated this revision to Diff 267994.
efriedma added a comment.
"Address" the review comments. Not really happy with this, but not sure what else to do.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D79052/new/
https://reviews.llvm.org/D79052
Files:
clang/lib/CodeGen/CodeGenModule.cpp
clang/test/CodeGenCXX/alignment.cpp
Index: clang/test/CodeGenCXX/alignment.cpp
===================================================================
--- clang/test/CodeGenCXX/alignment.cpp
+++ clang/test/CodeGenCXX/alignment.cpp
@@ -309,3 +309,7 @@
AlignedArray result = d.bArray;
}
}
+
+// CHECK-LABEL: @_Z22incomplete_array_derefPA_i
+// CHECK: load i32, i32* {{%.*}}, align 4
+int incomplete_array_deref(int (*p)[]) { return (*p)[2]; }
Index: clang/lib/CodeGen/CodeGenModule.cpp
===================================================================
--- clang/lib/CodeGen/CodeGenModule.cpp
+++ clang/lib/CodeGen/CodeGenModule.cpp
@@ -5993,32 +5993,58 @@
}
}
+ bool AlignForArray = T->isArrayType();
+
+ // Analyze the base element type, so we don't get confused by incomplete
+ // array types.
+ T = getBaseElementType(T);
+
+ if (T->isIncompleteType()) {
+ // FIXME: This duplicates logic in ASTContext::getTypeAlignIfKnown. But we
+ // that doesn't return whether we got the alignment from an attribute.
+ if (const auto *TT = T->getAs<TypedefType>()) {
+ if (unsigned Align = TT->getDecl()->getMaxAlignment()) {
+ if (BaseInfo)
+ *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType);
+ return getContext().toCharUnitsFromBits(Align);
+ }
+ }
+
+ // Otherwise, see if the declaration of the type had an attribute.
+ if (const auto *TT = T->getAs<TagType>()) {
+ if (BaseInfo)
+ *BaseInfo = LValueBaseInfo(AlignmentSource::AttributedType);
+ return getContext().toCharUnitsFromBits(TT->getDecl()->getMaxAlignment());
+ }
+
+ // The alignment is completely unknown; just return 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;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D79052.267994.patch
Type: text/x-patch
Size: 3595 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20200602/b1d74dd8/attachment-0001.bin>
More information about the cfe-commits
mailing list