[clang] [clang] Fix array types comparison in getCommonSugaredType (PR #131649)

via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 17 10:39:53 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Serge Pavlov (spavloff)

<details>
<summary>Changes</summary>

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).

---
Full diff: https://github.com/llvm/llvm-project/pull/131649.diff


2 Files Affected:

- (modified) clang/lib/AST/ASTContext.cpp (+9) 
- (added) clang/test/SemaCXX/constexpr-implicit-const-97005.cpp (+10) 


``````````diff
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);

``````````

</details>


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


More information about the cfe-commits mailing list