diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-27 04:19:56 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2014-01-27 04:19:56 +0000 |
commit | 6a6a4bbdd4230a3a4c5630888452940a0006d546 (patch) | |
tree | ef18778ccc28c7d552a68e78606d2f83261ea717 /clang/lib/AST/ExprClassification.cpp | |
parent | 3bb1de7885fd065668d3eeecd73c91157286fcd6 (diff) | |
download | bcm5719-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.cpp | 17 |
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. |