diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-05-24 16:02:01 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-05-24 16:02:01 +0000 |
commit | 63fe6814f339df30b8463b39995947cbdf920e48 (patch) | |
tree | b2787522290f73659cb391e785fca5d4526cd0a3 /lib/AST/ExprConstant.cpp | |
parent | 5b4e7b11e745329d8a55fd56504450dede1b2100 (diff) |
Implement the initial part of C++0x [expr.const]p2, which specifies
that the unevaluated subexpressions of &&, ||, and ? : are not
considered when determining whether the expression is a constant
expression. Also, turn the "used in its own initializer" warning into
a runtime-behavior warning, so that it doesn't fire when a variable is
used as part of an unevaluated subexpression of its own initializer.
Fixes PR9999.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@131968 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ExprConstant.cpp')
-rw-r--r-- | lib/AST/ExprConstant.cpp | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 1126289aee..1206fe7fb3 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -2957,6 +2957,21 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { case BO_LAnd: case BO_LOr: { ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); + + // C++0x [expr.const]p2: + // [...] subexpressions of logical AND (5.14), logical OR + // (5.15), and condi- tional (5.16) operations that are not + // evaluated are not considered. + if (Ctx.getLangOptions().CPlusPlus0x && LHSResult.Val == 0) { + if (Exp->getOpcode() == BO_LAnd && + Exp->getLHS()->EvaluateAsInt(Ctx) == 0) + return LHSResult; + + if (Exp->getOpcode() == BO_LOr && + Exp->getLHS()->EvaluateAsInt(Ctx) != 0) + return LHSResult; + } + ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); if (LHSResult.Val == 0 && RHSResult.Val == 1) { // Rare case where the RHS has a comma "side-effect"; we need @@ -3015,10 +3030,22 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) { return NoDiag(); } ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx); - ICEDiag TrueResult = CheckICE(Exp->getTrueExpr(), Ctx); - ICEDiag FalseResult = CheckICE(Exp->getFalseExpr(), Ctx); if (CondResult.Val == 2) return CondResult; + + // C++0x [expr.const]p2: + // subexpressions of [...] conditional (5.16) operations that + // are not evaluated are not considered + bool TrueBranch = Ctx.getLangOptions().CPlusPlus0x + ? Exp->getCond()->EvaluateAsInt(Ctx) != 0 + : false; + ICEDiag TrueResult = NoDiag(); + if (!Ctx.getLangOptions().CPlusPlus0x || TrueBranch) + TrueResult = CheckICE(Exp->getTrueExpr(), Ctx); + ICEDiag FalseResult = NoDiag(); + if (!Ctx.getLangOptions().CPlusPlus0x || !TrueBranch) + FalseResult = CheckICE(Exp->getFalseExpr(), Ctx); + if (TrueResult.Val == 2) return TrueResult; if (FalseResult.Val == 2) |