Skip to content

Commit 22e4fa0

Browse files
committed
Move const qualification of array to its elements
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. As a fix, the const qualifier is moved to the array element type when setting the implicit const. It fixes #97005 (Clang crashed in ASTContext::getCommonSugaredType).
1 parent 3f62718 commit 22e4fa0

File tree

4 files changed

+16
-3
lines changed

4 files changed

+16
-3
lines changed

clang/lib/Sema/SemaType.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5613,8 +5613,13 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
56135613
// A constexpr specifier used in an object declaration declares the object
56145614
// as const.
56155615
if (D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr &&
5616-
T->isObjectType())
5616+
T->isObjectType()) {
56175617
T.addConst();
5618+
// C++ 9.3.3.4p3: Any type of the form "cv-qualifier-seq array of N U" is
5619+
// adjusted to "array of N cv-qualifier-seq U".
5620+
if (const ArrayType *AType = Context.getAsArrayType(T))
5621+
T = QualType(AType, 0);
5622+
}
56185623

56195624
// C++2a [dcl.fct]p4:
56205625
// A parameter with volatile-qualified type is deprecated

clang/test/AST/ByteCode/constexpr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ constexpr TheA V19[3] = {};
8282
constexpr TheV V20[3] = {};
8383
// both-error@-1 {{constexpr variable cannot have type 'const TheV[3]' (aka 'const volatile short[3]')}}
8484
constexpr TheR V21[3] = {};
85-
// both-error@-1 {{constexpr variable cannot have type 'const TheR[3]' (aka 'float *restrict const[3]')}}
85+
// both-error@-1 {{constexpr variable cannot have type 'const TheR[3]' (aka 'float *const restrict[3]')}}
8686

8787
struct HasA {
8888
TheA f;

clang/test/Sema/constexpr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ constexpr TheA V19[3] = {};
8181
constexpr TheV V20[3] = {};
8282
// expected-error@-1 {{constexpr variable cannot have type 'const TheV[3]' (aka 'const volatile short[3]')}}
8383
constexpr TheR V21[3] = {};
84-
// expected-error@-1 {{constexpr variable cannot have type 'const TheR[3]' (aka 'float *restrict const[3]')}}
84+
// expected-error@-1 {{constexpr variable cannot have type 'const TheR[3]' (aka 'float *const restrict[3]')}}
8585

8686
struct HasA {
8787
TheA f;
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// RUN: %clang_cc1 -triple x86_64-linux-gnu -ast-dump %s | FileCheck %s
2+
3+
bool aaa;
4+
constexpr const unsigned char ccc[] = { 5 };
5+
constexpr const unsigned char ddd[1] = { 0 };
6+
auto bbb = (aaa ? ddd : ccc);
7+
8+
// CHECK: DeclRefExpr {{.*}} 'const unsigned char[1]' {{.*}} 'ddd' 'const unsigned char[1]'

0 commit comments

Comments
 (0)