summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2013-06-02 08:40:42 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2013-06-02 08:40:42 +0000
commita9d4f77eb928ba0752466b604667bbf9a7af1c9a (patch)
tree9239bc80e08fa306ab1c6617c43ee226f9e8abac
parent3fbb763a92612bb6567a7e39b50bd3e7e2f2e6a7 (diff)
downloadbcm5719-llvm-a9d4f77eb928ba0752466b604667bbf9a7af1c9a.tar.gz
bcm5719-llvm-a9d4f77eb928ba0752466b604667bbf9a7af1c9a.zip
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. llvm-svn: 183085
-rw-r--r--clang/lib/Sema/SemaExprCXX.cpp4
-rw-r--r--clang/test/CodeGenCXX/throw-expressions.cpp24
-rw-r--r--clang/test/SemaCXX/conditional-expr.cpp2
3 files changed, 28 insertions, 2 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index 439fc1636f5..087fea206d7 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -4273,8 +4273,8 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// ... 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)
diff --git a/clang/test/CodeGenCXX/throw-expressions.cpp b/clang/test/CodeGenCXX/throw-expressions.cpp
index ba8a86881a6..87c481b25fe 100644
--- a/clang/test/CodeGenCXX/throw-expressions.cpp
+++ b/clang/test/CodeGenCXX/throw-expressions.cpp
@@ -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
diff --git a/clang/test/SemaCXX/conditional-expr.cpp b/clang/test/SemaCXX/conditional-expr.cpp
index 692aaefc9d5..5abee4a3c4f 100644
--- a/clang/test/SemaCXX/conditional-expr.cpp
+++ b/clang/test/SemaCXX/conditional-expr.cpp
@@ -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}}
OpenPOWER on IntegriCloud