justinstitt created this revision.
Herald added a project: All.
justinstitt requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Signed-off-by: Justin Stitt <justinst...@google.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D131416

Files:
  clang/include/clang/AST/Expr.h
  clang/lib/AST/ExprConstant.cpp

Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -15283,27 +15283,6 @@
 // in the rare cases where CheckICE actually cares about the evaluated
 // value, it calls into Evaluate.
 
-namespace {
-
-enum ICEKind {
-  /// This expression is an ICE.
-  IK_ICE,
-  /// This expression is not an ICE, but if it isn't evaluated, it's
-  /// a legal subexpression for an ICE. This return value is used to handle
-  /// the comma operator in C99 mode, and non-constant subexpressions.
-  IK_ICEIfUnevaluated,
-  /// This expression is not an ICE, and is not a legal subexpression for one.
-  IK_NotICE
-};
-
-struct ICEDiag {
-  ICEKind Kind;
-  SourceLocation Loc;
-
-  ICEDiag(ICEKind IK, SourceLocation l) : Kind(IK), Loc(l) {}
-};
-
-}
 
 static ICEDiag NoDiag() { return ICEDiag(IK_ICE, SourceLocation()); }
 
@@ -15322,7 +15301,7 @@
   return NoDiag();
 }
 
-static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
+static ICEDiag CheckICE(Expr* E, const ASTContext &Ctx) {
   assert(!E->isValueDependent() && "Should not see value dependent exprs!");
   if (!E->getType()->isIntegralOrEnumerationType())
     return ICEDiag(IK_NotICE, E->getBeginLoc());
@@ -15533,7 +15512,9 @@
     return NoDiag();
   }
   case Expr::BinaryOperatorClass: {
-    const BinaryOperator *Exp = cast<BinaryOperator>(E);
+    BinaryOperator *Exp = cast<BinaryOperator>(E);
+    if (Exp->IK.has_value()) return ICEDiag(Exp->IK.value(), E->getBeginLoc());
+    /* if (Exp->IK != IK_NotYetEvaluated) return ICEDiag(Exp->IK, E->getBeginLoc()); */
     switch (Exp->getOpcode()) {
     case BO_PtrMemD:
     case BO_PtrMemI:
@@ -15551,6 +15532,7 @@
       // C99 6.6/3 allows assignments within unevaluated subexpressions of
       // constant expressions, but they can never be ICEs because an ICE cannot
       // contain an lvalue operand.
+      Exp->IK = IK_NotICE;
       return ICEDiag(IK_NotICE, E->getBeginLoc());
 
     case BO_Mul:
@@ -15579,12 +15561,16 @@
         // we don't evaluate one.
         if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
           llvm::APSInt REval = Exp->getRHS()->EvaluateKnownConstInt(Ctx);
-          if (REval == 0)
+          if (REval == 0) {
+            Exp->IK = IK_ICEIfUnevaluated;
             return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc());
+          }
           if (REval.isSigned() && REval.isAllOnes()) {
             llvm::APSInt LEval = Exp->getLHS()->EvaluateKnownConstInt(Ctx);
-            if (LEval.isMinSignedValue())
+            if (LEval.isMinSignedValue()) {
+              Exp->IK = IK_ICEIfUnevaluated;
               return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc());
+            }
           }
         }
       }
@@ -15592,14 +15578,19 @@
         if (Ctx.getLangOpts().C99) {
           // C99 6.6p3 introduces a strange edge case: comma can be in an ICE
           // if it isn't evaluated.
-          if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE)
+          if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) {
+            Exp->IK = IK_ICEIfUnevaluated;
             return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc());
+          }
         } else {
           // In both C89 and C++, commas in ICEs are illegal.
+          Exp->IK = IK_NotICE;
           return ICEDiag(IK_NotICE, E->getBeginLoc());
         }
       }
-      return Worst(LHSResult, RHSResult);
+      ICEDiag D = Worst(LHSResult, RHSResult);
+      Exp->IK = D.Kind; 
+      return D; 
     }
     case BO_LAnd:
     case BO_LOr: {
@@ -15610,12 +15601,16 @@
         // to actually check the condition to see whether the side
         // with the comma is evaluated.
         if ((Exp->getOpcode() == BO_LAnd) !=
-            (Exp->getLHS()->EvaluateKnownConstInt(Ctx) == 0))
+            (Exp->getLHS()->EvaluateKnownConstInt(Ctx) == 0)) {
+          Exp->IK = RHSResult.Kind;
           return RHSResult;
+        }
+        Exp->IK = IK_ICE;
         return NoDiag();
       }
-
-      return Worst(LHSResult, RHSResult);
+      ICEDiag WorstResult = Worst(LHSResult, RHSResult);
+      Exp->IK = WorstResult.Kind; 
+      return WorstResult; 
     }
     }
     llvm_unreachable("invalid binary operator kind");
@@ -15747,7 +15742,6 @@
 
   if (Ctx.getLangOpts().CPlusPlus11)
     return EvaluateCPlusPlus11IntegralConstantExpr(Ctx, this, nullptr, Loc);
-
   ICEDiag D = CheckICE(this, Ctx);
   if (D.Kind != IK_ICE) {
     if (Loc) *Loc = D.Loc;
Index: clang/include/clang/AST/Expr.h
===================================================================
--- clang/include/clang/AST/Expr.h
+++ clang/include/clang/AST/Expr.h
@@ -27,6 +27,7 @@
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/SyncScope.h"
 #include "clang/Basic/TypeTraits.h"
+#include "llvm/ADT/Optional.h"
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/SmallVector.h"
@@ -3804,12 +3805,37 @@
 /// value-dependent). If either x or y is type-dependent, or if the
 /// "+" resolves to an overloaded operator, CXXOperatorCallExpr will
 /// be used to express the computation.
+namespace {
+
+enum ICEKind {
+  /// This expression is an ICE.
+  IK_ICE,
+  /// This expression is not an ICE, but if it isn't evaluated, it's
+  /// a legal subexpression for an ICE. This return value is used to handle
+  /// the comma operator in C99 mode, and non-constant subexpressions.
+  IK_ICEIfUnevaluated,
+  /// This expression is not an ICE, and is not a legal subexpression for one.
+  IK_NotICE,
+};
+
+struct ICEDiag {
+  ICEKind Kind;
+  SourceLocation Loc;
+
+  ICEDiag(ICEKind IK, SourceLocation l) : Kind(IK), Loc(l) {}
+};
+
+}
+
 class BinaryOperator : public Expr {
   enum { LHS, RHS, END_EXPR };
   Stmt *SubExprs[END_EXPR];
 
 public:
   typedef BinaryOperatorKind Opcode;
+  /* ICEDiag Diag{IK_NotYetEvaluated, SourceLocation()}; */
+  llvm::Optional<enum ICEKind> IK;
+  /* ICEKind IK = IK_NotYetEvaluated; */
 
 protected:
   size_t offsetOfTrailingStorage() const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to