Skip to content

Commit cdf9f1a

Browse files
committed
[clang] Fix array types comparison in getCommonSugaredType
Const-qualification of an array caused by constexpr specifier can produce QualType, where the const qualifier is set both as fast qualifier and as a qualifier of the array element type. It can result in a compiler crash, because such QualType does not compare equal to the same type but without extra qualification. To avoid the crash, the redundant qualifiers are removed while searching for common sugar. It fixes #97005 (Clang crashed in ASTContext::getCommonSugaredType).
1 parent 3f62718 commit cdf9f1a

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14171,6 +14171,15 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
1417114171
static auto unwrapSugar(SplitQualType &T, Qualifiers &QTotal) {
1417214172
SmallVector<SplitQualType, 8> R;
1417314173
while (true) {
14174+
if (const auto *ATy = dyn_cast<ArrayType>(T.Ty)) {
14175+
// C++ 9.3.3.4p3: Any type of the form "cv-qualifier-seq array of N U" is
14176+
// adjusted to "array of N cv-qualifier-seq U".
14177+
// C23 6.7.3p10: If the specification of an array type includes any type
14178+
// qualifiers, both the array and the element type are so-qualified.
14179+
//
14180+
// To simplify comparison remove the redundant qualifiers from the array.
14181+
T.Quals.removeCVRQualifiers(Qualifiers::Const | Qualifiers::Volatile);
14182+
}
1417414183
QTotal.addConsistentQualifiers(T.Quals);
1417514184
QualType NT = T.Ty->getLocallyUnqualifiedSingleStepDesugaredType();
1417614185
if (NT == QualType(T.Ty, 0))
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -triple x86_64-linux-gnu %s
2+
3+
bool a;
4+
constexpr const unsigned char c[] = { 5 };
5+
constexpr const unsigned char d[1] = { 0 };
6+
auto b = (a ? d : c);
7+
8+
constexpr const unsigned char c1[][1] = {{ 5 }};
9+
constexpr const unsigned char d1[1][1] = {{ 0 }};
10+
auto b1 = (a ? d1 : c1);

0 commit comments

Comments
 (0)