Skip to content

Commit 8d26593

Browse files
committed
[Clang] Fix Codegen UO real/imag crash on scalar with type promotion
1 parent ce170d2 commit 8d26593

File tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,7 @@ Crash and bug fixes
558558
- Fixed a crash in the static analyzer that when the expression in an
559559
``[[assume(expr)]]`` attribute was enclosed in parentheses. (#GH151529)
560560
- Fixed a crash when parsing ``#embed`` parameters with unmatched closing brackets. (#GH152829)
561+
- Fixed a crash when compiling ``__real__`` or ``__imag__`` unary operator on scalar value with type promotion. (#GH160583)
561562

562563
Improvements
563564
^^^^^^^^^^^^

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3672,17 +3672,19 @@ Value *ScalarExprEmitter::VisitReal(const UnaryOperator *E,
36723672
// If it's an l-value, load through the appropriate subobject l-value.
36733673
// Note that we have to ask E because Op might be an l-value that
36743674
// this won't work for, e.g. an Obj-C property.
3675-
if (E->isGLValue()) {
3675+
if (E->isGLValue()) {
36763676
if (!PromotionType.isNull()) {
36773677
CodeGenFunction::ComplexPairTy result = CGF.EmitComplexExpr(
36783678
Op, /*IgnoreReal*/ IgnoreResultAssign, /*IgnoreImag*/ true);
3679-
if (result.first)
3680-
result.first = CGF.EmitPromotedValue(result, PromotionType).first;
3681-
return result.first;
3682-
} else {
3683-
return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3684-
.getScalarVal();
3679+
PromotionType = PromotionType->isAnyComplexType()
3680+
? PromotionType
3681+
: CGF.getContext().getComplexType(PromotionType);
3682+
return result.first ? CGF.EmitPromotedValue(result, PromotionType).first
3683+
: result.first;
36853684
}
3685+
3686+
return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3687+
.getScalarVal();
36863688
}
36873689
// Otherwise, calculate and project.
36883690
return CGF.EmitComplexExpr(Op, false, true).first;
@@ -3715,13 +3717,16 @@ Value *ScalarExprEmitter::VisitImag(const UnaryOperator *E,
37153717
if (!PromotionType.isNull()) {
37163718
CodeGenFunction::ComplexPairTy result = CGF.EmitComplexExpr(
37173719
Op, /*IgnoreReal*/ true, /*IgnoreImag*/ IgnoreResultAssign);
3718-
if (result.second)
3719-
result.second = CGF.EmitPromotedValue(result, PromotionType).second;
3720-
return result.second;
3721-
} else {
3722-
return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3723-
.getScalarVal();
3720+
PromotionType = PromotionType->isAnyComplexType()
3721+
? PromotionType
3722+
: CGF.getContext().getComplexType(PromotionType);
3723+
return result.second
3724+
? CGF.EmitPromotedValue(result, PromotionType).second
3725+
: result.second;
37243726
}
3727+
3728+
return CGF.EmitLoadOfLValue(CGF.EmitLValue(E), E->getExprLoc())
3729+
.getScalarVal();
37253730
}
37263731
// Otherwise, calculate and project.
37273732
return CGF.EmitComplexExpr(Op, true, false).second;

clang/test/CodeGen/complex.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,12 @@ void t92(void) {
113113
(0 ? (_Complex double) 2.0f : 2.0f);
114114
}
115115

116+
void real_on_scalar_with_type_promotion() {
117+
_Float16 _Complex a;
118+
_Float16 b = __real__(__real__ a);
119+
}
120+
121+
void imag_on_scalar_with_type_promotion() {
122+
_Float16 _Complex a;
123+
_Float16 b = __real__(__imag__ a);
124+
}

0 commit comments

Comments
 (0)