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
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 1126289..1206fe7 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -2957,6 +2957,21 @@
     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 @@
         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)