Fix error recovery with in-class initializer.

Previously, for a field with an invalid in-class initializer, we
would create a CXXDefaultInitExpr referring to a null Expr*.
This is not a good idea.

llvm-svn: 185216
This commit is contained in:
Eli Friedman 2013-06-28 21:07:41 +00:00
parent c37dbf7f65
commit b13e64eb60
2 changed files with 21 additions and 1 deletions

View File

@ -919,6 +919,9 @@ static void CheckConstexprCtorInitializer(Sema &SemaRef,
FieldDecl *Field,
llvm::SmallSet<Decl*, 16> &Inits,
bool &Diagnosed) {
if (Field->isInvalidDecl())
return;
if (Field->isUnnamedBitfield())
return;
@ -3236,6 +3239,8 @@ static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) {
static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info,
FieldDecl *Field,
IndirectFieldDecl *Indirect = 0) {
if (Field->isInvalidDecl())
return false;
// Overwhelmingly common case: we have a direct initializer for this field.
if (CXXCtorInitializer *Init = Info.AllBaseFields.lookup(Field))
@ -3274,7 +3279,7 @@ static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info,
// Don't try to build an implicit initializer if there were semantic
// errors in any of the initializers (and therefore we might be
// missing some that the user actually wrote).
if (Info.AnyErrorsInInits || Field->isInvalidDecl())
if (Info.AnyErrorsInInits)
return false;
CXXCtorInitializer *Init = 0;

View File

@ -1694,3 +1694,18 @@ namespace VirtualFromBase {
constexpr X<S2> *q = const_cast<X<X<S2>>*>(&xxs2);
static_assert(q->f() == sizeof(S2), "");
}
namespace ConstexprConstructorRecovery {
class X {
public:
enum E : short {
headers = 0x1,
middlefile = 0x2,
choices = 0x4
};
constexpr X() noexcept {};
protected:
E val{0}; // expected-error {{cannot initialize a member subobject of type 'ConstexprConstructorRecovery::X::E' with an rvalue of type 'int'}}
};
constexpr X x{};
}