Skip to content

Commit d17e469

Browse files
committed
asdf
1 parent efa7385 commit d17e469

File tree

9 files changed

+87
-83
lines changed

9 files changed

+87
-83
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ class CompoundStmt;
6161
class DependentFunctionTemplateSpecializationInfo;
6262
class EnumDecl;
6363
class Expr;
64+
struct EvalStatus;
6465
class FunctionTemplateDecl;
6566
class FunctionTemplateSpecializationInfo;
6667
class FunctionTypeLoc;
@@ -1412,7 +1413,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
14121413
APValue *evaluateValue() const;
14131414

14141415
private:
1415-
APValue *evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
1416+
APValue *evaluateValueImpl(EvalStatus &EStatus,
14161417
bool IsConstantInitialization) const;
14171418

14181419
public:
@@ -1446,7 +1447,7 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
14461447
/// constant initializer. Should only be called once, after completing the
14471448
/// definition of the variable.
14481449
bool checkForConstantInitialization(
1449-
SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
1450+
SmallVectorImpl<PartialDiagnosticAt> *Notes) const;
14501451

14511452
void setInitStyle(InitializationStyle Style) {
14521453
VarDeclBits.InitStyle = Style;

clang/include/clang/AST/Expr.h

Lines changed: 42 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,47 @@ namespace clang {
6060
class ValueDecl;
6161
class WarnUnusedResultAttr;
6262

63+
/// EvalStatus is a struct with detailed info about an evaluation in progress.
64+
struct EvalStatus {
65+
/// Whether the evaluated expression has side effects.
66+
/// For example, (f() && 0) can be folded, but it still has side effects.
67+
bool HasSideEffects = false;
68+
69+
/// Whether the evaluation hit undefined behavior.
70+
/// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
71+
/// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
72+
bool HasUndefinedBehavior = false;
73+
74+
bool HasFFDiagnostic = false;
75+
bool HasCCEDiagnostic = false;
76+
77+
/// Diag - If this is non-null, it will be filled in with a stack of notes
78+
/// indicating why evaluation failed (or why it failed to produce a constant
79+
/// expression).
80+
/// If the expression is unfoldable, the notes will indicate why it's not
81+
/// foldable. If the expression is foldable, but not a constant expression,
82+
/// the notes will describes why it isn't a constant expression. If the
83+
/// expression *is* a constant expression, no notes will be produced.
84+
///
85+
/// FIXME: this causes significant performance concerns and should be
86+
/// refactored at some point. Not all evaluations of the constant
87+
/// expression interpreter will display the given diagnostics, this means
88+
/// those kinds of uses are paying the expense of generating a diagnostic
89+
/// (which may include expensive operations like converting APValue objects
90+
/// to a string representation).
91+
SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr;
92+
93+
EvalStatus() = default;
94+
95+
/// Return true if the evaluated expression has
96+
/// side effects.
97+
bool hasSideEffects() const { return HasSideEffects; }
98+
99+
bool hasAnyDiagnostic() const {
100+
return HasFFDiagnostic || HasCCEDiagnostic;
101+
}
102+
};
103+
63104
/// A simple array of base specifiers.
64105
typedef SmallVector<CXXBaseSpecifier*, 4> CXXCastPath;
65106

@@ -605,42 +646,6 @@ class Expr : public ValueStmt {
605646
/// expression is a member pointer constant.
606647
const ValueDecl *getAsBuiltinConstantDeclRef(const ASTContext &Context) const;
607648

608-
/// EvalStatus is a struct with detailed info about an evaluation in progress.
609-
struct EvalStatus {
610-
/// Whether the evaluated expression has side effects.
611-
/// For example, (f() && 0) can be folded, but it still has side effects.
612-
bool HasSideEffects = false;
613-
614-
/// Whether the evaluation hit undefined behavior.
615-
/// For example, 1.0 / 0.0 can be folded to Inf, but has undefined behavior.
616-
/// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
617-
bool HasUndefinedBehavior = false;
618-
619-
/// Diag - If this is non-null, it will be filled in with a stack of notes
620-
/// indicating why evaluation failed (or why it failed to produce a constant
621-
/// expression).
622-
/// If the expression is unfoldable, the notes will indicate why it's not
623-
/// foldable. If the expression is foldable, but not a constant expression,
624-
/// the notes will describes why it isn't a constant expression. If the
625-
/// expression *is* a constant expression, no notes will be produced.
626-
///
627-
/// FIXME: this causes significant performance concerns and should be
628-
/// refactored at some point. Not all evaluations of the constant
629-
/// expression interpreter will display the given diagnostics, this means
630-
/// those kinds of uses are paying the expense of generating a diagnostic
631-
/// (which may include expensive operations like converting APValue objects
632-
/// to a string representation).
633-
SmallVectorImpl<PartialDiagnosticAt> *Diag = nullptr;
634-
635-
EvalStatus() = default;
636-
637-
/// Return true if the evaluated expression has
638-
/// side effects.
639-
bool hasSideEffects() const {
640-
return HasSideEffects;
641-
}
642-
};
643-
644649
/// EvalResult is a struct with detailed info about an evaluated expression.
645650
struct EvalResult : EvalStatus {
646651
/// Val - This is the value the expression can be folded to.
@@ -735,8 +740,7 @@ class Expr : public ValueStmt {
735740
/// can be folded to a constant, and produces any relevant notes. In C++11,
736741
/// notes will be produced if the expression is not a constant expression.
737742
bool EvaluateAsInitializer(APValue &Result, const ASTContext &Ctx,
738-
const VarDecl *VD,
739-
SmallVectorImpl<PartialDiagnosticAt> &Notes,
743+
const VarDecl *VD, EvalStatus &Status,
740744
bool IsConstantInitializer) const;
741745

742746
/// EvaluateWithSubstitution - Evaluate an expression as if from the context

clang/lib/AST/ByteCode/Compiler.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6985,8 +6985,8 @@ bool Compiler<Emitter>::visitDeclRef(const ValueDecl *D, const Expr *E) {
69856985
// here -- we will create a global variable in any case, and that
69866986
// will have the state of initializer evaluation attached.
69876987
APValue V;
6988-
SmallVector<PartialDiagnosticAt> Notes;
6989-
(void)Init->EvaluateAsInitializer(V, Ctx.getASTContext(), VD, Notes,
6988+
EvalStatus EStatus;
6989+
(void)Init->EvaluateAsInitializer(V, Ctx.getASTContext(), VD, EStatus,
69906990
true);
69916991
return this->visitDeclRef(D, E);
69926992
}

clang/lib/AST/ByteCode/InterpState.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ class InterpState final : public State, public SourceMapper {
6464
const Frame *getBottomFrame() const override { return &BottomFrame; }
6565

6666
// Access objects from the walker context.
67-
Expr::EvalStatus &getEvalStatus() const override {
68-
return Parent.getEvalStatus();
69-
}
67+
EvalStatus &getEvalStatus() const override { return Parent.getEvalStatus(); }
7068
ASTContext &getASTContext() const override { return Ctx.getASTContext(); }
7169
const LangOptions &getLangOpts() const {
7270
return Ctx.getASTContext().getLangOpts();

clang/lib/AST/ByteCode/State.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,12 @@ PartialDiagnostic &State::addDiag(SourceLocation Loc, diag::kind DiagId) {
8484

8585
OptionalDiagnostic State::diag(SourceLocation Loc, diag::kind DiagId,
8686
unsigned ExtraNotes, bool IsCCEDiag) {
87-
Expr::EvalStatus &EvalStatus = getEvalStatus();
87+
EvalStatus &EvalStatus = getEvalStatus();
88+
if (IsCCEDiag)
89+
EvalStatus.HasCCEDiagnostic = true;
90+
else
91+
EvalStatus.HasFFDiagnostic = true;
92+
8893
if (EvalStatus.Diag) {
8994
if (hasPriorDiagnostic()) {
9095
return OptionalDiagnostic();

clang/lib/AST/ByteCode/State.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ class State {
8888
virtual bool hasActiveDiagnostic() = 0;
8989
virtual void setActiveDiagnostic(bool Flag) = 0;
9090
virtual void setFoldFailureDiagnostic(bool Flag) = 0;
91-
virtual Expr::EvalStatus &getEvalStatus() const = 0;
91+
virtual EvalStatus &getEvalStatus() const = 0;
9292
virtual ASTContext &getASTContext() const = 0;
9393
virtual bool hasPriorDiagnostic() = 0;
9494
virtual unsigned getCallStackDepth() = 0;

clang/lib/AST/Decl.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2573,11 +2573,11 @@ EvaluatedStmt *VarDecl::getEvaluatedStmt() const {
25732573
}
25742574

25752575
APValue *VarDecl::evaluateValue() const {
2576-
SmallVector<PartialDiagnosticAt, 8> Notes;
2577-
return evaluateValueImpl(Notes, hasConstantInitialization());
2576+
EvalStatus ES;
2577+
return evaluateValueImpl(ES, hasConstantInitialization());
25782578
}
25792579

2580-
APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
2580+
APValue *VarDecl::evaluateValueImpl(EvalStatus &EStatus,
25812581
bool IsConstantInitialization) const {
25822582
EvaluatedStmt *Eval = ensureEvaluatedStmt();
25832583

@@ -2598,7 +2598,7 @@ APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
25982598
Eval->IsEvaluating = true;
25992599

26002600
ASTContext &Ctx = getASTContext();
2601-
bool Result = Init->EvaluateAsInitializer(Eval->Evaluated, Ctx, this, Notes,
2601+
bool Result = Init->EvaluateAsInitializer(Eval->Evaluated, Ctx, this, EStatus,
26022602
IsConstantInitialization);
26032603

26042604
// In C++, or in C23 if we're initialising a 'constexpr' variable, this isn't
@@ -2608,7 +2608,7 @@ APValue *VarDecl::evaluateValueImpl(SmallVectorImpl<PartialDiagnosticAt> &Notes,
26082608
if (IsConstantInitialization &&
26092609
(Ctx.getLangOpts().CPlusPlus ||
26102610
(isConstexpr() && Ctx.getLangOpts().C23)) &&
2611-
!Notes.empty())
2611+
EStatus.hasAnyDiagnostic())
26122612
Result = false;
26132613

26142614
// Ensure the computed APValue is cleaned up later if evaluation succeeded,
@@ -2662,7 +2662,7 @@ bool VarDecl::hasConstantInitialization() const {
26622662
}
26632663

26642664
bool VarDecl::checkForConstantInitialization(
2665-
SmallVectorImpl<PartialDiagnosticAt> &Notes) const {
2665+
SmallVectorImpl<PartialDiagnosticAt> *Notes) const {
26662666
EvaluatedStmt *Eval = ensureEvaluatedStmt();
26672667
// If we ask for the value before we know whether we have a constant
26682668
// initializer, we can compute the wrong value (for example, due to
@@ -2676,8 +2676,10 @@ bool VarDecl::checkForConstantInitialization(
26762676
assert(!getInit()->isValueDependent());
26772677

26782678
// Evaluate the initializer to check whether it's a constant expression.
2679+
EvalStatus EStatus;
2680+
EStatus.Diag = Notes;
26792681
Eval->HasConstantInitialization =
2680-
evaluateValueImpl(Notes, true) && Notes.empty();
2682+
evaluateValueImpl(EStatus, true) && !EStatus.hasAnyDiagnostic();
26812683

26822684
// If evaluation as a constant initializer failed, allow re-evaluation as a
26832685
// non-constant initializer if we later find we want the value.

0 commit comments

Comments
 (0)