r373161 - For now, disallow lifetime-extended temporaries with non-trivial (but

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Sat Sep 28 23:22:54 PDT 2019


Author: rsmith
Date: Sat Sep 28 23:22:54 2019
New Revision: 373161

URL: http://llvm.org/viewvc/llvm-project?rev=373161&view=rev
Log:
For now, disallow lifetime-extended temporaries with non-trivial (but
constexpr) destructors from being used in the values of constexpr
variables.

The standard rules here are unclear at best, so rejecting the
problematic cases seems prudent. Prior to this change, we would fail to
run the destructors for these temporaries, even if they had
side-effects, which is certainly not the right behavior.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td?rev=373161&r1=373160&r2=373161&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticASTKinds.td Sat Sep 28 23:22:54 2019
@@ -210,6 +210,9 @@ def note_constexpr_destroy_out_of_lifeti
   "destroying object '%0' whose lifetime has already ended">;
 def note_constexpr_unsupported_destruction : Note<
   "non-trivial destruction of type %0 in a constant expression is not supported">;
+def note_constexpr_unsupported_tempoarary_nontrivial_dtor : Note<
+  "non-trivial destruction of lifetime-extended temporary with type %0 "
+  "used in the result of a constant expression is not yet supported">;
 def note_constexpr_unsupported_unsized_array : Note<
   "array-to-pointer decay of array member without known bound is not supported">;
 def note_constexpr_unsized_array_indexed : Note<

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=373161&r1=373160&r2=373161&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Sat Sep 28 23:22:54 2019
@@ -1999,10 +1999,18 @@ static bool CheckLValueConstantExpressio
   } else if (const auto *MTE = dyn_cast_or_null<MaterializeTemporaryExpr>(
                  Base.dyn_cast<const Expr *>())) {
     if (CheckedTemps.insert(MTE).second) {
+      QualType TempType = getType(Base);
+      if (TempType.isDestructedType()) {
+        Info.FFDiag(MTE->getExprLoc(),
+                    diag::note_constexpr_unsupported_tempoarary_nontrivial_dtor)
+            << TempType;
+        return false;
+      }
+
       APValue *V = Info.Ctx.getMaterializedTemporaryValue(MTE, false);
       assert(V && "evasluation result refers to uninitialised temporary");
       if (!CheckEvaluationResult(CheckEvaluationResultKind::ConstantExpression,
-                                 Info, MTE->getExprLoc(), getType(Base), *V,
+                                 Info, MTE->getExprLoc(), TempType, *V,
                                  Usage, SourceLocation(), CheckedTemps))
         return false;
     }

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp?rev=373161&r1=373160&r2=373161&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx2a.cpp Sat Sep 28 23:22:54 2019
@@ -1250,3 +1250,22 @@ namespace dtor_call {
     as.b.~A(); // expected-note {{destruction of member 'b' of union with active member 'a'}}
   }
 }
+
+namespace temp_dtor {
+  void f();
+  struct A {
+    bool b;
+    constexpr ~A() { if (b) f(); }
+  };
+
+  // We can't accept either of these unless we start actually registering the
+  // destructors of the A temporaries to run on shutdown. It's unclear what the
+  // intended standard behavior is so we reject this for now.
+  constexpr A &&a = A{false}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}}
+  void f() { a.b = true; }
+
+  constexpr A &&b = A{true}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}}
+
+  // FIXME: We could in prinicple accept this.
+  constexpr const A &c = A{false}; // expected-error {{constant}} expected-note {{non-trivial destruction of lifetime-extended temporary}}
+}




More information about the cfe-commits mailing list