Skip to content

Commit 343bed8

Browse files
committed
Canonically identical types are allowed in compound expressions in C
We did not have a catch-all for when the two operand types are identical after canonicalization. Instead, we handled that on a case by case basis. Thus, we would diagnose code like: ``` mat4 test(int a) { typedef float mat4 __attribute((matrix_type(4, 4))); mat4 transform; return (a > 0) ? transform : transform; } ``` This simplifies the logic and will be more forwards compatible with other extended datatypes. Fixes #69008
1 parent 5e1c2bf commit 343bed8

File tree

3 files changed

+23
-13
lines changed

3 files changed

+23
-13
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,10 +386,13 @@ Bug Fixes in This Version
386386
cannot be used with ``Release`` mode builds. (`#68237 <https://github.com/llvm/llvm-project/issues/68237>`_).
387387
- Fix crash in evaluating ``constexpr`` value for invalid template function.
388388
Fixes (`#68542 <https://github.com/llvm/llvm-project/issues/68542>`_)
389-
390389
- Fixed an issue when a shift count larger than ``__INT64_MAX__``, in a right
391390
shift operation, could result in missing warnings about
392391
``shift count >= width of type`` or internal compiler error.
392+
- Fixed an issue with computing the common type for the LHS and RHS of a `?:`
393+
operator in C. No longer issuing a confusing diagnostic along the lines of
394+
"incompatible operand types ('foo' and 'foo')" with extensions such as matrix
395+
types. Fixes (`#69008 <https://github.com/llvm/llvm-project/issues/69008>`_)
393396

394397
Bug Fixes to Compiler Builtins
395398
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/Sema/SemaExpr.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9186,7 +9186,7 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
91869186
if (checkCondition(*this, Cond.get(), QuestionLoc))
91879187
return QualType();
91889188

9189-
// Now check the two expressions.
9189+
// Handle vectors.
91909190
if (LHS.get()->getType()->isVectorType() ||
91919191
RHS.get()->getType()->isVectorType())
91929192
return CheckVectorOperands(LHS, RHS, QuestionLoc, /*isCompAssign*/ false,
@@ -9244,11 +9244,6 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
92449244
return ResTy;
92459245
}
92469246

9247-
// And if they're both bfloat (which isn't arithmetic), that's fine too.
9248-
if (LHSTy->isBFloat16Type() && RHSTy->isBFloat16Type()) {
9249-
return Context.getCommonSugaredType(LHSTy, RHSTy);
9250-
}
9251-
92529247
// If both operands are the same structure or union type, the result is that
92539248
// type.
92549249
if (const RecordType *LHSRT = LHSTy->getAs<RecordType>()) { // C99 6.5.15p3
@@ -9320,17 +9315,17 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
93209315
/*IsIntFirstExpr=*/false))
93219316
return LHSTy;
93229317

9323-
// Allow ?: operations in which both operands have the same
9324-
// built-in sizeless type.
9325-
if (LHSTy->isSizelessBuiltinType() && Context.hasSameType(LHSTy, RHSTy))
9326-
return Context.getCommonSugaredType(LHSTy, RHSTy);
9327-
93289318
// Emit a better diagnostic if one of the expressions is a null pointer
93299319
// constant and the other is not a pointer type. In this case, the user most
93309320
// likely forgot to take the address of the other expression.
93319321
if (DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc))
93329322
return QualType();
93339323

9324+
// Finally, if the LHS and RHS types are canonically the same type, we can
9325+
// use the common sugared type.
9326+
if (Context.hasSameType(LHSTy, RHSTy))
9327+
return Context.getCommonSugaredType(LHSTy, RHSTy);
9328+
93349329
// Otherwise, the operands are not compatible.
93359330
Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
93369331
<< LHSTy << RHSTy << LHS.get()->getSourceRange()

clang/test/Sema/conditional.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %clang_cc1 %s -fsyntax-only -verify
1+
// RUN: %clang_cc1 %s -fsyntax-only -fenable-matrix -verify
22

33
const char* test1 = 1 ? "i" : 1 == 1 ? "v" : "r";
44

@@ -19,3 +19,15 @@ void pr39809(void) {
1919
_Generic(0 ? (int volatile*)0 : (void const*)1, void volatile const*: (void)0);
2020
_Generic(0 ? (int volatile*)0 : (void const*)0, void volatile const*: (void)0);
2121
}
22+
23+
// Ensure we compute the correct common type for extension types as well.
24+
void GH69008(void) {
25+
typedef float mat4 __attribute((matrix_type(4, 4)));
26+
typedef float mat5 __attribute((matrix_type(5, 5)));
27+
28+
mat4 transform;
29+
(void)(1 ? transform : transform); // ok
30+
31+
mat5 other_transform;
32+
(void)(1 ? other_transform : transform); // expected-error {{incompatible operand types ('mat5' (aka 'float __attribute__((matrix_type(5, 5)))') and 'mat4' (aka 'float __attribute__((matrix_type(4, 4)))'))}}
33+
}

0 commit comments

Comments
 (0)