Add error messages for structs containing nested undefined structs

This commit is contained in:
jbrodman
2014-05-27 15:50:53 -07:00
parent 68f62b1fc3
commit d3144da5eb
3 changed files with 46 additions and 11 deletions

View File

@@ -5143,9 +5143,18 @@ MemberExpr::create(Expr *e, const char *id, SourcePos p, SourcePos idpos,
exprType->GetString().c_str()); exprType->GetString().c_str());
return NULL; return NULL;
} }
if (CastType<StructType>(exprType) != NULL) {
if (CastType<StructType>(exprType) != NULL) const StructType *st = CastType<StructType>(exprType);
if (st->IsDefined()) {
return new StructMemberExpr(e, id, p, idpos, derefLValue); return new StructMemberExpr(e, id, p, idpos, derefLValue);
}
else {
Error(p, "Member operator \"%s\" can't be applied to declared "
"struct \"%s\" containing an undefined struct type.", derefLValue ? "->" : ".",
exprType->GetString().c_str());
return NULL;
}
}
else if (CastType<VectorType>(exprType) != NULL) else if (CastType<VectorType>(exprType) != NULL)
return new VectorMemberExpr(e, id, p, idpos, derefLValue); return new VectorMemberExpr(e, id, p, idpos, derefLValue);
else if (CastType<UndefinedStructType>(exprType)) { else if (CastType<UndefinedStructType>(exprType)) {
@@ -8708,6 +8717,12 @@ NewExpr::TypeCheck() {
"but not defined type \"%s\".", allocType->GetString().c_str()); "but not defined type \"%s\".", allocType->GetString().c_str());
return NULL; return NULL;
} }
const StructType *st = CastType<StructType>(allocType);
if (st != NULL && !st->IsDefined()) {
Error(pos, "Can't dynamically allocate storage for declared "
"type \"%s\" containing undefined member type.", allocType->GetString().c_str());
return NULL;
}
// Otherwise we only need to make sure that if we have an expression // Otherwise we only need to make sure that if we have an expression
// giving a number of elements to allocate that it can be converted to // giving a number of elements to allocate that it can be converted to

View File

@@ -1956,6 +1956,25 @@ StructType::IsConstType() const {
} }
bool
StructType::IsDefined() const {
for (int i = 0; i < GetElementCount(); i++) {
const Type *t = GetElementType(i);
const UndefinedStructType *ust = CastType<UndefinedStructType>(t);
if (ust != NULL) {
return false;
}
const StructType *st = CastType<StructType>(t);
if (st != NULL) {
if (!st->IsDefined()) {
return false;
}
}
}
return true;
}
const Type * const Type *
StructType::GetBaseType() const { StructType::GetBaseType() const {
return this; return this;

19
type.h
View File

@@ -81,15 +81,15 @@ struct Variability {
/** Enumerant that records each of the types that inherit from the Type /** Enumerant that records each of the types that inherit from the Type
baseclass. */ baseclass. */
enum TypeId { enum TypeId {
ATOMIC_TYPE, ATOMIC_TYPE, // 0
ENUM_TYPE, ENUM_TYPE, // 1
POINTER_TYPE, POINTER_TYPE, // 2
ARRAY_TYPE, ARRAY_TYPE, // 3
VECTOR_TYPE, VECTOR_TYPE, // 4
STRUCT_TYPE, STRUCT_TYPE, // 5
UNDEFINED_STRUCT_TYPE, UNDEFINED_STRUCT_TYPE, // 6
REFERENCE_TYPE, REFERENCE_TYPE, // 7
FUNCTION_TYPE FUNCTION_TYPE // 8
}; };
@@ -675,6 +675,7 @@ public:
bool IsIntType() const; bool IsIntType() const;
bool IsUnsignedType() const; bool IsUnsignedType() const;
bool IsConstType() const; bool IsConstType() const;
bool IsDefined() const;
const Type *GetBaseType() const; const Type *GetBaseType() const;
const StructType *GetAsVaryingType() const; const StructType *GetAsVaryingType() const;