Skip to content

Conversation

@zahiraam
Copy link
Contributor

@zahiraam zahiraam commented Nov 20, 2025

This patch fixes a crash in Clang that occurs when the compiler retrieves the element type of a complex type but receives a sugared type. See example here: https://godbolt.org/z/cdbdeMcaT
This patch fixes the crash.

@github-actions
Copy link

🐧 Linux x64 Test Results

  • 111350 tests passed
  • 4431 tests skipped

@zahiraam zahiraam marked this pull request as ready for review November 20, 2025 21:30
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:codegen IR generation bugs: mangling, exceptions, etc. labels Nov 20, 2025
@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2025

@llvm/pr-subscribers-clang

Author: Zahira Ammarguellat (zahiraam)

Changes

This patch fixes a crash in Clang that occurs when the compiler retrieves the element type of a complex type but receives a sugared type. See example here: https://godbolt.org/z/cdbdeMcaT
This patch fixes the crash.


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

3 Files Affected:

  • (modified) clang/lib/CodeGen/CGExprComplex.cpp (+2-1)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+2-2)
  • (modified) clang/test/CodeGen/promoted-complex-div.c (+52)
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index d281c4c20616a..f33e5d75296eb 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -320,7 +320,8 @@ class ComplexExprEmitter
   QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
                             bool IsComplexDivisor) {
     if (auto *CT = Ty->getAs<ComplexType>()) {
-      QualType ElementType = CT->getElementType();
+      QualType ElementType =
+          CT->getElementType().getDesugaredType(CGF.getContext());
       bool IsFloatingType = ElementType->isFloatingType();
       bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
                                     LangOptions::ComplexRangeKind::CX_Promoted;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 10f0ec3010c6c..ea7937d551ddb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10726,13 +10726,13 @@ static void DetectPrecisionLossInComplexDivision(Sema &S, QualType DivisorTy,
   if (!CT)
     return;
 
-  QualType ElementType = CT->getElementType();
+  ASTContext &Ctx = S.getASTContext();
+  QualType ElementType = CT->getElementType().getDesugaredType(Ctx);
   bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() ==
                                 LangOptions::ComplexRangeKind::CX_Promoted;
   if (!ElementType->isFloatingType() || !IsComplexRangePromoted)
     return;
 
-  ASTContext &Ctx = S.getASTContext();
   QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType);
   const llvm::fltSemantics &ElementTypeSemantics =
       Ctx.getFloatTypeSemantics(ElementType);
diff --git a/clang/test/CodeGen/promoted-complex-div.c b/clang/test/CodeGen/promoted-complex-div.c
index 7ed7b07db83ae..006b5e334e6ea 100644
--- a/clang/test/CodeGen/promoted-complex-div.c
+++ b/clang/test/CodeGen/promoted-complex-div.c
@@ -81,3 +81,55 @@ _Complex double divf(_Complex double a, _Complex double b) {
 
   return a / b; // nopromotion-warning{{excess precision is requested but the target does not support excess precision which may result in observable differences in complex division behavior}}
 }
+
+// This test ensures that Clang does not crash when complex element types
+// require desugaring under -complex-range=promoted. Previously, a sugared
+// typedef element type (e.g., 'typedef double a') caused a crash during
+// complex range evaluation in both Sema and CodeGen.
+typedef double a;
+_Complex double *b;
+// CHECK-LABEL: define dso_local void @DivideByComplexZero
+void DivideByComplexZero() {
+  // CHECK: fpext double {{.*}} to x86_fp80
+  // CHECK: fpext double {{.*}} to x86_fp80
+  // CHECK: fmul x86_fp80
+  // CHECK: fmul x86_fp80
+  // CHECK: fadd x86_fp80
+  // CHECK: fmul x86_fp80
+  // CHECK: fmul x86_fp80
+  // CHECK: fsub x86_fp80
+  // CHECK: fdiv x86_fp80
+  // CHECK: fdiv x86_fp80
+  // CHECK: fptrunc x86_fp80
+  // CHECK: fptrunc x86_fp80
+
+  // NOX87: call double @llvm.fabs.f64(double {{.*}})
+  // NOX87-NEXT: call double @llvm.fabs.f64(double {{.*}}
+  // NOX87-NEXT: fcmp ugt double {{.*}}, {{.*}}
+  // NOX87-NEXT: br i1 {{.*}}, label
+  // NOX87: abs_rhsr_greater_or_equal_abs_rhsi:
+  // NOX87-NEXT: fmul double
+  // NOX87-NEXT: fadd double
+  // NOX87-NEXT: fdiv double
+  // NOX87-NEXT: fmul double
+  // NOX87-NEXT: fsub double
+  // NOX87-NEXT: fdiv double
+  // NOX87-NEXT: br label {{.*}}
+  // NOX87: abs_rhsr_less_than_abs_rhsi:
+  // NOX87-NEXT: fmul double
+  // NOX87-NEXT: fadd double
+  // NOX87-NEXT: fdiv double
+  // NOX87-NEXT: fmul double
+  // NOX87-NEXT: fsub double
+  // NOX87-NEXT: fdiv double
+  // NOX87-NEXT: br label {{.*}}
+  // NOX87: complex_div:
+  // NOX87-NEXT: phi double
+  // NOX87-NEXT: phi double
+  // NOX87-NEXT: getelementptr inbounds nuw { double, double }, ptr {{.*}}, i32 0, i32 0
+  // NOX87-NEXT: getelementptr inbounds nuw { double, double }, ptr {{.*}}, i32 0, i32 1
+  // NOX87-NEXT: store double
+  // NOX87-NEXT: store double
+
+  *b /= 1.0iF * (a)0;
+}

@llvmbot
Copy link
Member

llvmbot commented Nov 20, 2025

@llvm/pr-subscribers-clang-codegen

Author: Zahira Ammarguellat (zahiraam)

Changes

This patch fixes a crash in Clang that occurs when the compiler retrieves the element type of a complex type but receives a sugared type. See example here: https://godbolt.org/z/cdbdeMcaT
This patch fixes the crash.


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

3 Files Affected:

  • (modified) clang/lib/CodeGen/CGExprComplex.cpp (+2-1)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+2-2)
  • (modified) clang/test/CodeGen/promoted-complex-div.c (+52)
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index d281c4c20616a..f33e5d75296eb 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -320,7 +320,8 @@ class ComplexExprEmitter
   QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
                             bool IsComplexDivisor) {
     if (auto *CT = Ty->getAs<ComplexType>()) {
-      QualType ElementType = CT->getElementType();
+      QualType ElementType =
+          CT->getElementType().getDesugaredType(CGF.getContext());
       bool IsFloatingType = ElementType->isFloatingType();
       bool IsComplexRangePromoted = CGF.getLangOpts().getComplexRange() ==
                                     LangOptions::ComplexRangeKind::CX_Promoted;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 10f0ec3010c6c..ea7937d551ddb 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -10726,13 +10726,13 @@ static void DetectPrecisionLossInComplexDivision(Sema &S, QualType DivisorTy,
   if (!CT)
     return;
 
-  QualType ElementType = CT->getElementType();
+  ASTContext &Ctx = S.getASTContext();
+  QualType ElementType = CT->getElementType().getDesugaredType(Ctx);
   bool IsComplexRangePromoted = S.getLangOpts().getComplexRange() ==
                                 LangOptions::ComplexRangeKind::CX_Promoted;
   if (!ElementType->isFloatingType() || !IsComplexRangePromoted)
     return;
 
-  ASTContext &Ctx = S.getASTContext();
   QualType HigherElementType = Ctx.GetHigherPrecisionFPType(ElementType);
   const llvm::fltSemantics &ElementTypeSemantics =
       Ctx.getFloatTypeSemantics(ElementType);
diff --git a/clang/test/CodeGen/promoted-complex-div.c b/clang/test/CodeGen/promoted-complex-div.c
index 7ed7b07db83ae..006b5e334e6ea 100644
--- a/clang/test/CodeGen/promoted-complex-div.c
+++ b/clang/test/CodeGen/promoted-complex-div.c
@@ -81,3 +81,55 @@ _Complex double divf(_Complex double a, _Complex double b) {
 
   return a / b; // nopromotion-warning{{excess precision is requested but the target does not support excess precision which may result in observable differences in complex division behavior}}
 }
+
+// This test ensures that Clang does not crash when complex element types
+// require desugaring under -complex-range=promoted. Previously, a sugared
+// typedef element type (e.g., 'typedef double a') caused a crash during
+// complex range evaluation in both Sema and CodeGen.
+typedef double a;
+_Complex double *b;
+// CHECK-LABEL: define dso_local void @DivideByComplexZero
+void DivideByComplexZero() {
+  // CHECK: fpext double {{.*}} to x86_fp80
+  // CHECK: fpext double {{.*}} to x86_fp80
+  // CHECK: fmul x86_fp80
+  // CHECK: fmul x86_fp80
+  // CHECK: fadd x86_fp80
+  // CHECK: fmul x86_fp80
+  // CHECK: fmul x86_fp80
+  // CHECK: fsub x86_fp80
+  // CHECK: fdiv x86_fp80
+  // CHECK: fdiv x86_fp80
+  // CHECK: fptrunc x86_fp80
+  // CHECK: fptrunc x86_fp80
+
+  // NOX87: call double @llvm.fabs.f64(double {{.*}})
+  // NOX87-NEXT: call double @llvm.fabs.f64(double {{.*}}
+  // NOX87-NEXT: fcmp ugt double {{.*}}, {{.*}}
+  // NOX87-NEXT: br i1 {{.*}}, label
+  // NOX87: abs_rhsr_greater_or_equal_abs_rhsi:
+  // NOX87-NEXT: fmul double
+  // NOX87-NEXT: fadd double
+  // NOX87-NEXT: fdiv double
+  // NOX87-NEXT: fmul double
+  // NOX87-NEXT: fsub double
+  // NOX87-NEXT: fdiv double
+  // NOX87-NEXT: br label {{.*}}
+  // NOX87: abs_rhsr_less_than_abs_rhsi:
+  // NOX87-NEXT: fmul double
+  // NOX87-NEXT: fadd double
+  // NOX87-NEXT: fdiv double
+  // NOX87-NEXT: fmul double
+  // NOX87-NEXT: fsub double
+  // NOX87-NEXT: fdiv double
+  // NOX87-NEXT: br label {{.*}}
+  // NOX87: complex_div:
+  // NOX87-NEXT: phi double
+  // NOX87-NEXT: phi double
+  // NOX87-NEXT: getelementptr inbounds nuw { double, double }, ptr {{.*}}, i32 0, i32 0
+  // NOX87-NEXT: getelementptr inbounds nuw { double, double }, ptr {{.*}}, i32 0, i32 1
+  // NOX87-NEXT: store double
+  // NOX87-NEXT: store double
+
+  *b /= 1.0iF * (a)0;
+}

QualType getPromotionType(FPOptionsOverride Features, QualType Ty,
bool IsComplexDivisor) {
if (auto *CT = Ty->getAs<ComplexType>()) {
QualType ElementType = CT->getElementType();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not just use the canonical type?


QualType ElementType = CT->getElementType();
ASTContext &Ctx = S.getASTContext();
QualType ElementType = CT->getElementType().getDesugaredType(Ctx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

clang:codegen IR generation bugs: mangling, exceptions, etc. clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants