[cfe-commits] r166956 - in /cfe/trunk: lib/Sema/SemaDecl.cpp test/SemaCXX/constant-expression-cxx11.cpp

Richard Smith richard-llvm at metafoo.co.uk
Mon Oct 29 11:26:47 PDT 2012


Author: rsmith
Date: Mon Oct 29 13:26:47 2012
New Revision: 166956

URL: http://llvm.org/viewvc/llvm-project?rev=166956&view=rev
Log:
Partially roll back r166898; it exposed a bug in the standard.

The problem is as follows: C++11 has contexts which are not
potentially-evaluated, and yet in which we are required or encouraged to
perform constant evaluation. In such contexts, we are not permitted to
implicitly define special member functions for literal types, therefore
we cannot evalaute those constant expressions.

Punt on this in one more context for now by skipping checking constexpr
variable initializers if they occur in dependent contexts.

Modified:
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=166956&r1=166955&r2=166956&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Oct 29 13:26:47 2012
@@ -7200,7 +7200,8 @@
   Expr *Init = var->getInit();
   bool IsGlobal = var->hasGlobalStorage() && !var->isStaticLocal();
 
-  if (Init && !Init->isValueDependent()) {
+  if (!var->getDeclContext()->isDependentContext() &&
+      Init && !Init->isValueDependent()) {
     if (IsGlobal && !var->isConstexpr() &&
         getDiagnostics().getDiagnosticLevel(diag::warn_global_constructor,
                                             var->getLocation())

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=166956&r1=166955&r2=166956&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Mon Oct 29 13:26:47 2012
@@ -521,7 +521,7 @@
 
 struct I { int n; typedef I V[10]; };
 I::V x, y;
-int g(); // expected-note {{here}}
+int g();
 template<bool B, typename T> struct S : T {
   int k;
   void f() {
@@ -529,9 +529,8 @@
     I &i = cells[k];
     switch (i.n) {}
 
-    constexpr int n = g(); // \
-    // expected-error {{must be initialized by a constant expression}} \
-    // expected-note {{non-constexpr function 'g'}}
+    // FIXME: We should be able to diagnose this.
+    constexpr int n = g();
 
     constexpr int m = this->g(); // ok, could be constexpr
   }
@@ -1435,3 +1434,23 @@
   constexpr auto &y = typeid(g()); // expected-error{{constant expression}} \
   // expected-note{{typeid applied to expression of polymorphic type 'TypeId::A' is not allowed in a constant expression}}
 }
+
+namespace PR14203 {
+  struct duration {
+    constexpr duration() {}
+    constexpr operator int() const { return 0; }
+  };
+  template<typename T> void f() {
+    // If we want to evaluate this at the point of the template definition, we
+    // need to trigger the implicit definition of the move constructor at that
+    // point.
+    // FIXME: C++ does not permit us to implicitly define it at the appropriate
+    // times, since it is only allowed to be implicitly defined when it is
+    // odr-used.
+    constexpr duration d = duration();
+  }
+  // FIXME: It's unclear whether this is valid. On the one hand, we're not
+  // allowed to generate a move constructor. On the other hand, if we did,
+  // this would be a constant expression.
+  int n = sizeof(short{duration(duration())}); // expected-error {{non-constant-expression cannot be narrowed}} expected-note {{override}}
+}





More information about the cfe-commits mailing list