https://github.com/spavloff created 
https://github.com/llvm/llvm-project/pull/131649

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 https://github.com/llvm/llvm-project/issues/97005 (Clang crashed in 
ASTContext::getCommonSugaredType).

>From cdf9f1a5b960d2561a7c4415313b397578de0f8b Mon Sep 17 00:00:00 2001
From: Serge Pavlov <sepavl...@gmail.com>
Date: Mon, 17 Mar 2025 21:33:24 +0700
Subject: [PATCH] [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 https://github.com/llvm/llvm-project/issues/97005 (Clang
crashed in ASTContext::getCommonSugaredType).
---
 clang/lib/AST/ASTContext.cpp                          |  9 +++++++++
 clang/test/SemaCXX/constexpr-implicit-const-97005.cpp | 10 ++++++++++
 2 files changed, 19 insertions(+)
 create mode 100644 clang/test/SemaCXX/constexpr-implicit-const-97005.cpp

diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 7ed5b033d9bd8..2614c4235c994 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -14171,6 +14171,15 @@ static QualType getCommonSugarTypeNode(ASTContext 
&Ctx, const Type *X,
 static auto unwrapSugar(SplitQualType &T, Qualifiers &QTotal) {
   SmallVector<SplitQualType, 8> R;
   while (true) {
+    if (const auto *ATy = dyn_cast<ArrayType>(T.Ty)) {
+      // C++ 9.3.3.4p3: Any type of the form "cv-qualifier-seq array of N U" is
+      // adjusted to "array of N cv-qualifier-seq U".
+      // C23 6.7.3p10: If the specification of an array type includes any type
+      // qualifiers, both the array and the element type are so-qualified.
+      //
+      // To simplify comparison remove the redundant qualifiers from the array.
+      T.Quals.removeCVRQualifiers(Qualifiers::Const | Qualifiers::Volatile);
+    }
     QTotal.addConsistentQualifiers(T.Quals);
     QualType NT = T.Ty->getLocallyUnqualifiedSingleStepDesugaredType();
     if (NT == QualType(T.Ty, 0))
diff --git a/clang/test/SemaCXX/constexpr-implicit-const-97005.cpp 
b/clang/test/SemaCXX/constexpr-implicit-const-97005.cpp
new file mode 100644
index 0000000000000..db6106998d02b
--- /dev/null
+++ b/clang/test/SemaCXX/constexpr-implicit-const-97005.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple x86_64-linux-gnu %s
+
+bool a;
+constexpr const unsigned char c[] = { 5 };
+constexpr const unsigned char d[1] = { 0 };
+auto b = (a ? d : c);
+
+constexpr const unsigned char c1[][1] = {{ 5 }};
+constexpr const unsigned char d1[1][1] = {{ 0 }};
+auto b1 = (a ? d1 : c1);

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to