r183085 - Allow paren casted throw statements inside of ternary expressions

David Majnemer david.majnemer at gmail.com
Sun Jun 2 01:40:42 PDT 2013


Author: majnemer
Date: Sun Jun  2 03:40:42 2013
New Revision: 183085

URL: http://llvm.org/viewvc/llvm-project?rev=183085&view=rev
Log:
Allow paren casted throw statements inside of ternary expressions

clang would incorrectly not allow the following:

int x = true ? (throw 1) : 2;

The problem exists because we don't see beyond the parens.
This, in turn, causes us to believe that we are choosing between void
and int which we diagnose as an error.

Instead, allow clang to see the 'throw' inside the parens.

Modified:
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/test/CodeGenCXX/throw-expressions.cpp
    cfe/trunk/test/SemaCXX/conditional-expr.cpp

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=183085&r1=183084&r2=183085&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Sun Jun  2 03:40:42 2013
@@ -4273,8 +4273,8 @@ QualType Sema::CXXCheckConditionalOperan
     //   ... and one of the following shall hold:
     //   -- The second or the third operand (but not both) is a throw-
     //      expression; the result is of the type of the other and is a prvalue.
-    bool LThrow = isa<CXXThrowExpr>(LHS.get());
-    bool RThrow = isa<CXXThrowExpr>(RHS.get());
+    bool LThrow = isa<CXXThrowExpr>(LHS.get()->IgnoreParenCasts());
+    bool RThrow = isa<CXXThrowExpr>(RHS.get()->IgnoreParenCasts());
     if (LThrow && !RThrow)
       return RTy;
     if (RThrow && !LThrow)

Modified: cfe/trunk/test/CodeGenCXX/throw-expressions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/throw-expressions.cpp?rev=183085&r1=183084&r2=183085&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/throw-expressions.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/throw-expressions.cpp Sun Jun  2 03:40:42 2013
@@ -43,3 +43,27 @@ int test5(bool x, bool y, int z) {
 //
 // end:
 // CHECK: ret i32
+
+int test6(bool x, bool y, int z) {
+  return (x ? throw 1 : y) ? z : (throw 2);
+}
+// CHECK: define i32 @_Z5test6bbi(
+// CHECK: br i1
+//
+// x.true:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// x.false:
+// CHECK: br i1
+//
+// y.true:
+// CHECK: load i32*
+// CHECK: br label
+//
+// y.false:
+// CHECK: call void @__cxa_throw(
+// CHECK-NEXT: unreachable
+//
+// end:
+// CHECK: ret i32

Modified: cfe/trunk/test/SemaCXX/conditional-expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conditional-expr.cpp?rev=183085&r1=183084&r2=183085&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conditional-expr.cpp (original)
+++ cfe/trunk/test/SemaCXX/conditional-expr.cpp Sun Jun  2 03:40:42 2013
@@ -81,6 +81,8 @@ void test()
   i1 ? test() : test();
   i1 = i1 ? throw 0 : 0;
   i1 = i1 ? 0 : throw 0;
+  i1 = i1 ? (throw 0) : 0;
+  i1 = i1 ? 0 : (throw 0);
   i1 ? 0 : test(); // expected-error {{right operand to ? is void, but left operand is of type 'int'}}
   i1 ? test() : 0; // expected-error {{left operand to ? is void, but right operand is of type 'int'}}
   (i1 ? throw 0 : i1) = 0; // expected-error {{expression is not assignable}}





More information about the cfe-commits mailing list