justinstitt updated this revision to Diff 450872.
justinstitt edited the summary of this revision.
justinstitt added a reviewer: nickdesaulniers.
justinstitt added a comment.
- test adding reviewers
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D131416/new/
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits