[clang] 66aff32 - Issue error on invalid arithemtic conversions in C ternary

Erich Keane via cfe-commits cfe-commits at lists.llvm.org
Mon Jul 20 08:02:50 PDT 2020


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 at +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);
+}


        


More information about the cfe-commits mailing list