diff options
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 214 |
1 files changed, 112 insertions, 102 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 48c0695a1da..b21577e1a04 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -562,12 +562,12 @@ namespace { return false; if (NextCallIndex == 0) { // NextCallIndex has wrapped around. - Diag(Loc, diag::note_constexpr_call_limit_exceeded); + FFDiag(Loc, diag::note_constexpr_call_limit_exceeded); return false; } if (CallStackDepth <= getLangOpts().ConstexprCallDepth) return true; - Diag(Loc, diag::note_constexpr_depth_limit_exceeded) + FFDiag(Loc, diag::note_constexpr_depth_limit_exceeded) << getLangOpts().ConstexprCallDepth; return false; } @@ -584,7 +584,7 @@ namespace { bool nextStep(const Stmt *S) { if (!StepsLeft) { - Diag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded); + FFDiag(S->getLocStart(), diag::note_constexpr_step_limit_exceeded); return false; } --StepsLeft; @@ -602,11 +602,10 @@ namespace { /// Add notes containing a call stack to the current point of evaluation. void addCallStack(unsigned Limit); - public: - /// Diagnose that the evaluation cannot be folded. - OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId - = diag::note_invalid_subexpr_in_const_expr, - unsigned ExtraNotes = 0, bool IsCCEDiag = false) { + private: + OptionalDiagnostic Diag(SourceLocation Loc, diag::kind DiagId, + unsigned ExtraNotes, bool IsCCEDiag) { + if (EvalStatus.Diag) { // If we have a prior diagnostic, it will be noting that the expression // isn't a constant expression. This diagnostic is more important, @@ -651,12 +650,20 @@ namespace { HasActiveDiagnostic = false; return OptionalDiagnostic(); } - - OptionalDiagnostic Diag(const Expr *E, diag::kind DiagId + public: + // Diagnose that the evaluation could not be folded (FF => FoldFailure) + OptionalDiagnostic + FFDiag(SourceLocation Loc, + diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, + unsigned ExtraNotes = 0) { + return Diag(Loc, DiagId, ExtraNotes, false); + } + + OptionalDiagnostic FFDiag(const Expr *E, diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, - unsigned ExtraNotes = 0, bool IsCCEDiag = false) { + unsigned ExtraNotes = 0) { if (EvalStatus.Diag) - return Diag(E->getExprLoc(), DiagId, ExtraNotes, IsCCEDiag); + return Diag(E->getExprLoc(), DiagId, ExtraNotes, /*IsCCEDiag*/false); HasActiveDiagnostic = false; return OptionalDiagnostic(); } @@ -666,8 +673,7 @@ namespace { /// /// FIXME: Stop evaluating if we're in EM_ConstantExpression or /// EM_PotentialConstantExpression mode and we produce one of these. - template<typename LocArg> - OptionalDiagnostic CCEDiag(LocArg Loc, diag::kind DiagId + OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId = diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes = 0) { // Don't override a previous diagnostic. Don't bother collecting @@ -678,7 +684,11 @@ namespace { } return Diag(Loc, DiagId, ExtraNotes, true); } - + OptionalDiagnostic CCEDiag(const Expr *E, diag::kind DiagId + = diag::note_invalid_subexpr_in_const_expr, + unsigned ExtraNotes = 0) { + return CCEDiag(E->getExprLoc(), DiagId, ExtraNotes); + } /// Add a note to a prior diagnostic. OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId) { if (!HasActiveDiagnostic) @@ -1401,12 +1411,12 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, if (!IsGlobalLValue(Base)) { if (Info.getLangOpts().CPlusPlus11) { const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>(); - Info.Diag(Loc, diag::note_constexpr_non_global, 1) + Info.FFDiag(Loc, diag::note_constexpr_non_global, 1) << IsReferenceType << !Designator.Entries.empty() << !!VD << VD; NoteLValueLocation(Info, Base); } else { - Info.Diag(Loc); + Info.FFDiag(Loc); } // Don't allow references to temporaries to escape. return false; @@ -1456,7 +1466,7 @@ static bool CheckLValueConstantExpression(EvalInfo &Info, SourceLocation Loc, // Does this refer one past the end of some object? if (!Designator.Invalid && Designator.isOnePastTheEnd()) { const ValueDecl *VD = Base.dyn_cast<const ValueDecl*>(); - Info.Diag(Loc, diag::note_constexpr_past_end, 1) + Info.FFDiag(Loc, diag::note_constexpr_past_end, 1) << !Designator.Entries.empty() << !!VD << VD; NoteLValueLocation(Info, Base); } @@ -1480,10 +1490,10 @@ static bool CheckLiteralType(EvalInfo &Info, const Expr *E, // Prvalue constant expressions must be of literal types. if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_nonliteral) + Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->getType(); else - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -1493,7 +1503,7 @@ static bool CheckLiteralType(EvalInfo &Info, const Expr *E, static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc, QualType Type, const APValue &Value) { if (Value.isUninit()) { - Info.Diag(DiagLoc, diag::note_constexpr_uninitialized) + Info.FFDiag(DiagLoc, diag::note_constexpr_uninitialized) << true << Type; return false; } @@ -1703,7 +1713,7 @@ static bool truncateBitfieldValue(EvalInfo &Info, const Expr *E, // FIXME: In this case, we should provide the diagnostic for casting // a pointer to an integer. assert(Value.isLValue() && "integral value neither int nor lvalue?"); - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -1745,7 +1755,7 @@ static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, } else { // Don't try to handle vectors of anything other than int or float // (not sure if it's possible to hit this case). - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } unsigned BaseEltSize = EltAsInt.getBitWidth(); @@ -1758,7 +1768,7 @@ static bool EvalAndBitcastToAPInt(EvalInfo &Info, const Expr *E, } // Give up if the input isn't an int, float, or vector. For example, we // reject "(v4i16)(intptr_t)&a". - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -1794,7 +1804,7 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, APSInt &Result) { switch (Opcode) { default: - Info.Diag(E); + Info.FFDiag(E); return false; case BO_Mul: return CheckedIntArithmetic(Info, E, LHS, RHS, LHS.getBitWidth() * 2, @@ -1811,7 +1821,7 @@ static bool handleIntIntBinOp(EvalInfo &Info, const Expr *E, const APSInt &LHS, case BO_Div: case BO_Rem: if (RHS == 0) { - Info.Diag(E, diag::note_expr_divide_by_zero); + Info.FFDiag(E, diag::note_expr_divide_by_zero); return false; } Result = (Opcode == BO_Rem ? LHS % RHS : LHS / RHS); @@ -1892,7 +1902,7 @@ static bool handleFloatFloatBinOp(EvalInfo &Info, const Expr *E, const APFloat &RHS) { switch (Opcode) { default: - Info.Diag(E); + Info.FFDiag(E); return false; case BO_Mul: LHS.multiply(RHS, APFloat::rmNearestTiesToEven); @@ -2035,14 +2045,14 @@ static bool HandleSizeof(EvalInfo &Info, SourceLocation Loc, } if (Type->isDependentType()) { - Info.Diag(Loc); + Info.FFDiag(Loc); return false; } if (!Type->isConstantSizeType()) { // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. // FIXME: Better diagnostic. - Info.Diag(Loc); + Info.FFDiag(Loc); return false; } @@ -2106,7 +2116,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, if (Info.checkingPotentialConstantExpression()) return false; if (!Frame || !Frame->Arguments) { - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } Result = &Frame->Arguments[PVD->getFunctionScopeIndex()]; @@ -2127,7 +2137,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, if (Info.checkingPotentialConstantExpression()) return false; // FIXME: implement capture evaluation during constant expr evaluation. - Info.Diag(E->getLocStart(), + Info.FFDiag(E->getLocStart(), diag::note_unimplemented_constexpr_lambda_feature_ast) << "captures not currently allowed"; return false; @@ -2141,7 +2151,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // If we're checking a potential constant expression, the variable could be // initialized later. if (!Info.checkingPotentialConstantExpression()) - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -2155,7 +2165,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // Never evaluate the initializer of a weak variable. We can't be sure that // this is the definition which will be used. if (VD->isWeak()) { - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } @@ -2163,7 +2173,7 @@ static bool evaluateVarDeclInit(EvalInfo &Info, const Expr *E, // this in the cases where it matters for conformance. SmallVector<PartialDiagnosticAt, 8> Notes; if (!VD->evaluateValue(Notes)) { - Info.Diag(E, diag::note_constexpr_var_init_non_constant, + Info.FFDiag(E, diag::note_constexpr_var_init_non_constant, Notes.size() + 1) << VD; Info.Note(VD->getLocation(), diag::note_declared_at); Info.addNotes(Notes); @@ -2304,7 +2314,7 @@ static bool diagnoseUnreadableFields(EvalInfo &Info, const Expr *E, // FIXME: Add core issue number for the union case. if (Field->isMutable() && (RD->isUnion() || isReadByLvalueToRvalueConversion(Field->getType()))) { - Info.Diag(E, diag::note_constexpr_ltor_mutable, 1) << Field; + Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field; Info.Note(Field->getLocation(), diag::note_declared_at); return true; } @@ -2358,10 +2368,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, return handler.failed(); if (Sub.isOnePastTheEnd()) { if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_access_past_end) + Info.FFDiag(E, diag::note_constexpr_access_past_end) << handler.AccessKind; else - Info.Diag(E); + Info.FFDiag(E); return handler.failed(); } @@ -2373,7 +2383,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, for (unsigned I = 0, N = Sub.Entries.size(); /**/; ++I) { if (O->isUninit()) { if (!Info.checkingPotentialConstantExpression()) - Info.Diag(E, diag::note_constexpr_access_uninit) << handler.AccessKind; + Info.FFDiag(E, diag::note_constexpr_access_uninit) << handler.AccessKind; return handler.failed(); } @@ -2408,10 +2418,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, // Note, it should not be possible to form a pointer with a valid // designator which points more than one past the end of the array. if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_access_past_end) + Info.FFDiag(E, diag::note_constexpr_access_past_end) << handler.AccessKind; else - Info.Diag(E); + Info.FFDiag(E); return handler.failed(); } @@ -2441,10 +2451,10 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, uint64_t Index = Sub.Entries[I].ArrayIndex; if (Index > 1) { if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_access_past_end) + Info.FFDiag(E, diag::note_constexpr_access_past_end) << handler.AccessKind; else - Info.Diag(E); + Info.FFDiag(E); return handler.failed(); } @@ -2464,7 +2474,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, } } else if (const FieldDecl *Field = getAsField(Sub.Entries[I])) { if (Field->isMutable() && handler.AccessKind == AK_Read) { - Info.Diag(E, diag::note_constexpr_ltor_mutable, 1) + Info.FFDiag(E, diag::note_constexpr_ltor_mutable, 1) << Field; Info.Note(Field->getLocation(), diag::note_declared_at); return handler.failed(); @@ -2476,7 +2486,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, const FieldDecl *UnionField = O->getUnionField(); if (!UnionField || UnionField->getCanonicalDecl() != Field->getCanonicalDecl()) { - Info.Diag(E, diag::note_constexpr_access_inactive_union_member) + Info.FFDiag(E, diag::note_constexpr_access_inactive_union_member) << handler.AccessKind << Field << !UnionField << UnionField; return handler.failed(); } @@ -2492,11 +2502,11 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj, if (ObjType.isVolatileQualified()) { if (Info.getLangOpts().CPlusPlus) { // FIXME: Include a description of the path to the volatile subobject. - Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1) + Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1) << handler.AccessKind << 2 << Field; Info.Note(Field->getLocation(), diag::note_declared_at); } else { - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); } return handler.failed(); } @@ -2568,7 +2578,7 @@ struct ModifySubobjectHandler { bool checkConst(QualType QT) { // Assigning to a const object has undefined behavior. if (QT.isConstQualified()) { - Info.Diag(E, diag::note_constexpr_modify_const_type) << QT; + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; return false; } return true; @@ -2587,7 +2597,7 @@ struct ModifySubobjectHandler { return false; if (!NewVal.isInt()) { // Maybe trying to write a cast pointer value into a complex? - Info.Diag(E); + Info.FFDiag(E); return false; } Value = NewVal.getInt(); @@ -2678,7 +2688,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, AccessKinds AK, const LValue &LVal, QualType LValType) { if (!LVal.Base) { - Info.Diag(E, diag::note_constexpr_access_null) << AK; + Info.FFDiag(E, diag::note_constexpr_access_null) << AK; return CompleteObject(); } @@ -2686,7 +2696,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, if (LVal.CallIndex) { Frame = Info.getCallFrame(LVal.CallIndex); if (!Frame) { - Info.Diag(E, diag::note_constexpr_lifetime_ended, 1) + Info.FFDiag(E, diag::note_constexpr_lifetime_ended, 1) << AK << LVal.Base.is<const ValueDecl*>(); NoteLValueLocation(Info, LVal.Base); return CompleteObject(); @@ -2699,10 +2709,10 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, // semantics. if (LValType.isVolatileQualified()) { if (Info.getLangOpts().CPlusPlus) - Info.Diag(E, diag::note_constexpr_access_volatile_type) + Info.FFDiag(E, diag::note_constexpr_access_volatile_type) << AK << LValType; else - Info.Diag(E); + Info.FFDiag(E); return CompleteObject(); } @@ -2724,18 +2734,18 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, VD = VDef; } if (!VD || VD->isInvalidDecl()) { - Info.Diag(E); + Info.FFDiag(E); return CompleteObject(); } // Accesses of volatile-qualified objects are not allowed. if (BaseType.isVolatileQualified()) { if (Info.getLangOpts().CPlusPlus) { - Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1) + Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1) << AK << 1 << VD; Info.Note(VD->getLocation(), diag::note_declared_at); } else { - Info.Diag(E); + Info.FFDiag(E); } return CompleteObject(); } @@ -2750,7 +2760,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, // evaluation. } else if (AK != AK_Read) { // All the remaining cases only permit reading. - Info.Diag(E, diag::note_constexpr_modify_global); + Info.FFDiag(E, diag::note_constexpr_modify_global); return CompleteObject(); } else if (VD->isConstexpr()) { // OK, we can read this variable. @@ -2760,10 +2770,10 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, (Info.getLangOpts().OpenCL && BaseType.getAddressSpace() == LangAS::opencl_constant))) { if (Info.getLangOpts().CPlusPlus) { - Info.Diag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD; + Info.FFDiag(E, diag::note_constexpr_ltor_non_const_int, 1) << VD; Info.Note(VD->getLocation(), diag::note_declared_at); } else { - Info.Diag(E); + Info.FFDiag(E); } return CompleteObject(); } @@ -2784,10 +2794,10 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, // The definition of this variable could be constexpr. We can't // access it right now, but may be able to in future. } else if (Info.getLangOpts().CPlusPlus11) { - Info.Diag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD; + Info.FFDiag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD; Info.Note(VD->getLocation(), diag::note_declared_at); } else { - Info.Diag(E); + Info.FFDiag(E); } return CompleteObject(); } @@ -2823,7 +2833,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, if (!(BaseType.isConstQualified() && BaseType->isIntegralOrEnumerationType()) && !(VD && VD->getCanonicalDecl() == ED->getCanonicalDecl())) { - Info.Diag(E, diag::note_constexpr_access_static_temporary, 1) << AK; + Info.FFDiag(E, diag::note_constexpr_access_static_temporary, 1) << AK; Info.Note(MTE->getExprLoc(), diag::note_constexpr_temporary_here); return CompleteObject(); } @@ -2831,7 +2841,7 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, BaseVal = Info.Ctx.getMaterializedTemporaryValue(MTE, false); assert(BaseVal && "got reference to unevaluated temporary"); } else { - Info.Diag(E); + Info.FFDiag(E); return CompleteObject(); } } else { @@ -2842,11 +2852,11 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E, // Volatile temporary objects cannot be accessed in constant expressions. if (BaseType.isVolatileQualified()) { if (Info.getLangOpts().CPlusPlus) { - Info.Diag(E, diag::note_constexpr_access_volatile_obj, 1) + Info.FFDiag(E, diag::note_constexpr_access_volatile_obj, 1) << AK << 0; Info.Note(Base->getExprLoc(), diag::note_constexpr_temporary_here); } else { - Info.Diag(E); + Info.FFDiag(E); } return CompleteObject(); } @@ -2900,7 +2910,7 @@ static bool handleLValueToRValueConversion(EvalInfo &Info, const Expr *Conv, // an ICE in C, so this only matters for fold. assert(!Info.getLangOpts().CPlusPlus && "lvalue compound literal in c++?"); if (Type.isVolatileQualified()) { - Info.Diag(Conv); + Info.FFDiag(Conv); return false; } APValue Lit; @@ -2929,7 +2939,7 @@ static bool handleAssignment(EvalInfo &Info, const Expr *E, const LValue &LVal, return false; if (!Info.getLangOpts().CPlusPlus14) { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -2957,7 +2967,7 @@ struct CompoundAssignSubobjectHandler { bool checkConst(QualType QT) { // Assigning to a const object has undefined behavior. if (QT.isConstQualified()) { - Info.Diag(E, diag::note_constexpr_modify_const_type) << QT; + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; return false; } return true; @@ -2973,13 +2983,13 @@ struct CompoundAssignSubobjectHandler { case APValue::ComplexInt: case APValue::ComplexFloat: // FIXME: Implement complex compound assignment. - Info.Diag(E); + Info.FFDiag(E); return false; case APValue::LValue: return foundPointer(Subobj, SubobjType); default: // FIXME: can this happen? - Info.Diag(E); + Info.FFDiag(E); return false; } } @@ -2990,7 +3000,7 @@ struct CompoundAssignSubobjectHandler { if (!SubobjType->isIntegerType() || !RHS.isInt()) { // We don't support compound assignment on integer-cast-to-pointer // values. - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3018,7 +3028,7 @@ struct CompoundAssignSubobjectHandler { if (PointeeType.isNull() || !RHS.isInt() || (Opcode != BO_Add && Opcode != BO_Sub)) { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3050,7 +3060,7 @@ static bool handleCompoundAssignment( return false; if (!Info.getLangOpts().CPlusPlus14) { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3072,7 +3082,7 @@ struct IncDecSubobjectHandler { bool checkConst(QualType QT) { // Assigning to a const object has undefined behavior. if (QT.isConstQualified()) { - Info.Diag(E, diag::note_constexpr_modify_const_type) << QT; + Info.FFDiag(E, diag::note_constexpr_modify_const_type) << QT; return false; } return true; @@ -3104,7 +3114,7 @@ struct IncDecSubobjectHandler { return foundPointer(Subobj, SubobjType); default: // FIXME: can this happen? - Info.Diag(E); + Info.FFDiag(E); return false; } } @@ -3115,7 +3125,7 @@ struct IncDecSubobjectHandler { if (!SubobjType->isIntegerType()) { // We don't support increment / decrement on integer-cast-to-pointer // values. - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3174,7 +3184,7 @@ struct IncDecSubobjectHandler { if (const PointerType *PT = SubobjType->getAs<PointerType>()) PointeeType = PT->getPointeeType(); else { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3199,7 +3209,7 @@ static bool handleIncDec(EvalInfo &Info, const Expr *E, const LValue &LVal, return false; if (!Info.getLangOpts().CPlusPlus14) { - Info.Diag(E); + Info.FFDiag(E); return false; } @@ -3221,7 +3231,7 @@ static bool EvaluateObjectArgument(EvalInfo &Info, const Expr *Object, if (Object->getType()->isLiteralType(Info.Ctx)) return EvaluateTemporary(Object, This, Info); - Info.Diag(Object, diag::note_constexpr_nonliteral) << Object->getType(); + Info.FFDiag(Object, diag::note_constexpr_nonliteral) << Object->getType(); return false; } @@ -3249,7 +3259,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info, // member value, the behavior is undefined. if (!MemPtr.getDecl()) { // FIXME: Specific diagnostic. - Info.Diag(RHS); + Info.FFDiag(RHS); return nullptr; } @@ -3259,7 +3269,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info, // derived-to-base path for the member pointer. if (LV.Designator.MostDerivedPathLength + MemPtr.Path.size() > LV.Designator.Entries.size()) { - Info.Diag(RHS); + Info.FFDiag(RHS); return nullptr; } unsigned PathLengthToMember = @@ -3269,7 +3279,7 @@ static const ValueDecl *HandleMemberPointerAccess(EvalInfo &Info, LV.Designator.Entries[PathLengthToMember + I]); const CXXRecordDecl *MPDecl = MemPtr.Path[I]; if (LVDecl->getCanonicalDecl() != MPDecl->getCanonicalDecl()) { - Info.Diag(RHS); + Info.FFDiag(RHS); return nullptr; } } @@ -3403,7 +3413,7 @@ static bool EvaluateDecl(EvalInfo &Info, const Decl *D) { const Expr *InitE = VD->getInit(); if (!InitE) { - Info.Diag(D->getLocStart(), diag::note_constexpr_uninitialized) + Info.FFDiag(D->getLocStart(), diag::note_constexpr_uninitialized) << false << VD->getType(); Val = APValue(); return false; @@ -3517,7 +3527,7 @@ static EvalStmtResult EvaluateSwitch(StmtResult &Result, EvalInfo &Info, case ESR_CaseNotFound: // This can only happen if the switch case is nested within a statement // expression. We have no intention of supporting that. - Info.Diag(Found->getLocStart(), diag::note_constexpr_stmt_expr_unsupported); + Info.FFDiag(Found->getLocStart(), diag::note_constexpr_stmt_expr_unsupported); return ESR_Failed; } llvm_unreachable("Invalid EvalStmtResult!"); @@ -3608,7 +3618,7 @@ static EvalStmtResult EvaluateStmt(StmtResult &Result, EvalInfo &Info, return ESR_Succeeded; } - Info.Diag(S->getLocStart()); + Info.FFDiag(S->getLocStart()); return ESR_Failed; case Stmt::NullStmtClass: @@ -3855,7 +3865,7 @@ static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, if (Info.getLangOpts().CPlusPlus11) { const FunctionDecl *DiagDecl = Definition ? Definition : Declaration; - + // If this function is not constexpr because it is an inherited // non-constexpr constructor, diagnose that directly. auto *CD = dyn_cast<CXXConstructorDecl>(DiagDecl); @@ -3869,14 +3879,14 @@ static bool CheckConstexprFunction(EvalInfo &Info, SourceLocation CallLoc, // or an inheriting constructor, we should be much more explicit about why // it's not constexpr. if (CD && CD->isInheritingConstructor()) - Info.Diag(CallLoc, diag::note_constexpr_invalid_inhctor, 1) + Info.FFDiag(CallLoc, diag::note_constexpr_invalid_inhctor, 1) << CD->getInheritedConstructor().getConstructor()->getParent(); else - Info.Diag(CallLoc, diag::note_constexpr_invalid_function, 1) + Info.FFDiag(CallLoc, diag::note_constexpr_invalid_function, 1) << DiagDecl->isConstexpr() << (bool)CD << DiagDecl; Info.Note(DiagDecl->getLocation(), diag::note_declared_at); } else { - Info.Diag(CallLoc, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(CallLoc, diag::note_invalid_subexpr_in_const_expr); } return false; } @@ -3963,7 +3973,7 @@ static bool HandleFunctionCall(SourceLocation CallLoc, if (ESR == ESR_Succeeded) { if (Callee->getReturnType()->isVoidType()) return true; - Info.Diag(Callee->getLocEnd(), diag::note_constexpr_no_return); + Info.FFDiag(Callee->getLocEnd(), diag::note_constexpr_no_return); } return ESR == ESR_Returned; } @@ -3979,7 +3989,7 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This, const CXXRecordDecl *RD = Definition->getParent(); if (RD->getNumVBases()) { - Info.Diag(CallLoc, diag::note_constexpr_virtual_base) << RD; + Info.FFDiag(CallLoc, diag::note_constexpr_virtual_base) << RD; return false; } @@ -4199,7 +4209,7 @@ public: /// Report an evaluation error. This should only be called when an error is /// first discovered. When propagating an error, just return false. bool Error(const Expr *E, diag::kind D) { - Info.Diag(E, D); + Info.FFDiag(E, D); return false; } bool Error(const Expr *E) { @@ -4524,7 +4534,7 @@ public: if (BI + 1 == BE) { const Expr *FinalExpr = dyn_cast<Expr>(*BI); if (!FinalExpr) { - Info.Diag((*BI)->getLocStart(), + Info.FFDiag((*BI)->getLocStart(), diag::note_constexpr_stmt_expr_unsupported); return false; } @@ -4539,7 +4549,7 @@ public: // 'break', or 'continue', it would be nice to propagate that to // the outer statement evaluation rather than bailing out. if (ESR != ESR_Failed) - Info.Diag((*BI)->getLocStart(), + Info.FFDiag((*BI)->getLocStart(), diag::note_constexpr_stmt_expr_unsupported); return false; } @@ -4787,7 +4797,7 @@ bool LValueExprEvaluator::VisitVarDecl(const Expr *E, const VarDecl *VD) { return false; if (V->isUninit()) { if (!Info.checkingPotentialConstantExpression()) - Info.Diag(E, diag::note_constexpr_use_uninit_reference); + Info.FFDiag(E, diag::note_constexpr_use_uninit_reference); return false; } return Success(*V, E); @@ -4871,7 +4881,7 @@ bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) { if (!E->isPotentiallyEvaluated()) return Success(E); - Info.Diag(E, diag::note_constexpr_typeid_polymorphic) + Info.FFDiag(E, diag::note_constexpr_typeid_polymorphic) << E->getExprOperand()->getType() << E->getExprOperand()->getSourceRange(); return false; @@ -5039,9 +5049,9 @@ public: return false; if (!Info.CurrentCall->This) { if (Info.getLangOpts().CPlusPlus11) - Info.Diag(E, diag::note_constexpr_this) << E->isImplicit(); + Info.FFDiag(E, diag::note_constexpr_this) << E->isImplicit(); else - Info.Diag(E); + Info.FFDiag(E); return false; } Result = *Info.CurrentCall->This; @@ -5491,7 +5501,7 @@ bool RecordExprEvaluator::ZeroInitialization(const Expr *E, QualType T) { } if (isa<CXXRecordDecl>(RD) && cast<CXXRecordDecl>(RD)->getNumVBases()) { - Info.Diag(E, diag::note_constexpr_virtual_base) << RD; + Info.FFDiag(E, diag::note_constexpr_virtual_base) << RD; return false; } @@ -6313,7 +6323,7 @@ static bool EvaluateInteger(const Expr *E, APSInt &Result, EvalInfo &Info) { if (!Val.isInt()) { // FIXME: It would be better to produce the diagnostic for casting // a pointer to an integer. - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } Result = Val.getInt(); @@ -7663,7 +7673,7 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) { // C, array of zero length). Pointer subtraction in such cases has // undefined behavior, so is not constant. if (ElementSize.isZero()) { - Info.Diag(E, diag::note_constexpr_pointer_subtraction_zero_size) + Info.FFDiag(E, diag::note_constexpr_pointer_subtraction_zero_size) << ElementType; return false; } @@ -9036,10 +9046,10 @@ static bool Evaluate(APValue &Result, EvalInfo &Info, const Expr *E) { if (!EvaluateAtomic(E, Result, Info)) return false; } else if (Info.getLangOpts().CPlusPlus11) { - Info.Diag(E, diag::note_constexpr_nonliteral) << E->getType(); + Info.FFDiag(E, diag::note_constexpr_nonliteral) << E->getType(); return false; } else { - Info.Diag(E, diag::note_invalid_subexpr_in_const_expr); + Info.FFDiag(E, diag::note_invalid_subexpr_in_const_expr); return false; } |