]> granicus.if.org Git - clang/commitdiff
PR14503: Don't assert if a constexpr constructor temploid instantiates to a
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 18 Jun 2013 17:51:51 +0000 (17:51 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 18 Jun 2013 17:51:51 +0000 (17:51 +0000)
constructor that does not initialize all members, and that constructor is used
to initialize a global.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184211 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticASTKinds.td
lib/AST/ExprConstant.cpp
test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp

index 06aca52c63af485dc7a32bce888dec3fb89ef9c9..f560069189a792c069e5242c0c3c05d30ea562d8 100644 (file)
@@ -38,6 +38,8 @@ def note_constexpr_nonliteral : Note<
 def note_constexpr_non_global : Note<
   "%select{pointer|reference}0 to %select{|subobject of }1"
   "%select{temporary|%3}2 is not a constant expression">;
+def note_constexpr_uninitialized : Note<
+  "subobject of type %0 is not initialized">;
 def note_constexpr_array_index : Note<"cannot refer to element %0 of "
   "%select{array of %2 elements|non-array object}1 in a constant expression">;
 def note_constexpr_float_arithmetic : Note<
index 86dcbd04e71d56bc2e7a9aa1e6bc24d15159a2f5..72f1c21ee6544d6167f2c6084608c419211ff462 100644 (file)
@@ -1132,6 +1132,11 @@ static bool CheckLiteralType(EvalInfo &Info, const Expr *E,
 /// check that the expression is of literal type.
 static bool CheckConstantExpression(EvalInfo &Info, SourceLocation DiagLoc,
                                     QualType Type, const APValue &Value) {
+  if (Value.isUninit()) {
+    Info.Diag(DiagLoc, diag::note_constexpr_uninitialized) << Type;
+    return false;
+  }
+
   // Core issue 1454: For a literal constant expression of array or class type,
   // each subobject of its value shall have been initialized by a constant
   // expression.
index 8a4fa42f0023bbb1d8c4fe051cdd6a103b39cc03..708c259d5b6125951e07cfeec2c0516c14e76429 100644 (file)
@@ -314,3 +314,23 @@ namespace CtorLookup {
   constexpr C::C(const C&) = default;
   constexpr C::C(C&) = default; // expected-error {{not constexpr}}
 }
+
+namespace PR14503 {
+  template<typename> struct V {
+    union {
+      int n;
+      struct {
+        int x,
+            y;
+      };
+    };
+    constexpr V() : x(0) {}
+  };
+
+  // The constructor is still 'constexpr' here, but the result is not intended
+  // to be a constant expression. The standard is not clear on how this should
+  // work.
+  constexpr V<int> v; // expected-error {{constant expression}} expected-note {{subobject of type 'int' is not initialized}}
+
+  constexpr int k = V<int>().x; // FIXME: ok?
+}