llvmorg-github-actions[bot] wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Timm Baeder (tbaederr)

<details>
<summary>Changes</summary>

There are some instances where we want to know _if_ a diagnostic has been 
emitted, but we're not interested in the actual diagnostic. Emitting the 
diagnostics can be rather costly, especially because we add the callstack as 
notes.

---
Full diff: https://github.com/llvm/llvm-project/pull/203838.diff


5 Files Affected:

- (modified) clang/include/clang/AST/Expr.h (+4) 
- (modified) clang/lib/AST/ByteCode/State.cpp (+3) 
- (modified) clang/lib/AST/ComputeDependence.cpp (+2-4) 
- (modified) clang/lib/AST/ExprConstant.cpp (+2-4) 
- (modified) clang/lib/Sema/SemaExpr.cpp (+1-3) 


``````````diff
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index eeac69cb1d0eb..b17957f2c08f6 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -619,6 +619,10 @@ class Expr : public ValueStmt {
     /// Likewise, INT_MAX + 1 can be folded to INT_MIN, but has UB.
     bool HasUndefinedBehavior = false;
 
+    /// Whether any diagnostic has been emitted. This is set regardless of
+    /// whether @ref #Diag is set or not.
+    bool DiagEmitted = false;
+
     /// Diag - If this is non-null, it will be filled in with a stack of notes
     /// indicating why evaluation failed (or why it failed to produce a 
constant
     /// expression).
diff --git a/clang/lib/AST/ByteCode/State.cpp b/clang/lib/AST/ByteCode/State.cpp
index e612c6863e60f..e62b77272046c 100644
--- a/clang/lib/AST/ByteCode/State.cpp
+++ b/clang/lib/AST/ByteCode/State.cpp
@@ -25,6 +25,7 @@ OptionalDiagnostic State::FFDiag(SourceLocation Loc, 
diag::kind DiagId,
 
 OptionalDiagnostic State::FFDiag(const Expr *E, diag::kind DiagId,
                                  unsigned ExtraNotes) {
+  EvalStatus.DiagEmitted = true;
   if (EvalStatus.Diag)
     return diag(E->getExprLoc(), DiagId, ExtraNotes, false);
   setActiveDiagnostic(false);
@@ -33,6 +34,7 @@ OptionalDiagnostic State::FFDiag(const Expr *E, diag::kind 
DiagId,
 
 OptionalDiagnostic State::FFDiag(SourceInfo SI, diag::kind DiagId,
                                  unsigned ExtraNotes) {
+  EvalStatus.DiagEmitted = true;
   if (EvalStatus.Diag)
     return diag(SI.getLoc(), DiagId, ExtraNotes, false);
   setActiveDiagnostic(false);
@@ -41,6 +43,7 @@ OptionalDiagnostic State::FFDiag(SourceInfo SI, diag::kind 
DiagId,
 
 OptionalDiagnostic State::CCEDiag(SourceLocation Loc, diag::kind DiagId,
                                   unsigned ExtraNotes) {
+  EvalStatus.DiagEmitted = true;
   // Don't override a previous diagnostic. Don't bother collecting
   // diagnostics if we're evaluating for overflow.
   if (!EvalStatus.Diag || !EvalStatus.Diag->empty()) {
diff --git a/clang/lib/AST/ComputeDependence.cpp 
b/clang/lib/AST/ComputeDependence.cpp
index 34167eee8d8f2..95cfd19c0bcc8 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -57,11 +57,9 @@ ExprDependence clang::computeDependence(UnaryOperator *E,
   if (Ctx.getLangOpts().CPlusPlus && E->getOpcode() == UO_AddrOf &&
       !(Dep & ExprDependence::Value)) {
     Expr::EvalResult Result;
-    SmallVector<PartialDiagnosticAt, 8> Diag;
-    Result.Diag = &Diag;
     // FIXME: This doesn't enforce the C++98 constant expression rules.
-    if (E->getSubExpr()->EvaluateAsConstantExpr(Result, Ctx) && Diag.empty() &&
-        Result.Val.isLValue()) {
+    if (E->getSubExpr()->EvaluateAsConstantExpr(Result, Ctx) &&
+        !Result.DiagEmitted && Result.Val.isLValue()) {
       auto *VD = Result.Val.getLValueBase().dyn_cast<const ValueDecl *>();
       if (VD && VD->isTemplated()) {
         auto *VarD = dyn_cast<VarDecl>(VD);
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 1642c41a99a2f..0c5bf231c9f0a 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -22292,17 +22292,15 @@ bool Expr::isCXX11ConstantExpr(const ASTContext &Ctx, 
APValue *Result) const {
 
   // Build evaluation settings.
   Expr::EvalStatus Status;
-  SmallVector<PartialDiagnosticAt, 8> Diags;
-  Status.Diag = &Diags;
   EvalInfo Info(Ctx, Status, EvaluationMode::ConstantExpression);
 
   bool IsConstExpr =
       ::EvaluateAsRValue(Info, this, Result ? *Result : Scratch) &&
-      // FIXME: We don't produce a diagnostic for this, but the callers that
+      // NOTE: We don't produce a diagnostic for this, but the callers that
       // call us on arbitrary full-expressions should generally not care.
       Info.discardCleanups() && !Status.HasSideEffects;
 
-  return IsConstExpr && Diags.empty();
+  return IsConstExpr && !Status.DiagEmitted;
 }
 
 bool Expr::EvaluateWithSubstitution(APValue &Value, ASTContext &Ctx,
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index f2745425588f5..675d0bd389e28 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18340,12 +18340,10 @@ ExprResult 
Sema::CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl) {
   // immediate invocation.
   APValue Cached;
   auto CheckConstantExpressionAndKeepResult = [&]() {
-    llvm::SmallVector<PartialDiagnosticAt, 8> Notes;
     Expr::EvalResult Eval;
-    Eval.Diag = &Notes;
     bool Res = E.get()->EvaluateAsConstantExpr(
         Eval, getASTContext(), ConstantExprKind::ImmediateInvocation);
-    if (Res && Notes.empty()) {
+    if (Res && !Eval.DiagEmitted) {
       Cached = std::move(Eval.Val);
       return true;
     }

``````````

</details>


https://github.com/llvm/llvm-project/pull/203838
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to