For P0784R7: compute whether a variable has constant destruction if it
has a constexpr destructor.
For constexpr variables, reject if the variable does not have constant
destruction. In all cases, do not emit runtime calls to the destructor
for variables with constant destruction.
llvm-svn: 373159
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index 6b6a8ab..cbac50d 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -808,12 +808,19 @@
/// valid if CheckedICE is true.
bool IsICE : 1;
+ /// Whether this variable is known to have constant destruction. That is,
+ /// whether running the destructor on the initial value is a side-effect
+ /// (and doesn't inspect any state that might have changed during program
+ /// execution). This is currently only computed if the destructor is
+ /// non-trivial.
+ bool HasConstantDestruction : 1;
+
Stmt *Value;
APValue Evaluated;
- EvaluatedStmt() : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
- CheckingICE(false), IsICE(false) {}
-
+ EvaluatedStmt()
+ : WasEvaluated(false), IsEvaluating(false), CheckedICE(false),
+ CheckingICE(false), IsICE(false), HasConstantDestruction(false) {}
};
/// Represents a variable declaration or definition.
@@ -1267,6 +1274,14 @@
/// to untyped APValue if the value could not be evaluated.
APValue *getEvaluatedValue() const;
+ /// Evaluate the destruction of this variable to determine if it constitutes
+ /// constant destruction.
+ ///
+ /// \pre isInitICE()
+ /// \return \c true if this variable has constant destruction, \c false if
+ /// not.
+ bool evaluateDestruction(SmallVectorImpl<PartialDiagnosticAt> &Notes) const;
+
/// Determines whether it is already known whether the
/// initializer is an integral constant expression or not.
bool isInitKnownICE() const;
@@ -1505,9 +1520,14 @@
// has no definition within this source file.
bool isKnownToBeDefined() const;
- /// Do we need to emit an exit-time destructor for this variable?
+ /// Is destruction of this variable entirely suppressed? If so, the variable
+ /// need not have a usable destructor at all.
bool isNoDestroy(const ASTContext &) const;
+ /// Do we need to emit an exit-time destructor for this variable, and if so,
+ /// what kind?
+ QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K >= firstVar && K <= lastVar; }