summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ExprClassification.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2014-01-27 04:19:56 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2014-01-27 04:19:56 +0000
commit6a6a4bbdd4230a3a4c5630888452940a0006d546 (patch)
treeef18778ccc28c7d552a68e78606d2f83261ea717 /clang/lib/AST/ExprClassification.cpp
parent3bb1de7885fd065668d3eeecd73c91157286fcd6 (diff)
downloadbcm5719-llvm-6a6a4bbdd4230a3a4c5630888452940a0006d546.tar.gz
bcm5719-llvm-6a6a4bbdd4230a3a4c5630888452940a0006d546.zip
PR17052 / DR1560 (+DR1550): In a conditional expression between a glvalue and a
throw-expression, the result is also a glvalue and isn't unnecessarily coerced to a prvalue. llvm-svn: 200189
Diffstat (limited to 'clang/lib/AST/ExprClassification.cpp')
-rw-r--r--clang/lib/AST/ExprClassification.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/clang/lib/AST/ExprClassification.cpp b/clang/lib/AST/ExprClassification.cpp
index f9d2b2c7788..55b9f13b291 100644
--- a/clang/lib/AST/ExprClassification.cpp
+++ b/clang/lib/AST/ExprClassification.cpp
@@ -541,10 +541,21 @@ static Cl::Kinds ClassifyConditional(ASTContext &Ctx, const Expr *True,
"This is only relevant for C++.");
// C++ [expr.cond]p2
- // If either the second or the third operand has type (cv) void, [...]
- // the result [...] is a prvalue.
- if (True->getType()->isVoidType() || False->getType()->isVoidType())
+ // If either the second or the third operand has type (cv) void,
+ // one of the following shall hold:
+ if (True->getType()->isVoidType() || False->getType()->isVoidType()) {
+ // The second or the third operand (but not both) is a (possibly
+ // parenthesized) throw-expression; the result is of the [...] value
+ // category of the other.
+ bool TrueIsThrow = isa<CXXThrowExpr>(True->IgnoreParenImpCasts());
+ bool FalseIsThrow = isa<CXXThrowExpr>(False->IgnoreParenImpCasts());
+ if (const Expr *NonThrow = TrueIsThrow ? (FalseIsThrow ? 0 : False)
+ : (FalseIsThrow ? True : 0))
+ return ClassifyInternal(Ctx, NonThrow);
+
+ // [Otherwise] the result [...] is a prvalue.
return Cl::CL_PRValue;
+ }
// Note that at this point, we have already performed all conversions
// according to [expr.cond]p3.
OpenPOWER on IntegriCloud