Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -901,10 +901,16 @@ /// ConstantExpr - An expression that occurs in a constant context. class ConstantExpr : public FullExpr { -public: ConstantExpr(Expr *subexpr) : FullExpr(ConstantExprClass, subexpr) {} +public: + static ConstantExpr *Create(const ASTContext &Context, Expr *E) { + if (ConstantExpr *CE = dyn_cast(E)) + return CE; + return new (Context) ConstantExpr(E); + } + /// Build an empty constant expression wrapper. explicit ConstantExpr(EmptyShell Empty) : FullExpr(ConstantExprClass, Empty) {} @@ -3070,8 +3076,8 @@ while (true) if (ImplicitCastExpr *ice = dyn_cast(e)) e = ice->getSubExpr(); - else if (ConstantExpr *ce = dyn_cast(e)) - e = ce->getSubExpr(); + else if (FullExpr *fe = dyn_cast(e)) + e = fe->getSubExpr(); else break; return e; Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -6375,7 +6375,7 @@ Expr *ToSubExpr; std::tie(ToSubExpr) = *Imp; - return new (Importer.getToContext()) ConstantExpr(ToSubExpr); + return ConstantExpr::Create(Importer.getToContext(), ToSubExpr); } ExpectedStmt ASTNodeImporter::VisitParenExpr(ParenExpr *E) { Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -2585,8 +2585,8 @@ E = NTTP->getReplacement(); continue; } - if (ConstantExpr *CE = dyn_cast(E)) { - E = CE->getSubExpr(); + if (FullExpr *FE = dyn_cast(E)) { + E = FE->getSubExpr(); continue; } return E; @@ -2610,8 +2610,8 @@ E = NTTP->getReplacement(); continue; } - if (ConstantExpr *CE = dyn_cast(E)) { - E = CE->getSubExpr(); + if (FullExpr *FE = dyn_cast(E)) { + E = FE->getSubExpr(); continue; } return E; @@ -2639,8 +2639,8 @@ = dyn_cast(E)) { E = NTTP->getReplacement(); continue; - } else if (ConstantExpr *CE = dyn_cast(E)) { - E = CE->getSubExpr(); + } else if (FullExpr *FE = dyn_cast(E)) { + E = FE->getSubExpr(); continue; } break; @@ -2683,8 +2683,8 @@ E = NTTP->getReplacement(); continue; } - if (ConstantExpr *CE = dyn_cast(E)) { - E = CE->getSubExpr(); + if (FullExpr *FE = dyn_cast(E)) { + E = FE->getSubExpr(); continue; } return E; @@ -2911,6 +2911,10 @@ break; } + case ConstantExprClass: { + const Expr *Exp = cast(this)->getSubExpr(); + return Exp->isConstantInitializer(Ctx, false, Culprit); + } case CompoundLiteralExprClass: { // This handles gcc's extension that allows global initializers like // "struct x {int x;} x = (struct x) {};". Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -45,6 +45,7 @@ #include "clang/AST/TypeLoc.h" #include "clang/Basic/Builtins.h" #include "clang/Basic/TargetInfo.h" +#include "llvm/Support/SaveAndRestore.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -721,6 +722,10 @@ /// Whether or not we're currently speculatively evaluating. bool IsSpeculativelyEvaluating; + /// Whether or not we're in a context where the front end requires a + /// constant value. + bool InConstantContext; + enum EvaluationMode { /// Evaluate as a constant expression. Stop if we find that the expression /// is not a constant expression. @@ -782,7 +787,7 @@ EvaluatingDecl((const ValueDecl *)nullptr), EvaluatingDeclValue(nullptr), HasActiveDiagnostic(false), HasFoldFailureDiagnostic(false), IsSpeculativelyEvaluating(false), - EvalMode(Mode) {} + InConstantContext(false), EvalMode(Mode) {} void setEvaluatingDecl(APValue::LValueBase Base, APValue &Value) { EvaluatingDecl = Base; @@ -7347,6 +7352,8 @@ // Visitor Methods //===--------------------------------------------------------------------===// + bool VisitConstantExpr(const ConstantExpr *E); + bool VisitIntegerLiteral(const IntegerLiteral *E) { return Success(E->getValue(), E); } @@ -8087,6 +8094,11 @@ return true; } +bool IntExprEvaluator::VisitConstantExpr(const ConstantExpr *E) { + llvm::SaveAndRestore InConstantContext(Info.InConstantContext, true); + return ExprEvaluatorBaseTy::VisitConstantExpr(E); +} + bool IntExprEvaluator::VisitCallExpr(const CallExpr *E) { if (unsigned BuiltinOp = E->getBuiltinCallee()) return VisitBuiltinCallExpr(E, BuiltinOp); @@ -8174,8 +8186,20 @@ return Success(Val.countLeadingZeros(), E); } - case Builtin::BI__builtin_constant_p: - return Success(EvaluateBuiltinConstantP(Info.Ctx, E->getArg(0)), E); + case Builtin::BI__builtin_constant_p: { + auto Arg = E->getArg(0); + if (EvaluateBuiltinConstantP(Info.Ctx, Arg)) + return Success(true, E); + auto ArgTy = Arg->IgnoreImplicit()->getType(); + if (!Info.InConstantContext && !Arg->HasSideEffects(Info.Ctx) && + !ArgTy->isAggregateType() && !ArgTy->isPointerType()) { + // We can delay calculation of __builtin_constant_p until after + // inlining. Note: This diagnostic won't be shown to the user. + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); + return false; + } + return Success(false, E); + } case Builtin::BI__builtin_ctz: case Builtin::BI__builtin_ctzl: @@ -10956,401 +10980,378 @@ static ICEDiag Worst(ICEDiag A, ICEDiag B) { return A.Kind >= B.Kind ? A : B; } -static ICEDiag CheckEvalInICE(const Expr* E, const ASTContext &Ctx) { +static ICEDiag CheckEvalInICE(const Expr *E, const ASTContext &Ctx, + EvalInfo &Info) { Expr::EvalResult EVResult; - if (!E->EvaluateAsRValue(EVResult, Ctx) || EVResult.HasSideEffects || + if (!::EvaluateAsRValue(Info, E, EVResult.Val) || EVResult.HasSideEffects || !EVResult.Val.isInt()) return ICEDiag(IK_NotICE, E->getBeginLoc()); return NoDiag(); } +class ICEChecker + : public ConstStmtVisitor { + const ASTContext &Ctx; + EvalInfo &Info; + + typedef ConstStmtVisitor StmtVisitorTy; + +public: + ICEChecker(const ASTContext &Ctx, EvalInfo &Info) + : Ctx(Ctx), Info(Info) {} + + ICEDiag VisitStmt(const Stmt *S) { + return ICEDiag(IK_NotICE, S->getBeginLoc()); + } + + ICEDiag VisitExpr(const Expr *E); + ICEDiag VisitConstantExpr(const ConstantExpr *E); + ICEDiag VisitInitListExpr(const InitListExpr *E); + ICEDiag VisitSubstNonTypeTemplateParmExpr( + const SubstNonTypeTemplateParmExpr *E); + ICEDiag VisitParenExpr(const ParenExpr *E); + ICEDiag VisitGenericSelectionExpr(const GenericSelectionExpr *E); + ICEDiag VisitCallExpr(const CallExpr *E); + ICEDiag VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E); + ICEDiag VisitDeclRefExpr(const DeclRefExpr *E); + ICEDiag VisitBinaryOperator(const BinaryOperator *E); + ICEDiag VisitUnaryOperator(const UnaryOperator *E); + ICEDiag VisitOffsetOfExpr(const OffsetOfExpr *E); + ICEDiag VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E); + ICEDiag VisitCastExpr(const CastExpr *E); + ICEDiag VisitBinaryConditionalOperator(const BinaryConditionalOperator *E); + ICEDiag VisitConditionalOperator(const ConditionalOperator *E); + ICEDiag VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E); + ICEDiag VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E); + ICEDiag VisitChooseExpr(const ChooseExpr *E); +}; + +ICEDiag ICEChecker::VisitExpr(const Expr *E) { + switch (E->getStmtClass()) { + default: + return ICEDiag(IK_NotICE, E->getBeginLoc()); + case Expr::ArrayTypeTraitExprClass: + case Expr::CharacterLiteralClass: + case Expr::CXXBoolLiteralExprClass: + case Expr::CXXNoexceptExprClass: + case Expr::CXXScalarValueInitExprClass: + case Expr::ExpressionTraitExprClass: + case Expr::FixedPointLiteralClass: + case Expr::GNUNullExprClass: + // GCC considers the GNU __null value to be an integral constant expression. + case Expr::IntegerLiteralClass: + case Expr::ObjCBoolLiteralExprClass: + case Expr::SizeOfPackExprClass: + case Expr::TypeTraitExprClass: + return NoDiag(); + } +} + +ICEDiag ICEChecker::VisitConstantExpr(const ConstantExpr *E) { + llvm::SaveAndRestore InConstantContext(Info.InConstantContext, true); + return StmtVisitorTy::Visit(E->getSubExpr()); +} + +ICEDiag ICEChecker::VisitInitListExpr(const InitListExpr *E) { + // C++03 [dcl.init]p13: If T is a scalar type, then a declaration of the form + // "T x = { a };" is equivalent to "T x = a;". + // Unless we're initializing a reference, T is a scalar as it is known to be + // of integral or enumeration type. + if (E->isRValue()) + if (E->getNumInits() == 1) + return StmtVisitorTy::Visit(E->getInit(0)); + return ICEDiag(IK_NotICE, E->getBeginLoc()); +} + +ICEDiag ICEChecker::VisitSubstNonTypeTemplateParmExpr( + const SubstNonTypeTemplateParmExpr *E) { + return StmtVisitorTy::Visit(E->getReplacement()); +} + +ICEDiag ICEChecker::VisitParenExpr(const ParenExpr *E) { + return StmtVisitorTy::Visit(E->getSubExpr()); +} + +ICEDiag ICEChecker::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { + return StmtVisitorTy::Visit(E->getResultExpr()); +} + +ICEDiag ICEChecker::VisitCallExpr(const CallExpr *E) { + // C99 6.6/3 allows function calls within unevaluated subexpressions of + // constant expressions, but they can never be ICEs because an ICE cannot + // contain an operand of (pointer to) function type. + if (E->getBuiltinCallee()) + return CheckEvalInICE(E, Ctx, Info); + return ICEDiag(IK_NotICE, E->getBeginLoc()); +} + +ICEDiag ICEChecker::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E) { + return VisitCallExpr(E); +} + +ICEDiag ICEChecker::VisitDeclRefExpr(const DeclRefExpr *E) { + if (isa(E->getDecl())) + return NoDiag(); + + const ValueDecl *D = E->getDecl(); + if (Ctx.getLangOpts().CPlusPlus && + D && IsConstNonVolatile(D->getType())) { + // Parameter variables are never constants. Without this check, + // getAnyInitializer() can find a default argument, which leads + // to chaos. + if (isa(D)) + return ICEDiag(IK_NotICE, E->getLocation()); + + // C++ 7.1.5.1p2 + // A variable of non-volatile const-qualified integral or enumeration + // type initialized by an ICE can be used in ICEs. + if (const VarDecl *Dcl = dyn_cast(D)) { + if (!Dcl->getType()->isIntegralOrEnumerationType()) + return ICEDiag(IK_NotICE, E->getLocation()); + + const VarDecl *VD; + // Look for a declaration of this variable that has an initializer, and + // check whether it is an ICE. + if (Dcl->getAnyInitializer(VD) && VD->checkInitIsICE()) + return NoDiag(); + else + return ICEDiag(IK_NotICE, E->getLocation()); + } + } + return ICEDiag(IK_NotICE, E->getBeginLoc()); +} + +ICEDiag ICEChecker::VisitUnaryOperator(const UnaryOperator *E) { + switch (E->getOpcode()) { + case UO_PostInc: + case UO_PostDec: + case UO_PreInc: + case UO_PreDec: + case UO_AddrOf: + case UO_Deref: + case UO_Coawait: + // C99 6.6/3 allows increment and decrement within unevaluated + // subexpressions of constant expressions, but they can never be ICEs + // because an ICE cannot contain an lvalue operand. + return ICEDiag(IK_NotICE, E->getBeginLoc()); + + case UO_Extension: + case UO_LNot: + case UO_Plus: + case UO_Minus: + case UO_Not: + case UO_Real: + case UO_Imag: + return StmtVisitorTy::Visit(E->getSubExpr()); + } + llvm_unreachable("invalid unary operator class"); +} + +ICEDiag ICEChecker::VisitBinaryOperator(const BinaryOperator *E) { + switch (E->getOpcode()) { + case BO_PtrMemD: + case BO_PtrMemI: + case BO_Assign: + case BO_MulAssign: + case BO_DivAssign: + case BO_RemAssign: + case BO_AddAssign: + case BO_SubAssign: + case BO_ShlAssign: + case BO_ShrAssign: + case BO_AndAssign: + case BO_XorAssign: + case BO_OrAssign: + // 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. + return ICEDiag(IK_NotICE, E->getBeginLoc()); + + case BO_Mul: + case BO_Div: + case BO_Rem: + case BO_Add: + case BO_Sub: + case BO_Shl: + case BO_Shr: + case BO_LT: + case BO_GT: + case BO_LE: + case BO_GE: + case BO_EQ: + case BO_NE: + case BO_And: + case BO_Xor: + case BO_Or: + case BO_Comma: + case BO_Cmp: { + ICEDiag LHSResult = StmtVisitorTy::Visit(E->getLHS()); + ICEDiag RHSResult = StmtVisitorTy::Visit(E->getRHS()); + if (E->getOpcode() == BO_Div || + E->getOpcode() == BO_Rem) { + // EvaluateAsRValue gives an error for undefined Div/Rem, so make sure + // we don't evaluate one. + if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) { + llvm::APSInt REval = E->getRHS()->EvaluateKnownConstInt(Ctx); + if (REval == 0) + return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc()); + if (REval.isSigned() && REval.isAllOnesValue()) { + llvm::APSInt LEval = E->getLHS()->EvaluateKnownConstInt(Ctx); + if (LEval.isMinSignedValue()) + return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc()); + } + } + } + if (E->getOpcode() == BO_Comma) { + 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) + return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc()); + } else { + // In both C89 and C++, commas in ICEs are illegal. + return ICEDiag(IK_NotICE, E->getBeginLoc()); + } + } + return Worst(LHSResult, RHSResult); + } + case BO_LAnd: + case BO_LOr: { + ICEDiag LHSResult = StmtVisitorTy::Visit(E->getLHS()); + ICEDiag RHSResult = StmtVisitorTy::Visit(E->getRHS()); + if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) { + // Rare case where the RHS has a comma "side-effect"; we need + // to actually check the condition to see whether the side + // with the comma is evaluated. + if ((E->getOpcode() == BO_LAnd) != + (E->getLHS()->EvaluateKnownConstInt(Ctx) == 0)) + return RHSResult; + return NoDiag(); + } + + return Worst(LHSResult, RHSResult); + } + } + llvm_unreachable("invalid binary operator kind"); +} + +ICEDiag ICEChecker::VisitOffsetOfExpr(const OffsetOfExpr *E) { + // Note that per C99, offsetof must be an ICE. And AFAIK, using + // EvaluateAsRValue matches the proposed gcc behavior for cases like + // "offsetof(struct s{int x[4];}, x[1.0])". This doesn't affect compliance: + // we should warn earlier for offsetof expressions with array subscripts that + // aren't ICEs, and if the array subscripts are ICEs, the value of the + // offsetof must be an integer constant. + return CheckEvalInICE(E, Ctx, Info); +} + +ICEDiag ICEChecker::VisitUnaryExprOrTypeTraitExpr( + const UnaryExprOrTypeTraitExpr *E) { + if (E->getKind() == UETT_SizeOf && + E->getTypeOfArgument()->isVariableArrayType()) + return ICEDiag(IK_NotICE, E->getBeginLoc()); + return NoDiag(); +} + +ICEDiag ICEChecker::VisitCastExpr(const CastExpr *E) { + const Expr *SubExpr = E->getSubExpr(); + if (isa(E)) { + if (const FloatingLiteral *FL + = dyn_cast(SubExpr->IgnoreParenImpCasts())) { + unsigned DestWidth = Ctx.getIntWidth(E->getType()); + bool DestSigned = E->getType()->isSignedIntegerOrEnumerationType(); + APSInt IgnoredVal(DestWidth, !DestSigned); + bool Ignored; + // If the value does not fit in the destination type, the behavior is + // undefined, so we are not required to treat it as a constant + // expression. + if (FL->getValue().convertToInteger(IgnoredVal, + llvm::APFloat::rmTowardZero, + &Ignored) & APFloat::opInvalidOp) + return ICEDiag(IK_NotICE, E->getBeginLoc()); + return NoDiag(); + } + } + switch (E->getCastKind()) { + default: + return ICEDiag(IK_NotICE, E->getBeginLoc()); + case CK_LValueToRValue: + case CK_AtomicToNonAtomic: + case CK_NonAtomicToAtomic: + case CK_NoOp: + case CK_IntegralToBoolean: + case CK_IntegralCast: + return StmtVisitorTy::Visit(SubExpr); + } +} + +ICEDiag ICEChecker::VisitBinaryConditionalOperator( + const BinaryConditionalOperator *E) { + ICEDiag CommonResult = StmtVisitorTy::Visit(E->getCommon()); + if (CommonResult.Kind == IK_NotICE) return CommonResult; + ICEDiag FalseResult = StmtVisitorTy::Visit(E->getFalseExpr()); + if (FalseResult.Kind == IK_NotICE) return FalseResult; + if (CommonResult.Kind == IK_ICEIfUnevaluated) return CommonResult; + if (FalseResult.Kind == IK_ICEIfUnevaluated && + E->getCommon()->EvaluateKnownConstInt(Ctx) != 0) return NoDiag(); + return FalseResult; +} + +ICEDiag ICEChecker::VisitConditionalOperator(const ConditionalOperator *E) { + // If the condition (ignoring parens) is a __builtin_constant_p call, + // then only the true side is actually considered in an integer constant + // expression, and it is fully evaluated. This is an important GNU + // extension. See GCC PR38377 for discussion. + if (const CallExpr *CallCE + = dyn_cast(E->getCond()->IgnoreParenCasts())) + if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) + return CheckEvalInICE(E, Ctx, Info); + ICEDiag CondResult = StmtVisitorTy::Visit(E->getCond()); + if (CondResult.Kind == IK_NotICE) + return CondResult; + + ICEDiag TrueResult = StmtVisitorTy::Visit(E->getTrueExpr()); + ICEDiag FalseResult = StmtVisitorTy::Visit(E->getFalseExpr()); + + if (TrueResult.Kind == IK_NotICE) + return TrueResult; + if (FalseResult.Kind == IK_NotICE) + return FalseResult; + if (CondResult.Kind == IK_ICEIfUnevaluated) + return CondResult; + if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE) + return NoDiag(); + // Rare case where the diagnostics depend on which side is evaluated + // Note that if we get here, CondResult is 0, and at least one of + // TrueResult and FalseResult is non-zero. + if (E->getCond()->EvaluateKnownConstInt(Ctx) == 0) + return FalseResult; + return TrueResult; +} + +ICEDiag ICEChecker::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { + return StmtVisitorTy::Visit(E->getExpr()); +} + +ICEDiag ICEChecker::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *E) { + return StmtVisitorTy::Visit(E->getExpr()); +} + +ICEDiag ICEChecker::VisitChooseExpr(const ChooseExpr *E) { + return StmtVisitorTy::Visit(E->getChosenSubExpr()); +} + static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) { assert(!E->isValueDependent() && "Should not see value dependent exprs!"); if (!E->getType()->isIntegralOrEnumerationType()) return ICEDiag(IK_NotICE, E->getBeginLoc()); - switch (E->getStmtClass()) { -#define ABSTRACT_STMT(Node) -#define STMT(Node, Base) case Expr::Node##Class: -#define EXPR(Node, Base) -#include "clang/AST/StmtNodes.inc" - case Expr::PredefinedExprClass: - case Expr::FloatingLiteralClass: - case Expr::ImaginaryLiteralClass: - case Expr::StringLiteralClass: - case Expr::ArraySubscriptExprClass: - case Expr::OMPArraySectionExprClass: - case Expr::MemberExprClass: - case Expr::CompoundAssignOperatorClass: - case Expr::CompoundLiteralExprClass: - case Expr::ExtVectorElementExprClass: - case Expr::DesignatedInitExprClass: - case Expr::ArrayInitLoopExprClass: - case Expr::ArrayInitIndexExprClass: - case Expr::NoInitExprClass: - case Expr::DesignatedInitUpdateExprClass: - case Expr::ImplicitValueInitExprClass: - case Expr::ParenListExprClass: - case Expr::VAArgExprClass: - case Expr::AddrLabelExprClass: - case Expr::StmtExprClass: - case Expr::CXXMemberCallExprClass: - case Expr::CUDAKernelCallExprClass: - case Expr::CXXDynamicCastExprClass: - case Expr::CXXTypeidExprClass: - case Expr::CXXUuidofExprClass: - case Expr::MSPropertyRefExprClass: - case Expr::MSPropertySubscriptExprClass: - case Expr::CXXNullPtrLiteralExprClass: - case Expr::UserDefinedLiteralClass: - case Expr::CXXThisExprClass: - case Expr::CXXThrowExprClass: - case Expr::CXXNewExprClass: - case Expr::CXXDeleteExprClass: - case Expr::CXXPseudoDestructorExprClass: - case Expr::UnresolvedLookupExprClass: - case Expr::TypoExprClass: - case Expr::DependentScopeDeclRefExprClass: - case Expr::CXXConstructExprClass: - case Expr::CXXInheritedCtorInitExprClass: - case Expr::CXXStdInitializerListExprClass: - case Expr::CXXBindTemporaryExprClass: - case Expr::ExprWithCleanupsClass: - case Expr::CXXTemporaryObjectExprClass: - case Expr::CXXUnresolvedConstructExprClass: - case Expr::CXXDependentScopeMemberExprClass: - case Expr::UnresolvedMemberExprClass: - case Expr::ObjCStringLiteralClass: - case Expr::ObjCBoxedExprClass: - case Expr::ObjCArrayLiteralClass: - case Expr::ObjCDictionaryLiteralClass: - case Expr::ObjCEncodeExprClass: - case Expr::ObjCMessageExprClass: - case Expr::ObjCSelectorExprClass: - case Expr::ObjCProtocolExprClass: - case Expr::ObjCIvarRefExprClass: - case Expr::ObjCPropertyRefExprClass: - case Expr::ObjCSubscriptRefExprClass: - case Expr::ObjCIsaExprClass: - case Expr::ObjCAvailabilityCheckExprClass: - case Expr::ShuffleVectorExprClass: - case Expr::ConvertVectorExprClass: - case Expr::BlockExprClass: - case Expr::NoStmtClass: - case Expr::OpaqueValueExprClass: - case Expr::PackExpansionExprClass: - case Expr::SubstNonTypeTemplateParmPackExprClass: - case Expr::FunctionParmPackExprClass: - case Expr::AsTypeExprClass: - case Expr::ObjCIndirectCopyRestoreExprClass: - case Expr::MaterializeTemporaryExprClass: - case Expr::PseudoObjectExprClass: - case Expr::AtomicExprClass: - case Expr::LambdaExprClass: - case Expr::CXXFoldExprClass: - case Expr::CoawaitExprClass: - case Expr::DependentCoawaitExprClass: - case Expr::CoyieldExprClass: - return ICEDiag(IK_NotICE, E->getBeginLoc()); - - case Expr::InitListExprClass: { - // C++03 [dcl.init]p13: If T is a scalar type, then a declaration of the - // form "T x = { a };" is equivalent to "T x = a;". - // Unless we're initializing a reference, T is a scalar as it is known to be - // of integral or enumeration type. - if (E->isRValue()) - if (cast(E)->getNumInits() == 1) - return CheckICE(cast(E)->getInit(0), Ctx); - return ICEDiag(IK_NotICE, E->getBeginLoc()); - } - - case Expr::SizeOfPackExprClass: - case Expr::GNUNullExprClass: - // GCC considers the GNU __null value to be an integral constant expression. - return NoDiag(); - - case Expr::SubstNonTypeTemplateParmExprClass: - return - CheckICE(cast(E)->getReplacement(), Ctx); - - case Expr::ConstantExprClass: - return CheckICE(cast(E)->getSubExpr(), Ctx); - - case Expr::ParenExprClass: - return CheckICE(cast(E)->getSubExpr(), Ctx); - case Expr::GenericSelectionExprClass: - return CheckICE(cast(E)->getResultExpr(), Ctx); - case Expr::IntegerLiteralClass: - case Expr::FixedPointLiteralClass: - case Expr::CharacterLiteralClass: - case Expr::ObjCBoolLiteralExprClass: - case Expr::CXXBoolLiteralExprClass: - case Expr::CXXScalarValueInitExprClass: - case Expr::TypeTraitExprClass: - case Expr::ArrayTypeTraitExprClass: - case Expr::ExpressionTraitExprClass: - case Expr::CXXNoexceptExprClass: - return NoDiag(); - case Expr::CallExprClass: - case Expr::CXXOperatorCallExprClass: { - // C99 6.6/3 allows function calls within unevaluated subexpressions of - // constant expressions, but they can never be ICEs because an ICE cannot - // contain an operand of (pointer to) function type. - const CallExpr *CE = cast(E); - if (CE->getBuiltinCallee()) - return CheckEvalInICE(E, Ctx); - return ICEDiag(IK_NotICE, E->getBeginLoc()); - } - case Expr::DeclRefExprClass: { - if (isa(cast(E)->getDecl())) - return NoDiag(); - const ValueDecl *D = cast(E)->getDecl(); - if (Ctx.getLangOpts().CPlusPlus && - D && IsConstNonVolatile(D->getType())) { - // Parameter variables are never constants. Without this check, - // getAnyInitializer() can find a default argument, which leads - // to chaos. - if (isa(D)) - return ICEDiag(IK_NotICE, cast(E)->getLocation()); - - // C++ 7.1.5.1p2 - // A variable of non-volatile const-qualified integral or enumeration - // type initialized by an ICE can be used in ICEs. - if (const VarDecl *Dcl = dyn_cast(D)) { - if (!Dcl->getType()->isIntegralOrEnumerationType()) - return ICEDiag(IK_NotICE, cast(E)->getLocation()); - - const VarDecl *VD; - // Look for a declaration of this variable that has an initializer, and - // check whether it is an ICE. - if (Dcl->getAnyInitializer(VD) && VD->checkInitIsICE()) - return NoDiag(); - else - return ICEDiag(IK_NotICE, cast(E)->getLocation()); - } - } - return ICEDiag(IK_NotICE, E->getBeginLoc()); - } - case Expr::UnaryOperatorClass: { - const UnaryOperator *Exp = cast(E); - switch (Exp->getOpcode()) { - case UO_PostInc: - case UO_PostDec: - case UO_PreInc: - case UO_PreDec: - case UO_AddrOf: - case UO_Deref: - case UO_Coawait: - // C99 6.6/3 allows increment and decrement within unevaluated - // subexpressions of constant expressions, but they can never be ICEs - // because an ICE cannot contain an lvalue operand. - return ICEDiag(IK_NotICE, E->getBeginLoc()); - case UO_Extension: - case UO_LNot: - case UO_Plus: - case UO_Minus: - case UO_Not: - case UO_Real: - case UO_Imag: - return CheckICE(Exp->getSubExpr(), Ctx); - } - llvm_unreachable("invalid unary operator class"); - } - case Expr::OffsetOfExprClass: { - // Note that per C99, offsetof must be an ICE. And AFAIK, using - // EvaluateAsRValue matches the proposed gcc behavior for cases like - // "offsetof(struct s{int x[4];}, x[1.0])". This doesn't affect - // compliance: we should warn earlier for offsetof expressions with - // array subscripts that aren't ICEs, and if the array subscripts - // are ICEs, the value of the offsetof must be an integer constant. - return CheckEvalInICE(E, Ctx); - } - case Expr::UnaryExprOrTypeTraitExprClass: { - const UnaryExprOrTypeTraitExpr *Exp = cast(E); - if ((Exp->getKind() == UETT_SizeOf) && - Exp->getTypeOfArgument()->isVariableArrayType()) - return ICEDiag(IK_NotICE, E->getBeginLoc()); - return NoDiag(); - } - case Expr::BinaryOperatorClass: { - const BinaryOperator *Exp = cast(E); - switch (Exp->getOpcode()) { - case BO_PtrMemD: - case BO_PtrMemI: - case BO_Assign: - case BO_MulAssign: - case BO_DivAssign: - case BO_RemAssign: - case BO_AddAssign: - case BO_SubAssign: - case BO_ShlAssign: - case BO_ShrAssign: - case BO_AndAssign: - case BO_XorAssign: - case BO_OrAssign: - // 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. - return ICEDiag(IK_NotICE, E->getBeginLoc()); - - case BO_Mul: - case BO_Div: - case BO_Rem: - case BO_Add: - case BO_Sub: - case BO_Shl: - case BO_Shr: - case BO_LT: - case BO_GT: - case BO_LE: - case BO_GE: - case BO_EQ: - case BO_NE: - case BO_And: - case BO_Xor: - case BO_Or: - case BO_Comma: - case BO_Cmp: { - ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); - ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); - if (Exp->getOpcode() == BO_Div || - Exp->getOpcode() == BO_Rem) { - // EvaluateAsRValue gives an error for undefined Div/Rem, so make sure - // we don't evaluate one. - if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICE) { - llvm::APSInt REval = Exp->getRHS()->EvaluateKnownConstInt(Ctx); - if (REval == 0) - return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc()); - if (REval.isSigned() && REval.isAllOnesValue()) { - llvm::APSInt LEval = Exp->getLHS()->EvaluateKnownConstInt(Ctx); - if (LEval.isMinSignedValue()) - return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc()); - } - } - } - if (Exp->getOpcode() == BO_Comma) { - 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) - return ICEDiag(IK_ICEIfUnevaluated, E->getBeginLoc()); - } else { - // In both C89 and C++, commas in ICEs are illegal. - return ICEDiag(IK_NotICE, E->getBeginLoc()); - } - } - return Worst(LHSResult, RHSResult); - } - case BO_LAnd: - case BO_LOr: { - ICEDiag LHSResult = CheckICE(Exp->getLHS(), Ctx); - ICEDiag RHSResult = CheckICE(Exp->getRHS(), Ctx); - if (LHSResult.Kind == IK_ICE && RHSResult.Kind == IK_ICEIfUnevaluated) { - // Rare case where the RHS has a comma "side-effect"; we need - // 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)) - return RHSResult; - return NoDiag(); - } - - return Worst(LHSResult, RHSResult); - } - } - llvm_unreachable("invalid binary operator kind"); - } - case Expr::ImplicitCastExprClass: - case Expr::CStyleCastExprClass: - case Expr::CXXFunctionalCastExprClass: - case Expr::CXXStaticCastExprClass: - case Expr::CXXReinterpretCastExprClass: - case Expr::CXXConstCastExprClass: - case Expr::ObjCBridgedCastExprClass: { - const Expr *SubExpr = cast(E)->getSubExpr(); - if (isa(E)) { - if (const FloatingLiteral *FL - = dyn_cast(SubExpr->IgnoreParenImpCasts())) { - unsigned DestWidth = Ctx.getIntWidth(E->getType()); - bool DestSigned = E->getType()->isSignedIntegerOrEnumerationType(); - APSInt IgnoredVal(DestWidth, !DestSigned); - bool Ignored; - // If the value does not fit in the destination type, the behavior is - // undefined, so we are not required to treat it as a constant - // expression. - if (FL->getValue().convertToInteger(IgnoredVal, - llvm::APFloat::rmTowardZero, - &Ignored) & APFloat::opInvalidOp) - return ICEDiag(IK_NotICE, E->getBeginLoc()); - return NoDiag(); - } - } - switch (cast(E)->getCastKind()) { - case CK_LValueToRValue: - case CK_AtomicToNonAtomic: - case CK_NonAtomicToAtomic: - case CK_NoOp: - case CK_IntegralToBoolean: - case CK_IntegralCast: - return CheckICE(SubExpr, Ctx); - default: - return ICEDiag(IK_NotICE, E->getBeginLoc()); - } - } - case Expr::BinaryConditionalOperatorClass: { - const BinaryConditionalOperator *Exp = cast(E); - ICEDiag CommonResult = CheckICE(Exp->getCommon(), Ctx); - if (CommonResult.Kind == IK_NotICE) return CommonResult; - ICEDiag FalseResult = CheckICE(Exp->getFalseExpr(), Ctx); - if (FalseResult.Kind == IK_NotICE) return FalseResult; - if (CommonResult.Kind == IK_ICEIfUnevaluated) return CommonResult; - if (FalseResult.Kind == IK_ICEIfUnevaluated && - Exp->getCommon()->EvaluateKnownConstInt(Ctx) != 0) return NoDiag(); - return FalseResult; - } - case Expr::ConditionalOperatorClass: { - const ConditionalOperator *Exp = cast(E); - // If the condition (ignoring parens) is a __builtin_constant_p call, - // then only the true side is actually considered in an integer constant - // expression, and it is fully evaluated. This is an important GNU - // extension. See GCC PR38377 for discussion. - if (const CallExpr *CallCE - = dyn_cast(Exp->getCond()->IgnoreParenCasts())) - if (CallCE->getBuiltinCallee() == Builtin::BI__builtin_constant_p) - return CheckEvalInICE(E, Ctx); - ICEDiag CondResult = CheckICE(Exp->getCond(), Ctx); - if (CondResult.Kind == IK_NotICE) - return CondResult; - - ICEDiag TrueResult = CheckICE(Exp->getTrueExpr(), Ctx); - ICEDiag FalseResult = CheckICE(Exp->getFalseExpr(), Ctx); - - if (TrueResult.Kind == IK_NotICE) - return TrueResult; - if (FalseResult.Kind == IK_NotICE) - return FalseResult; - if (CondResult.Kind == IK_ICEIfUnevaluated) - return CondResult; - if (TrueResult.Kind == IK_ICE && FalseResult.Kind == IK_ICE) - return NoDiag(); - // Rare case where the diagnostics depend on which side is evaluated - // Note that if we get here, CondResult is 0, and at least one of - // TrueResult and FalseResult is non-zero. - if (Exp->getCond()->EvaluateKnownConstInt(Ctx) == 0) - return FalseResult; - return TrueResult; - } - case Expr::CXXDefaultArgExprClass: - return CheckICE(cast(E)->getExpr(), Ctx); - case Expr::CXXDefaultInitExprClass: - return CheckICE(cast(E)->getExpr(), Ctx); - case Expr::ChooseExprClass: { - return CheckICE(cast(E)->getChosenSubExpr(), Ctx); - } - } - - llvm_unreachable("Invalid StmtClass!"); + Expr::EvalStatus Status; + SmallVector Diags; + Status.Diag = &Diags; + EvalInfo Info(Ctx, Status, EvalInfo::EM_ConstantExpression); + return ICEChecker(Ctx, Info).Visit(E); } /// Evaluate an expression as a C++11 integral constant expression. Index: lib/CodeGen/CGBuiltin.cpp =================================================================== --- lib/CodeGen/CGBuiltin.cpp +++ lib/CodeGen/CGBuiltin.cpp @@ -1918,6 +1918,19 @@ case Builtin::BI__builtin_rotateright64: return emitRotate(E, true); + case Builtin::BI__builtin_constant_p: { + if (CGM.getCodeGenOpts().OptimizationLevel == 0) + // At -O0, we don't perform inlining, so we don't need to delay the + // processing. + return RValue::get(ConstantInt::get(Int32Ty, 0)); + if (auto *DRE = dyn_cast(E->getArg(0)->IgnoreImplicit())) + if (DRE->getType()->isAggregateType()) + return RValue::get(ConstantInt::get(Int32Ty, 0)); + Value *Arg = EmitScalarExpr(E->getArg(0)); + Value *F = CGM.getIntrinsic(Intrinsic::is_constant, Arg->getType()); + Value *Call = Builder.CreateCall(F, Arg); + return RValue::get(Builder.CreateZExtOrBitCast(Call, Int32Ty)); + } case Builtin::BI__builtin_object_size: { unsigned Type = E->getArg(1)->EvaluateKnownConstInt(getContext()).getZExtValue(); Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -13861,6 +13861,8 @@ ExprResult Converted = PerformContextuallyConvertToBool(AssertExpr); if (Converted.isInvalid()) Failed = true; + else + Converted = ConstantExpr::Create(Context, Converted.get()); llvm::APSInt Cond; if (!Failed && VerifyIntegerConstantExpression(Converted.get(), &Cond, Index: lib/Sema/SemaExpr.cpp =================================================================== --- lib/Sema/SemaExpr.cpp +++ lib/Sema/SemaExpr.cpp @@ -4899,6 +4899,14 @@ unsigned NumParams = Proto->getNumParams(); bool Invalid = false; size_t ArgIx = 0; + + unsigned ICEArguments = 0; + if (FDecl) + if (auto BuiltinID = FDecl->getBuiltinID()) { + ASTContext::GetBuiltinTypeError Error; + Context.GetBuiltinType(BuiltinID, Error, &ICEArguments); + } + // Continue to check argument types (even if we have too few/many args). for (unsigned i = FirstParam; i < NumParams; i++) { QualType ProtoArgType = Proto->getParamType(i); @@ -4962,6 +4970,9 @@ // Check for violations of C99 static array rules (C99 6.7.5.3p7). CheckStaticArrayArgument(CallLoc, Param, Arg); + if ((ICEArguments & (1 << (ArgIx - 1))) != 0) + Arg = ConstantExpr::Create(Context, Arg); + AllArgs.push_back(Arg); } @@ -5769,6 +5780,8 @@ ? VK_RValue : VK_LValue; + if (isFileScope) + LiteralExpr = ConstantExpr::Create(Context, LiteralExpr); Expr *E = new (Context) CompoundLiteralExpr(LParenLoc, TInfo, literalType, VK, LiteralExpr, isFileScope); if (isFileScope) { @@ -5777,7 +5790,6 @@ !literalType->isDependentType()) // C99 6.5.2.5p3 if (CheckForConstantInitializer(LiteralExpr, literalType)) return ExprError(); - E = new (Context) ConstantExpr(E); } else if (literalType.getAddressSpace() != LangAS::opencl_private && literalType.getAddressSpace() != LangAS::Default) { // Embedded-C extensions to C99 6.5.2.5: @@ -14141,12 +14153,15 @@ return ExprError(); } + if (!CurContext->isFunctionOrMethod()) + E = ConstantExpr::Create(Context, E); + // Circumvent ICE checking in C++11 to avoid evaluating the expression twice // in the non-ICE case. if (!getLangOpts().CPlusPlus11 && E->isIntegerConstantExpr(Context)) { if (Result) *Result = E->EvaluateKnownConstIntCheckOverflow(Context); - return new (Context) ConstantExpr(E); + return E; } Expr::EvalResult EvalResult; @@ -14164,7 +14179,7 @@ if (Folded && getLangOpts().CPlusPlus11 && Notes.empty()) { if (Result) *Result = EvalResult.Val.getInt(); - return new (Context) ConstantExpr(E); + return E; } // If our only note is the usual "invalid subexpression" note, just point @@ -14192,7 +14207,7 @@ if (Result) *Result = EvalResult.Val.getInt(); - return new (Context) ConstantExpr(E); + return E; } namespace { Index: lib/Sema/SemaOverload.cpp =================================================================== --- lib/Sema/SemaOverload.cpp +++ lib/Sema/SemaOverload.cpp @@ -5444,7 +5444,7 @@ if (Notes.empty()) { // It's a constant expression. - return new (S.Context) ConstantExpr(Result.get()); + return ConstantExpr::Create(S.Context, Result.get()); } } Index: lib/Sema/SemaTemplateDeduction.cpp =================================================================== --- lib/Sema/SemaTemplateDeduction.cpp +++ lib/Sema/SemaTemplateDeduction.cpp @@ -178,6 +178,8 @@ while (true) { if (ImplicitCastExpr *IC = dyn_cast(E)) E = IC->getSubExpr(); + else if (ConstantExpr *CE = dyn_cast(E)) + E = CE->getSubExpr(); else if (SubstNonTypeTemplateParmExpr *Subst = dyn_cast(E)) E = Subst->getReplacement(); @@ -5225,6 +5227,8 @@ while (true) { if (const ImplicitCastExpr *ICE = dyn_cast(E)) E = ICE->getSubExpr(); + else if (const ConstantExpr *CE = dyn_cast(E)) + E = CE->getSubExpr(); else if (const SubstNonTypeTemplateParmExpr *Subst = dyn_cast(E)) E = Subst->getReplacement(); Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -2233,10 +2233,6 @@ T = Context.getConstantArrayType(T, ConstVal, ASM, Quals); } - if (ArraySize && !CurContext->isFunctionOrMethod()) - // A file-scoped array must have a constant array size. - ArraySize = new (Context) ConstantExpr(ArraySize); - // OpenCL v1.2 s6.9.d: variable length arrays are not supported. if (getLangOpts().OpenCL && T->isVariableArrayType()) { Diag(Loc, diag::err_opencl_vla); Index: lib/StaticAnalyzer/Core/ExprEngine.cpp =================================================================== --- lib/StaticAnalyzer/Core/ExprEngine.cpp +++ lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1283,9 +1283,6 @@ break; case Expr::ConstantExprClass: - // Handled due to it being a wrapper class. - break; - case Stmt::ExprWithCleanupsClass: // Handled due to fully linearised CFG. break; Index: test/Analysis/builtin-functions.cpp =================================================================== --- test/Analysis/builtin-functions.cpp +++ test/Analysis/builtin-functions.cpp @@ -70,14 +70,14 @@ const int j = 2; constexpr int k = 3; clang_analyzer_eval(__builtin_constant_p(42) == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(j) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k) == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(i + 42) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(j + 42) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(k + 42) == 1); // expected-warning {{TRUE}} clang_analyzer_eval(__builtin_constant_p(" ") == 1); // expected-warning {{TRUE}} - clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{TRUE}} + clang_analyzer_eval(__builtin_constant_p(test_constant_p) == 0); // expected-warning {{UNKNOWN}} clang_analyzer_eval(__builtin_constant_p(k - 3) == 0); // expected-warning {{FALSE}} clang_analyzer_eval(__builtin_constant_p(k - 3) == 1); // expected-warning {{TRUE}} } Index: test/SemaCXX/compound-literal.cpp =================================================================== --- test/SemaCXX/compound-literal.cpp +++ test/SemaCXX/compound-literal.cpp @@ -36,8 +36,8 @@ POD p = (POD){1, 2}; // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD' - // CHECK: ConstantExpr {{.*}} 'brace_initializers::POD' - // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' + // CHECK: CompoundLiteralExpr {{.*}} 'brace_initializers::POD' + // CHECK-NEXT: ConstantExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: InitListExpr {{.*}} 'brace_initializers::POD' // CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}} // CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}