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
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<
/// 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.
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?
+}