22 if (!
Ctx.getLangOpts().MSVCCompat ||
27 case diag::note_constexpr_invalid_cast_ptrtoint:
28 addExtendedDiag(Loc, diag::warn_relaxed_constant_fold_cast);
30 case diag::note_constexpr_null_subobject:
31 addExtendedDiag(Loc, diag::warn_relaxed_constant_fold_null);
39 unsigned ExtraNotes) {
40 return diag(Loc, DiagId, ExtraNotes,
false);
44 unsigned ExtraNotes) {
47 return diag(E->
getExprLoc(), DiagId, ExtraNotes,
false);
48 setActiveDiagnostic(
false);
53 unsigned ExtraNotes) {
56 return diag(SI.
getLoc(), DiagId, ExtraNotes,
false);
57 setActiveDiagnostic(
false);
62 unsigned ExtraNotes) {
64 setActiveDiagnostic(
false);
71 setActiveDiagnostic(
false);
74 return diag(Loc, DiagId, ExtraNotes,
true);
78 unsigned ExtraNotes) {
83 unsigned ExtraNotes) {
88 if (!hasActiveDiagnostic())
94 if (!hasActiveDiagnostic())
100 if (hasActiveDiagnostic())
105 return Ctx.getDiagnostics().Report(Loc, DiagId);
111 EvalStatus.Diag->push_back(std::make_pair(Loc, PD));
112 return EvalStatus.Diag->back().second;
116 if (!EvalStatus.ExtendedDiag)
119 EvalStatus.ExtendedDiag->push_back(std::make_pair(Loc, PD));
123 unsigned ExtraNotes,
bool IsCCEDiag) {
124 if (EvalStatus.Diag) {
125 if (hasPriorDiagnostic()) {
129 unsigned CallStackNotes = getCallStackDepth() - 1;
130 unsigned Limit = Ctx.getDiagnostics().getConstexprBacktraceLimit();
132 CallStackNotes = std::min(CallStackNotes, Limit + 1);
133 if (checkingPotentialConstantExpression())
136 setActiveDiagnostic(
true);
137 setFoldFailureDiagnostic(!IsCCEDiag);
138 EvalStatus.Diag->clear();
139 EvalStatus.Diag->reserve(1 + ExtraNotes + CallStackNotes);
140 addDiag(Loc, DiagId);
141 if (!checkingPotentialConstantExpression()) {
144 return OptionalDiagnostic(&(*EvalStatus.Diag)[0].second);
146 setActiveDiagnostic(
false);
147 return OptionalDiagnostic();
150void State::addCallStack(
unsigned Limit) {
152 unsigned ActiveCalls = getCallStackDepth() - 1;
153 unsigned SkipStart = ActiveCalls, SkipEnd = SkipStart;
154 if (Limit && Limit < ActiveCalls) {
155 SkipStart = Limit / 2 + Limit % 2;
156 SkipEnd = ActiveCalls - Limit / 2;
160 unsigned CallIdx = 0;
161 const Frame *Top = getCurrentFrame();
162 for (
const Frame *F = Top; F->getCaller() !=
nullptr;
163 F = F->getCaller(), ++CallIdx) {
164 SourceRange CallRange = F->getCallRange();
168 if (CallIdx >= SkipStart && CallIdx < SkipEnd) {
169 if (CallIdx == SkipStart) {
171 addDiag(CallRange.
getBegin(), diag::note_constexpr_calls_suppressed)
172 << unsigned(ActiveCalls - Limit);
180 dyn_cast_if_present<CXXConstructorDecl>(F->getCallee());
181 CD && CD->isInheritingConstructor()) {
183 diag::note_constexpr_inherited_ctor_call_here)
188 SmallString<128> Buffer;
189 llvm::raw_svector_ostream
Out(Buffer);
192 addDiag(CallRange.
getBegin(), diag::note_constexpr_call_here)
193 <<
Out.str() << CallRange;
197bool State::hasPriorDiagnostic() {
198 if (!EvalStatus.Diag->empty()) {
200 case EvaluationMode::ConstantFold:
201 case EvaluationMode::IgnoreSideEffects:
202 if (!HasFoldFailureDiagnostic)
206 case EvaluationMode::ConstantExpression:
207 case EvaluationMode::ConstantExpressionUnevaluated:
208 setActiveDiagnostic(
false);
216 uint64_t Limit =
Ctx.getLangOpts().ConstexprStepLimit;
228 llvm_unreachable(
"Missed EvalMode case");
244 llvm_unreachable(
"Missed EvalMode case");
247bool State::keepEvaluatingAfterUndefinedBehavior()
const {
255 return checkingForUndefinedBehavior();
257 llvm_unreachable(
"Missed EvalMode case");
Defines the clang::ASTContext interface.
Implements a partial diagnostic which may not be emitted.
A little helper class used to produce diagnostics.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
A partial diagnostic which we might know in advance that we are not going to emit.
Encodes a location in the source.
SourceLocation getBegin() const
Describes the statement/declaration an opcode was generated from.
SourceLocation getLoc() const
bool checkingForUndefinedBehavior() const
Are we checking an expression for overflow?
virtual bool stepsLeft() const =0
OptionalDiagnostic Note(SourceLocation Loc, diag::kind DiagId)
Add a note to a prior diagnostic.
DiagnosticBuilder report(SourceLocation Loc, diag::kind DiagId)
Directly reports a diagnostic message.
bool emitRelaxedDiag(SourceLocation Loc, diag::kind DiagId)
If DiagId should be relaxed as per the current evaluation settings, emit it as a warning instead of a...
OptionalDiagnostic FFDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Diagnose that the evaluation could not be folded (FF => FoldFailure)
Expr::EvalStatus & EvalStatus
void addNotes(ArrayRef< PartialDiagnosticAt > Diags)
Add a stack of notes to a prior diagnostic.
OptionalDiagnostic CCEDiag(SourceLocation Loc, diag::kind DiagId=diag::note_invalid_subexpr_in_const_expr, unsigned ExtraNotes=0)
Diagnose that the evaluation does not produce a C++11 core constant expression.
bool checkingPotentialConstantExpression() const
Are we checking whether the expression is a potential constant expression?
bool keepEvaluatingAfterSideEffect() const
Should we continue evaluation after encountering a side-effect that we couldn't model?
bool keepEvaluatingAfterFailure() const
Should we continue evaluation as much as possible after encountering a construct which can't be reduc...
bool InConstantContext
Whether or not we're in a context where the front end requires a constant value.
unsigned kind
All of the diagnostics that can be emitted by the frontend.
Top level wrappers for InstallAPI frontend operations.
@ ConstantFold
Fold the expression to a constant.
@ ConstantExpressionUnevaluated
Evaluate as a constant expression.
@ ConstantExpression
Evaluate as a constant expression.
@ IgnoreSideEffects
Evaluate in any way we know how.