Author: Erich Keane Date: 2020-07-20T08:02:37-07:00 New Revision: 66aff3239849507861d050c013cbe17c4a5781a7
URL: https://github.com/llvm/llvm-project/commit/66aff3239849507861d050c013cbe17c4a5781a7 DIFF: https://github.com/llvm/llvm-project/commit/66aff3239849507861d050c013cbe17c4a5781a7.diff LOG: Issue error on invalid arithemtic conversions in C ternary As reported in PR46774, an invalid arithemetic conversion used in a C ternary operator resulted in an assertion. This patch replaces that assertion with a diagnostic stating that the conversion failed. At the moment, I believe the only case of this happening is _ExtInt types. Added: clang/test/Sema/ext-int.c Modified: clang/lib/Sema/SemaExpr.cpp clang/test/SemaCXX/ext-int.cpp Removed: ################################################################################ diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 598aede14dd3..0bed0ddf539b 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -8106,6 +8106,15 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, // If both operands have arithmetic type, do the usual arithmetic conversions // to find a common type: C99 6.5.15p3,5. if (LHSTy->isArithmeticType() && RHSTy->isArithmeticType()) { + // Disallow invalid arithmetic conversions, such as those between ExtInts of + // diff erent sizes, or between ExtInts and other types. + if (ResTy.isNull() && (LHSTy->isExtIntType() || RHSTy->isExtIntType())) { + Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) + << LHSTy << RHSTy << LHS.get()->getSourceRange() + << RHS.get()->getSourceRange(); + return QualType(); + } + LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy)); RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy)); diff --git a/clang/test/Sema/ext-int.c b/clang/test/Sema/ext-int.c new file mode 100644 index 000000000000..6996942a204b --- /dev/null +++ b/clang/test/Sema/ext-int.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s -Wimplicit-int-conversion -triple x86_64-gnu-linux + +typedef _ExtInt(31) EI31; + +void Ternary(_ExtInt(30) s30, EI31 s31a, _ExtInt(31) s31b, + _ExtInt(32) s32, int b) { + b ? s30 : s31a; // expected-error{{incompatible operand types}} + b ? s31a : s30; // expected-error{{incompatible operand types}} + b ? s32 : 0; // expected-error{{incompatible operand types}} + (void)(b ? s31a : s31b); + (void)(s30 ? s31a : s31b); +} diff --git a/clang/test/SemaCXX/ext-int.cpp b/clang/test/SemaCXX/ext-int.cpp index 14f11a6bb961..0f2a3b89be1f 100644 --- a/clang/test/SemaCXX/ext-int.cpp +++ b/clang/test/SemaCXX/ext-int.cpp @@ -275,3 +275,12 @@ void ImplicitCasts(_ExtInt(31) s31, _ExtInt(33) s33, int i) { // expected-warning@+1{{implicit conversion loses integer precision}} i = s33; } + +void Ternary(_ExtInt(30) s30, _ExtInt(31) s31a, _ExtInt(31) s31b, + _ExtInt(32) s32, bool b) { + b ? s30 : s31a; // expected-error{{incompatible operand types}} + b ? s31a : s30; // expected-error{{incompatible operand types}} + b ? s32 : (int)0; // expected-error{{incompatible operand types}} + (void)(b ? s31a : s31b); + (void)(s30 ? s31a : s31b); +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits