From 157e7c97aec5a21e5dbf6baf0adb1f2c7c2a296a Mon Sep 17 00:00:00 2001 From: Matt Pharr Date: Tue, 7 Feb 2012 11:08:00 -0800 Subject: [PATCH] Fix a variety of cases in the parser that could crash with malformed programs. --- parse.yy | 345 ++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 224 insertions(+), 121 deletions(-) diff --git a/parse.yy b/parse.yy index 455d2b67..188e425c 100644 --- a/parse.yy +++ b/parse.yy @@ -333,7 +333,10 @@ argument_expression_list | argument_expression_list ',' assignment_expression { ExprList *argList = dynamic_cast($1); - Assert(argList != NULL); + if (argList == NULL) { + Assert(m->errorCount > 0); + argList = new ExprList(@3); + } argList->exprs.push_back($3); argList->pos = Union(argList->pos, @3); $$ = argList; @@ -462,8 +465,8 @@ rate_qualified_new rate_qualified_new_type : type_specifier { $$ = $1; } - | TOKEN_UNIFORM type_specifier { $$ = $2->GetAsUniformType(); } - | TOKEN_VARYING type_specifier { $$ = $2->GetAsVaryingType(); } + | TOKEN_UNIFORM type_specifier { $$ = $2 ? $2->GetAsUniformType() : NULL; } + | TOKEN_VARYING type_specifier { $$ = $2 ? $2->GetAsVaryingType() : NULL; } ; new_expression @@ -631,15 +634,20 @@ init_declarator_list : init_declarator { std::vector *dl = new std::vector; - dl->push_back($1); + if ($1 != NULL) + dl->push_back($1); $$ = dl; } | init_declarator_list ',' init_declarator { std::vector *dl = (std::vector *)$1; - if (dl != NULL && $3 != NULL) + if (dl == NULL) { + Assert(m->errorCount > 0); + dl = new std::vector; + } + if ($3 != NULL) dl->push_back($3); - $$ = $1; + $$ = dl; } ; @@ -664,9 +672,10 @@ storage_class_specifier type_specifier : atomic_var_type_specifier { $$ = $1; } | TOKEN_TYPE_NAME - { const Type *t = m->symbolTable->LookupType(yytext); + { + const Type *t = m->symbolTable->LookupType(yytext); $$ = t; - } + } | struct_or_union_specifier { $$ = $1; } | enum_specifier { $$ = $1; } ; @@ -684,41 +693,47 @@ atomic_var_type_specifier short_vec_specifier : atomic_var_type_specifier '<' int_constant '>' - { - Type* vt = - new VectorType($1, (int32_t)$3); - $$ = vt; - } + { + $$ = $1 ? new VectorType($1, (int32_t)$3) : NULL; + } ; struct_or_union_name : TOKEN_IDENTIFIER { $$ = strdup(yytext); } - | TOKEN_TYPE_NAME { $$ = strdup(yytext); } + | TOKEN_TYPE_NAME { $$ = strdup(yytext); } ; struct_or_union_specifier : struct_or_union struct_or_union_name '{' struct_declaration_list '}' - { - std::vector elementTypes; - std::vector elementNames; - std::vector elementPositions; - GetStructTypesNamesPositions(*$4, &elementTypes, &elementNames, - &elementPositions); - StructType *st = new StructType($2, elementTypes, elementNames, - elementPositions, false, Type::Unbound, @2); - m->symbolTable->AddType($2, st, @2); - $$ = st; + { + if ($4 != NULL) { + std::vector elementTypes; + std::vector elementNames; + std::vector elementPositions; + GetStructTypesNamesPositions(*$4, &elementTypes, &elementNames, + &elementPositions); + StructType *st = new StructType($2, elementTypes, elementNames, + elementPositions, false, Type::Unbound, @2); + m->symbolTable->AddType($2, st, @2); + $$ = st; + } + else + $$ = NULL; } | struct_or_union '{' struct_declaration_list '}' { - std::vector elementTypes; - std::vector elementNames; - std::vector elementPositions; - GetStructTypesNamesPositions(*$3, &elementTypes, &elementNames, - &elementPositions); - // FIXME: should be unbound - $$ = new StructType("", elementTypes, elementNames, elementPositions, - false, Type::Unbound, @1); + if ($3 != NULL) { + std::vector elementTypes; + std::vector elementNames; + std::vector elementPositions; + GetStructTypesNamesPositions(*$3, &elementTypes, &elementNames, + &elementPositions); + // FIXME: should be unbound + $$ = new StructType("", elementTypes, elementNames, elementPositions, + false, Type::Unbound, @1); + } + else + $$ = NULL; } | struct_or_union '{' '}' { @@ -729,16 +744,17 @@ struct_or_union_specifier Error(@1, "Empty struct definitions not allowed."); } | struct_or_union struct_or_union_name - { const Type *st = m->symbolTable->LookupType($2); - if (!st) { - std::vector alternates = m->symbolTable->ClosestTypeMatch($2); - std::string alts = lGetAlternates(alternates); - Error(@2, "Struct type \"%s\" unknown.%s", $2, alts.c_str()); - } - else if (dynamic_cast(st) == NULL) - Error(@2, "Type \"%s\" is not a struct type! (%s)", $2, - st->GetString().c_str()); - $$ = st; + { + const Type *st = m->symbolTable->LookupType($2); + if (!st) { + std::vector alternates = m->symbolTable->ClosestTypeMatch($2); + std::string alts = lGetAlternates(alternates); + Error(@2, "Struct type \"%s\" unknown.%s", $2, alts.c_str()); + } + else if (dynamic_cast(st) == NULL) + Error(@2, "Type \"%s\" is not a struct type! (%s)", $2, + st->GetString().c_str()); + $$ = st; } ; @@ -750,22 +766,26 @@ struct_declaration_list : struct_declaration { std::vector *sdl = new std::vector; - if (sdl != NULL && $1 != NULL) + if ($1 != NULL) sdl->push_back($1); $$ = sdl; } | struct_declaration_list struct_declaration { std::vector *sdl = (std::vector *)$1; - if (sdl != NULL && $2 != NULL) + if (sdl == NULL) { + Assert(m->errorCount > 0); + sdl = new std::vector; + } + if ($2 != NULL) sdl->push_back($2); - $$ = $1; + $$ = sdl; } ; struct_declaration : specifier_qualifier_list struct_declarator_list ';' - { $$ = new StructDeclaration($1, $2); } + { $$ = ($1 != NULL && $2 != NULL) ? new StructDeclaration($1, $2) : NULL; } ; specifier_qualifier_list @@ -831,9 +851,13 @@ struct_declarator_list | struct_declarator_list ',' struct_declarator { std::vector *sdl = (std::vector *)$1; - if (sdl != NULL && $3 != NULL) + if (sdl == NULL) { + Assert(m->errorCount > 0); + sdl = new std::vector; + } + if ($3 != NULL) sdl->push_back($3); - $$ = $1; + $$ = sdl; } ; @@ -900,9 +924,14 @@ enumerator_list } | enumerator_list ',' enumerator { - if ($1 != NULL && $3 != NULL) - $1->push_back($3); - $$ = $1; + std::vector *symList = $1; + if (symList == NULL) { + Assert(m->errorCount > 0); + symList = new std::vector; + } + if ($3 != NULL) + symList->push_back($3); + $$ = symList; } ; @@ -950,19 +979,27 @@ type_qualifier_list declarator : pointer direct_declarator { - Declarator *tail = $1; - while (tail->child != NULL) - tail = tail->child; - tail->child = $2; - $$ = $1; + if ($1 != NULL) { + Declarator *tail = $1; + while (tail->child != NULL) + tail = tail->child; + tail->child = $2; + $$ = $1; + } + else + $$ = NULL; } | reference direct_declarator { - Declarator *tail = $1; - while (tail->child != NULL) - tail = tail->child; - tail->child = $2; - $$ = $1; + if ($1 != NULL) { + Declarator *tail = $1; + while (tail->child != NULL) + tail = tail->child; + tail->child = $2; + $$ = $1; + } + else + $$ = NULL; } | direct_declarator ; @@ -1016,7 +1053,8 @@ direct_declarator if ($1 != NULL) { Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @4)); d->child = $1; - if ($3 != NULL) d->functionParams = *$3; + if ($3 != NULL) + d->functionParams = *$3; $$ = d; } else @@ -1086,7 +1124,6 @@ parameter_list { std::vector *dl = (std::vector *)$1; if (dl == NULL) - // dl may be NULL due to an earlier parse error... dl = new std::vector; if ($3 != NULL) dl->push_back($3); @@ -1118,18 +1155,26 @@ parameter_declaration } | declaration_specifiers declarator '=' initializer { - if ($2 != NULL) + if ($1 != NULL && $2 != NULL) { $2->initExpr = $4; - $$ = new Declaration($1, $2); - + $$ = new Declaration($1, $2); + } + else + $$ = NULL; } | declaration_specifiers abstract_declarator { - $$ = new Declaration($1, $2); + if ($1 != NULL && $2 != NULL) + $$ = new Declaration($1, $2); + else + $$ = NULL; } | declaration_specifiers { - $$ = new Declaration($1); + if ($1 == NULL) + $$ = NULL; + else + $$ = new Declaration($1); } ; @@ -1144,7 +1189,10 @@ type_name : specifier_qualifier_list | specifier_qualifier_list abstract_declarator { - $$ = $2->GetType($1, NULL); + if ($1 == NULL || $2 == NULL) + $$ = NULL; + else + $$ = $2->GetType($1, NULL); } ; @@ -1156,20 +1204,27 @@ abstract_declarator | direct_abstract_declarator | pointer direct_abstract_declarator { - Declarator *d = new Declarator(DK_POINTER, Union(@1, @2)); - d->child = $2; - $$ = d; + if ($2 == NULL) + $$ = NULL; + else { + Declarator *d = new Declarator(DK_POINTER, Union(@1, @2)); + d->child = $2; + $$ = d; + } } | reference { - Declarator *d = new Declarator(DK_REFERENCE, @1); - $$ = d; + $$ = new Declarator(DK_REFERENCE, @1); } | reference direct_abstract_declarator { - Declarator *d = new Declarator(DK_REFERENCE, Union(@1, @2)); - d->child = $2; - $$ = d; + if ($2 == NULL) + $$ = NULL; + else { + Declarator *d = new Declarator(DK_REFERENCE, Union(@1, @2)); + d->child = $2; + $$ = d; + } } ; @@ -1201,15 +1256,19 @@ direct_abstract_declarator } | direct_abstract_declarator '[' ']' { - Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3)); - d->arraySize = 0; - d->child = $1; - $$ = d; + if ($1 == NULL) + $$ = NULL; + else { + Declarator *d = new Declarator(DK_ARRAY, Union(@1, @3)); + d->arraySize = 0; + d->child = $1; + $$ = d; + } } | direct_abstract_declarator '[' constant_expression ']' { int size; - if ($3 != NULL && lGetConstantInt($3, &size, @3, "Array dimension")) { + if ($1 != NULL && $3 != NULL && lGetConstantInt($3, &size, @3, "Array dimension")) { if (size < 0) { Error(@3, "Array dimension must be non-negative."); $$ = NULL; @@ -1234,16 +1293,24 @@ direct_abstract_declarator } | direct_abstract_declarator '(' ')' { - Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @3)); - d->child = $1; - $$ = d; + if ($1 == NULL) + $$ = NULL; + else { + Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @3)); + d->child = $1; + $$ = d; + } } | direct_abstract_declarator '(' parameter_type_list ')' { - Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @4)); - d->child = $1; - if ($3 != NULL) d->functionParams = *$3; - $$ = d; + if ($1 == NULL) + $$ = NULL; + else { + Declarator *d = new Declarator(DK_FUNCTION, Union(@1, @4)); + d->child = $1; + if ($3 != NULL) d->functionParams = *$3; + $$ = d; + } } ; @@ -1258,15 +1325,14 @@ initializer_list { $$ = new ExprList($1, @1); } | initializer_list ',' initializer { - if ($1 == NULL) - $$ = NULL; - else { - ExprList *exprList = dynamic_cast($1); - Assert(exprList); - exprList->exprs.push_back($3); - exprList->pos = Union(exprList->pos, @3); - $$ = exprList; + ExprList *exprList = $1; + if (exprList == NULL) { + Assert(m->errorCount > 0); + exprList = new ExprList(@3); } + exprList->exprs.push_back($3); + exprList->pos = Union(exprList->pos, @3); + $$ = exprList; } ; @@ -1342,15 +1408,19 @@ statement_list } | statement_list statement { - if ($1 != NULL) - ((StmtList *)$1)->Add($2); - $$ = $1; + StmtList *sl = (StmtList *)$1; + if (sl == NULL) { + Assert(m->errorCount > 0); + sl = new StmtList(@2); + } + sl->Add($2); + $$ = sl; } ; expression_statement : ';' { $$ = NULL; } - | expression ';' { $$ = new ExprStmt($1, @1); } + | expression ';' { $$ = $1 ? new ExprStmt($1, @1) : NULL; } ; selection_statement @@ -1416,7 +1486,14 @@ foreach_dimension_list } | foreach_dimension_list ',' foreach_dimension_specifier { - $$->push_back($3); + std::vector *dv = $1; + if (dv == NULL) { + Assert(m->errorCount > 0); + dv = new std::vector; + } + if ($3 != NULL) + dv->push_back($3); + $$ = dv; } ; @@ -1447,38 +1524,57 @@ iteration_statement } | foreach_scope '(' foreach_dimension_list ')' { - std::vector &dims = *$3; - for (unsigned int i = 0; i < dims.size(); ++i) - m->symbolTable->AddVariable(dims[i]->sym); + std::vector *dims = $3; + if (dims == NULL) { + Assert(m->errorCount > 0); + dims = new std::vector; + } + for (unsigned int i = 0; i < dims->size(); ++i) + m->symbolTable->AddVariable((*dims)[i]->sym); } statement { - std::vector &dims = *$3; + std::vector *dims = $3; + if (dims == NULL) { + Assert(m->errorCount > 0); + dims = new std::vector; + } + std::vector syms; std::vector begins, ends; - for (unsigned int i = 0; i < dims.size(); ++i) { - syms.push_back(dims[i]->sym); - begins.push_back(dims[i]->beginExpr); - ends.push_back(dims[i]->endExpr); + for (unsigned int i = 0; i < dims->size(); ++i) { + syms.push_back((*dims)[i]->sym); + begins.push_back((*dims)[i]->beginExpr); + ends.push_back((*dims)[i]->endExpr); } $$ = new ForeachStmt(syms, begins, ends, $6, false, @1); m->symbolTable->PopScope(); } | foreach_tiled_scope '(' foreach_dimension_list ')' { - std::vector &dims = *$3; - for (unsigned int i = 0; i < dims.size(); ++i) - m->symbolTable->AddVariable(dims[i]->sym); + std::vector *dims = $3; + if (dims == NULL) { + Assert(m->errorCount > 0); + dims = new std::vector; + } + + for (unsigned int i = 0; i < dims->size(); ++i) + m->symbolTable->AddVariable((*dims)[i]->sym); } statement { - std::vector &dims = *$3; + std::vector *dims = $3; + if (dims == NULL) { + Assert(m->errorCount > 0); + dims = new std::vector; + } + std::vector syms; std::vector begins, ends; - for (unsigned int i = 0; i < dims.size(); ++i) { - syms.push_back(dims[i]->sym); - begins.push_back(dims[i]->beginExpr); - ends.push_back(dims[i]->endExpr); + for (unsigned int i = 0; i < dims->size(); ++i) { + syms.push_back((*dims)[i]->sym); + begins.push_back((*dims)[i]->beginExpr); + ends.push_back((*dims)[i]->endExpr); } $$ = new ForeachStmt(syms, begins, ends, $6, true, @1); m->symbolTable->PopScope(); @@ -1584,9 +1680,11 @@ function_definition compound_statement { std::vector args; - Symbol *sym = $2->GetFunctionInfo($1, &args); - if (sym != NULL) - m->AddFunctionDefinition(sym, args, $4); + if ($2 != NULL) { + Symbol *sym = $2->GetFunctionInfo($1, &args); + if (sym != NULL) + m->AddFunctionDefinition(sym, args, $4); + } m->symbolTable->PopScope(); // push in lAddFunctionParams(); } /* function with no declared return type?? @@ -1643,6 +1741,11 @@ static void lAddFunctionParams(Declarator *decl) { m->symbolTable->PushScope(); + if (decl == NULL) { + Assert(m->errorCount > 0); + return; + } + // walk down to the declarator for the function itself while (decl->kind != DK_FUNCTION && decl->child != NULL) decl = decl->child;