From 3ed4d1cbaad763c103771bdefb8b986a08f165fc Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Tue, 18 Jun 2013 17:51:51 +0000 Subject: [PATCH] PR14503: Don't assert if a constexpr constructor temploid instantiates to a 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 | 2 ++ lib/AST/ExprConstant.cpp | 5 +++++ .../CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp | 20 +++++++++++++++++++ 3 files changed, 27 insertions(+) diff --git a/include/clang/Basic/DiagnosticASTKinds.td b/include/clang/Basic/DiagnosticASTKinds.td index 06aca52c63..f560069189 100644 --- a/include/clang/Basic/DiagnosticASTKinds.td +++ b/include/clang/Basic/DiagnosticASTKinds.td @@ -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< diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 86dcbd04e7..72f1c21ee6 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -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. diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp index 8a4fa42f00..708c259d5b 100644 --- a/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp +++ b/test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp @@ -314,3 +314,23 @@ namespace CtorLookup { constexpr C::C(const C&) = default; constexpr C::C(C&) = default; // expected-error {{not constexpr}} } + +namespace PR14503 { + template 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 v; // expected-error {{constant expression}} expected-note {{subobject of type 'int' is not initialized}} + + constexpr int k = V().x; // FIXME: ok? +} -- 2.40.0