Fix a number of cases in the parser where segfaults were possible with malformed programs.

This commit is contained in:
Matt Pharr
2011-07-07 12:26:11 +01:00
parent 6b5ee6ccc0
commit f1aaf0115e

151
parse.yy
View File

@@ -305,9 +305,13 @@ cast_expression
// uniform float x = 1. / (float)y; // uniform float x = 1. / (float)y;
// don't issue an error due to (float)y being inadvertently // don't issue an error due to (float)y being inadvertently
// and undesirably-to-the-user "varying"... // and undesirably-to-the-user "varying"...
if ($4->GetType()->IsUniformType()) if ($2 == NULL || $4 == NULL || $4->GetType() == NULL)
$2 = $2->GetAsUniformType(); $$ = NULL;
$$ = new TypeCastExpr($2, $4, @1); else {
if ($4->GetType()->IsUniformType())
$2 = $2->GetAsUniformType();
$$ = new TypeCastExpr($2, $4, @1);
}
} }
; ;
@@ -459,13 +463,15 @@ declaration_specifiers
| storage_class_specifier declaration_specifiers | storage_class_specifier declaration_specifiers
{ {
DeclSpecs *ds = (DeclSpecs *)$2; DeclSpecs *ds = (DeclSpecs *)$2;
if (ds->storageClass != SC_NONE) if (ds != NULL) {
Error(@1, "Multiple storage class specifiers in a declaration are illegal. " if (ds->storageClass != SC_NONE)
"(Have provided both \"%s\" and \"%s\".)", Error(@1, "Multiple storage class specifiers in a declaration are illegal. "
lGetStorageClassString(ds->storageClass), "(Have provided both \"%s\" and \"%s\".)",
lGetStorageClassString($1)); lGetStorageClassString(ds->storageClass),
else lGetStorageClassString($1));
ds->storageClass = $1; else
ds->storageClass = $1;
}
$$ = ds; $$ = ds;
} }
| soa_width_specifier | soa_width_specifier
@@ -477,10 +483,12 @@ declaration_specifiers
| soa_width_specifier declaration_specifiers | soa_width_specifier declaration_specifiers
{ {
DeclSpecs *ds = (DeclSpecs *)$2; DeclSpecs *ds = (DeclSpecs *)$2;
if (ds->soaWidth != 0) if (ds != NULL) {
Error(@1, "soa<> qualifier supplied multiple times in declaration."); if (ds->soaWidth != 0)
else Error(@1, "soa<> qualifier supplied multiple times in declaration.");
ds->soaWidth = $1; else
ds->soaWidth = $1;
}
$$ = ds; $$ = ds;
} }
| type_specifier | type_specifier
@@ -496,9 +504,11 @@ declaration_specifiers
| type_specifier declaration_specifiers | type_specifier declaration_specifiers
{ {
DeclSpecs *ds = (DeclSpecs *)$2; DeclSpecs *ds = (DeclSpecs *)$2;
if (ds->baseType != NULL) if (ds != NULL) {
Error(@1, "Multiple types provided for declaration."); if (ds->baseType != NULL)
ds->baseType = $1; Error(@1, "Multiple types provided for declaration.");
ds->baseType = $1;
}
$$ = ds; $$ = ds;
} }
| type_qualifier | type_qualifier
@@ -508,7 +518,8 @@ declaration_specifiers
| type_qualifier declaration_specifiers | type_qualifier declaration_specifiers
{ {
DeclSpecs *ds = (DeclSpecs *)$2; DeclSpecs *ds = (DeclSpecs *)$2;
ds->typeQualifier |= $1; if (ds != NULL)
ds->typeQualifier |= $1;
$$ = ds; $$ = ds;
} }
; ;
@@ -523,14 +534,20 @@ init_declarator_list
| init_declarator_list ',' init_declarator | init_declarator_list ',' init_declarator
{ {
std::vector<Declarator *> *dl = (std::vector<Declarator *> *)$1; std::vector<Declarator *> *dl = (std::vector<Declarator *> *)$1;
dl->push_back($3); if (dl != NULL && $3 != NULL)
dl->push_back($3);
$$ = $1; $$ = $1;
} }
; ;
init_declarator init_declarator
: declarator : declarator
| declarator '=' initializer { $1->initExpr = $3; $$ = $1; } | declarator '=' initializer
{
if ($1 != NULL)
$1->initExpr = $3;
$$ = $1;
}
; ;
storage_class_specifier storage_class_specifier
@@ -637,13 +654,15 @@ struct_declaration_list
: struct_declaration : struct_declaration
{ {
std::vector<StructDeclaration *> *sdl = new std::vector<StructDeclaration *>; std::vector<StructDeclaration *> *sdl = new std::vector<StructDeclaration *>;
sdl->push_back($1); if (sdl != NULL && $1 != NULL)
sdl->push_back($1);
$$ = sdl; $$ = sdl;
} }
| struct_declaration_list struct_declaration | struct_declaration_list struct_declaration
{ {
std::vector<StructDeclaration *> *sdl = (std::vector<StructDeclaration *> *)$1; std::vector<StructDeclaration *> *sdl = (std::vector<StructDeclaration *> *)$1;
sdl->push_back($2); if (sdl != NULL && $2 != NULL)
sdl->push_back($2);
$$ = $1; $$ = $1;
} }
; ;
@@ -659,27 +678,31 @@ specifier_qualifier_list
| short_vec_specifier | short_vec_specifier
| type_qualifier specifier_qualifier_list | type_qualifier specifier_qualifier_list
{ {
if ($1 == TYPEQUAL_UNIFORM) if ($2 != NULL) {
$$ = $2->GetAsUniformType(); if ($1 == TYPEQUAL_UNIFORM)
else if ($1 == TYPEQUAL_VARYING) $$ = $2->GetAsUniformType();
$$ = $2->GetAsVaryingType(); else if ($1 == TYPEQUAL_VARYING)
else if ($1 == TYPEQUAL_REFERENCE) $$ = $2->GetAsVaryingType();
$$ = new ReferenceType($2, false); else if ($1 == TYPEQUAL_REFERENCE)
else if ($1 == TYPEQUAL_CONST) $$ = new ReferenceType($2, false);
$$ = $2->GetAsConstType(); else if ($1 == TYPEQUAL_CONST)
else if ($1 == TYPEQUAL_UNSIGNED) { $$ = $2->GetAsConstType();
const Type *t = $2->GetAsUnsignedType(); else if ($1 == TYPEQUAL_UNSIGNED) {
if (t) const Type *t = $2->GetAsUnsignedType();
$$ = t; if (t)
$$ = t;
else {
Error(@1, "Can't apply \"unsigned\" qualifier to \"%s\" type. Ignoring.",
$2->GetString().c_str());
$$ = $2;
}
}
else { else {
Error(@1, "Can't apply \"unsigned\" qualifier to \"%s\" type. Ignoring.", UNIMPLEMENTED;
$2->GetString().c_str());
$$ = $2;
} }
}
else {
UNIMPLEMENTED;
} }
else
$$ = NULL;
} }
/* K&R--implicit int type--e.g. "static foo" -> foo is an int */ /* K&R--implicit int type--e.g. "static foo" -> foo is an int */
/* | type_qualifier { UNIMPLEMENTED; }*/ /* | type_qualifier { UNIMPLEMENTED; }*/
@@ -690,13 +713,15 @@ struct_declarator_list
: struct_declarator : struct_declarator
{ {
std::vector<Declarator *> *sdl = new std::vector<Declarator *>; std::vector<Declarator *> *sdl = new std::vector<Declarator *>;
sdl->push_back($1); if ($1 != NULL)
sdl->push_back($1);
$$ = sdl; $$ = sdl;
} }
| struct_declarator_list ',' struct_declarator | struct_declarator_list ',' struct_declarator
{ {
std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1; std::vector<Declarator *> *sdl = (std::vector<Declarator *> *)$1;
sdl->push_back($3); if (sdl != NULL && $3 != NULL)
sdl->push_back($3);
$$ = $1; $$ = $1;
} }
; ;
@@ -757,8 +782,9 @@ direct_declarator
| direct_declarator '[' constant_expression ']' | direct_declarator '[' constant_expression ']'
{ {
Expr *size = $3; Expr *size = $3;
if (size) size = size->TypeCheck(); if (size)
if (size) { size = size->TypeCheck();
if (size && $1 != NULL) {
size = size->Optimize(); size = size->Optimize();
llvm::Constant *cval = size->GetConstant(size->GetType()); llvm::Constant *cval = size->GetConstant(size->GetType());
if (!cval) { if (!cval) {
@@ -780,21 +806,25 @@ direct_declarator
} }
| direct_declarator '[' ']' | direct_declarator '[' ']'
{ {
$1->AddArrayDimension(-1); // unsized if ($1 != NULL)
$1->AddArrayDimension(-1); // unsized
$$ = $1; $$ = $1;
} }
| direct_declarator '(' parameter_type_list ')' | direct_declarator '(' parameter_type_list ')'
{ {
Declarator *d = (Declarator *)$1; Declarator *d = (Declarator *)$1;
d->isFunction = true; if (d != NULL) {
d->functionArgs = $3; d->isFunction = true;
d->functionArgs = $3;
}
$$ = d; $$ = d;
} }
/* K&R? | direct_declarator '(' identifier_list ')' */ /* K&R? | direct_declarator '(' identifier_list ')' */
| direct_declarator '(' ')' | direct_declarator '(' ')'
{ {
Declarator *d = (Declarator *)$1; Declarator *d = (Declarator *)$1;
d->isFunction = true; if (d != NULL)
d->isFunction = true;
$$ = d; $$ = d;
} }
; ;
@@ -844,7 +874,8 @@ parameter_declaration
} }
| declaration_specifiers declarator '=' initializer | declaration_specifiers declarator '=' initializer
{ {
$2->initExpr = $4; if ($2 != NULL)
$2->initExpr = $4;
$$ = new Declaration($1, $2); $$ = new Declaration($1, $2);
} }
@@ -900,10 +931,14 @@ initializer_list
{ $$ = new ExprList($1, @1); } { $$ = new ExprList($1, @1); }
| initializer_list ',' initializer | initializer_list ',' initializer
{ {
ExprList *exprList = dynamic_cast<ExprList *>($1); if ($1 == NULL)
assert(exprList); $$ = NULL;
exprList->exprs.push_back($3); else {
$$ = exprList; ExprList *exprList = dynamic_cast<ExprList *>($1);
assert(exprList);
exprList->exprs.push_back($3);
$$ = exprList;
}
} }
; ;
@@ -960,7 +995,8 @@ statement_list
} }
| statement_list statement | statement_list statement
{ {
((StmtList *)$1)->Add($2); if ($1 != NULL)
((StmtList *)$1)->Add($2);
$$ = $1; $$ = $1;
} }
; ;
@@ -1084,8 +1120,9 @@ external_declaration
| TOKEN_EXTERN TOKEN_STRING_LITERAL '{' declaration '}' // FIXME: make sure string=="C" | TOKEN_EXTERN TOKEN_STRING_LITERAL '{' declaration '}' // FIXME: make sure string=="C"
| declaration | declaration
{ {
for (unsigned int i = 0; i < $1->declarators.size(); ++i) if ($1 != NULL)
m->AddGlobal($1->declSpecs, $1->declarators[i]); for (unsigned int i = 0; i < $1->declarators.size(); ++i)
m->AddGlobal($1->declSpecs, $1->declarators[i]);
} }
; ;
@@ -1127,6 +1164,8 @@ lAddFunctionParams(Declarator *decl) {
if (decl->functionArgs) { if (decl->functionArgs) {
for (unsigned int i = 0; i < decl->functionArgs->size(); ++i) { for (unsigned int i = 0; i < decl->functionArgs->size(); ++i) {
Declaration *pdecl = (*decl->functionArgs)[i]; Declaration *pdecl = (*decl->functionArgs)[i];
if (pdecl == NULL)
continue;
assert(pdecl->declarators.size() == 1); assert(pdecl->declarators.size() == 1);
Symbol *sym = pdecl->declarators[0]->sym; Symbol *sym = pdecl->declarators[0]->sym;
#ifndef NDEBUG #ifndef NDEBUG