[qfcc] Detect shadowed parameters in glsl

Unfortunately, it breaks detection in Ruamoko and QuakeC.
This commit is contained in:
Bill Currie 2024-10-07 09:51:03 +09:00
parent dae442c91e
commit 3c7bd275f3
3 changed files with 46 additions and 38 deletions

View file

@ -550,8 +550,8 @@ initialize_def (symbol_t *sym, const expr_t *init, defspace_t *space,
symbol_t *check = symtab_lookup (symtab, sym->name); symbol_t *check = symtab_lookup (symtab, sym->name);
reloc_t *relocs = 0; reloc_t *relocs = 0;
if (check && symtab->parent && check->table == symtab->parent->parent if (check && check->table == symtab->parent
&& symtab->parent->parent->type == stab_param) { && symtab->parent->type == stab_param) {
error (0, "%s shadows a parameter", sym->name); error (0, "%s shadows a parameter", sym->name);
} }
if (check && check->table == symtab) { if (check && check->table == symtab) {

View file

@ -36,6 +36,7 @@
#include "tools/qfcc/include/algebra.h" #include "tools/qfcc/include/algebra.h"
#include "tools/qfcc/include/diagnostic.h" #include "tools/qfcc/include/diagnostic.h"
#include "tools/qfcc/include/expr.h" #include "tools/qfcc/include/expr.h"
#include "tools/qfcc/include/qfcc.h"
#include "tools/qfcc/include/rua-lang.h" #include "tools/qfcc/include/rua-lang.h"
#include "tools/qfcc/include/shared.h" #include "tools/qfcc/include/shared.h"
#include "tools/qfcc/include/symtab.h" #include "tools/qfcc/include/symtab.h"
@ -221,6 +222,7 @@ proc_decl (const expr_t *expr)
list_scatter (&expr->decl.list, decls); list_scatter (&expr->decl.list, decls);
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
auto decl = decls[i]; auto decl = decls[i];
scoped_src_loc (decl);
const expr_t *init = nullptr; const expr_t *init = nullptr;
symbol_t *sym; symbol_t *sym;
if (decl->type == ex_assign) { if (decl->type == ex_assign) {
@ -228,11 +230,12 @@ proc_decl (const expr_t *expr)
if (decl->assign.dst->type != ex_symbol) { if (decl->assign.dst->type != ex_symbol) {
internal_error (decl->assign.dst, "not a symbol"); internal_error (decl->assign.dst, "not a symbol");
} }
pr.loc = decl->assign.dst->loc;
sym = decl->assign.dst->symbol; sym = decl->assign.dst->symbol;
} else if (decl->type == ex_symbol) { } else if (decl->type == ex_symbol) {
sym = decl->symbol; sym = decl->symbol;
} else { } else {
internal_error (decl->assign.dst, "not a symbol"); internal_error (decl, "not a symbol");
} }
auto spec = expr->decl.spec; auto spec = expr->decl.spec;
if (sym && sym->type) { if (sym && sym->type) {

View file

@ -166,7 +166,7 @@ int yylex (YYSTYPE *yylval, YYLTYPE *yylloc);
%token <spec> RESTRICT READONLY WRITEONLY %token <spec> RESTRICT READONLY WRITEONLY
%token <spec> DISCARD COHERENT %token <spec> DISCARD COHERENT
%type <symbol> variable_identifier %type <symbol> variable_identifier new_identifier
%type <block> block_declaration %type <block> block_declaration
%type <expr> declaration constant_expression %type <expr> declaration constant_expression
%type <expr> expression primary_exprsssion assignment_expression %type <expr> expression primary_exprsssion assignment_expression
@ -279,6 +279,7 @@ function_definition
{ {
$<symtab>$ = current_symtab; $<symtab>$ = current_symtab;
auto spec = $1; auto spec = $1;
spec.sym->params = spec.params;
auto sym = function_symbol (spec); auto sym = function_symbol (spec);
current_func = begin_function (sym, nullptr, current_symtab, current_func = begin_function (sym, nullptr, current_symtab,
false, spec.storage); false, spec.storage);
@ -303,6 +304,10 @@ variable_identifier
: IDENTIFIER : IDENTIFIER
; ;
new_identifier
: IDENTIFIER { $$ = new_symbol ($1->name); }
;
primary_exprsssion primary_exprsssion
: variable_identifier { $$ = new_symbol_expr ($1); } : variable_identifier { $$ = new_symbol_expr ($1); }
| VALUE | VALUE
@ -588,24 +593,24 @@ declaration
} }
$$ = nullptr; $$ = nullptr;
} }
| type_qualifier block_declaration IDENTIFIER ';' | type_qualifier block_declaration new_identifier ';'
{ {
if (current_symtab != pr.symtab) { if (current_symtab != pr.symtab) {
error (0, "blocks must be declared globally"); error (0, "blocks must be declared globally");
} else { } else {
auto block = $block_declaration; auto block = $block_declaration;
auto instance_name = $IDENTIFIER; auto instance_name = $new_identifier;
glsl_declare_block_instance (block, instance_name); glsl_declare_block_instance (block, instance_name);
} }
$$ = nullptr; $$ = nullptr;
} }
| type_qualifier block_declaration IDENTIFIER array_specifier ';' | type_qualifier block_declaration new_identifier array_specifier ';'
{ {
if (current_symtab != pr.symtab) { if (current_symtab != pr.symtab) {
error (0, "blocks must be declared globally"); error (0, "blocks must be declared globally");
} else { } else {
auto block = $block_declaration; auto block = $block_declaration;
auto instance_name = $IDENTIFIER; auto instance_name = $new_identifier;
instance_name->type = $array_specifier; instance_name->type = $array_specifier;
glsl_declare_block_instance (block, instance_name); glsl_declare_block_instance (block, instance_name);
} }
@ -617,15 +622,15 @@ declaration
nullptr, current_symtab); nullptr, current_symtab);
$$ = nullptr; $$ = nullptr;
} }
| type_qualifier IDENTIFIER ';' | type_qualifier new_identifier ';'
{ {
auto decl = new_decl_expr ($type_qualifier); auto decl = new_decl_expr ($type_qualifier);
$$ = append_decl (decl, $IDENTIFIER, nullptr); $$ = append_decl (decl, $new_identifier, nullptr);
} }
| type_qualifier IDENTIFIER identifier_list ';' | type_qualifier new_identifier identifier_list ';'
{ {
auto decl = new_decl_expr ($type_qualifier); auto decl = new_decl_expr ($type_qualifier);
append_decl (decl, $IDENTIFIER, nullptr); append_decl (decl, $new_identifier, nullptr);
$$ = append_decl_list (decl, $identifier_list); $$ = append_decl_list (decl, $identifier_list);
} }
; ;
@ -654,12 +659,12 @@ block_declaration
; ;
identifier_list identifier_list
: ',' IDENTIFIER : ',' new_identifier
{ {
auto expr = new_symbol_expr ($2); auto expr = new_symbol_expr ($2);
$$ = new_list_expr (expr); $$ = new_list_expr (expr);
} }
| identifier_list ',' IDENTIFIER | identifier_list ',' new_identifier
{ {
auto expr = new_symbol_expr ($3); auto expr = new_symbol_expr ($3);
$$ = expr_append_expr ($1, expr); $$ = expr_append_expr ($1, expr);
@ -696,7 +701,7 @@ function_header_with_parameters
; ;
function_header function_header
: fully_specified_type IDENTIFIER '(' : fully_specified_type new_identifier '('
{ {
auto spec = $1; auto spec = $1;
if ($2->table) { if ($2->table) {
@ -709,11 +714,11 @@ function_header
; ;
parameter_declarator parameter_declarator
: type_specifier IDENTIFIER : type_specifier new_identifier
{ {
$$ = new_param (nullptr, $1.type, $2->name); $$ = new_param (nullptr, $1.type, $2->name);
} }
| type_specifier IDENTIFIER array_specifier | type_specifier new_identifier array_specifier
{ {
$$ = new_param (nullptr, append_type ($1.type, $3), $2->name); $$ = new_param (nullptr, append_type ($1.type, $3), $2->name);
} }
@ -735,27 +740,27 @@ parameter_type_specifier
init_declarator_list init_declarator_list
: single_declaration : single_declaration
| init_declarator_list ',' IDENTIFIER | init_declarator_list ',' new_identifier
{ {
auto decl = $1; auto decl = $1;
$$ = append_decl (decl, $IDENTIFIER, nullptr); $$ = append_decl (decl, $new_identifier, nullptr);
} }
| init_declarator_list ',' IDENTIFIER array_specifier | init_declarator_list ',' new_identifier array_specifier
{ {
auto decl = $1; auto decl = $1;
$IDENTIFIER->type = $array_specifier; $new_identifier->type = $array_specifier;
$$ = append_decl (decl, $IDENTIFIER, nullptr); $$ = append_decl (decl, $new_identifier, nullptr);
} }
| init_declarator_list ',' IDENTIFIER array_specifier '=' initializer | init_declarator_list ',' new_identifier array_specifier '=' initializer
{ {
auto decl = $1; auto decl = $1;
$IDENTIFIER->type = $array_specifier; $new_identifier->type = $array_specifier;
$$ = append_decl (decl, $IDENTIFIER, $initializer); $$ = append_decl (decl, $new_identifier, $initializer);
} }
| init_declarator_list ',' IDENTIFIER '=' initializer | init_declarator_list ',' new_identifier '=' initializer
{ {
auto decl = $1; auto decl = $1;
$$ = append_decl (decl, $IDENTIFIER, $initializer); $$ = append_decl (decl, $new_identifier, $initializer);
} }
; ;
@ -764,31 +769,31 @@ single_declaration
{ {
$$ = new_decl_expr ($fully_specified_type); $$ = new_decl_expr ($fully_specified_type);
} }
| fully_specified_type IDENTIFIER | fully_specified_type new_identifier
{ {
auto decl = new_decl_expr ($fully_specified_type); auto decl = new_decl_expr ($fully_specified_type);
$$ = append_decl (decl, $IDENTIFIER, nullptr); $$ = append_decl (decl, $new_identifier, nullptr);
} }
| fully_specified_type IDENTIFIER array_specifier | fully_specified_type new_identifier array_specifier
{ {
auto spec = $fully_specified_type; auto spec = $fully_specified_type;
spec.type = append_type ($array_specifier, spec.type); spec.type = append_type ($array_specifier, spec.type);
spec.type = find_type (spec.type); spec.type = find_type (spec.type);
auto decl = new_decl_expr (spec); auto decl = new_decl_expr (spec);
$$ = append_decl (decl, $IDENTIFIER, nullptr); $$ = append_decl (decl, $new_identifier, nullptr);
} }
| fully_specified_type IDENTIFIER array_specifier '=' initializer | fully_specified_type new_identifier array_specifier '=' initializer
{ {
auto spec = $fully_specified_type; auto spec = $fully_specified_type;
spec.type = append_type ($array_specifier, spec.type); spec.type = append_type ($array_specifier, spec.type);
spec.type = find_type (spec.type); spec.type = find_type (spec.type);
auto decl = new_decl_expr (spec); auto decl = new_decl_expr (spec);
$$ = append_decl (decl, $IDENTIFIER, $initializer); $$ = append_decl (decl, $new_identifier, $initializer);
} }
| fully_specified_type IDENTIFIER '=' initializer | fully_specified_type new_identifier '=' initializer
{ {
auto decl = new_decl_expr ($fully_specified_type); auto decl = new_decl_expr ($fully_specified_type);
$$ = append_decl (decl, $IDENTIFIER, $initializer); $$ = append_decl (decl, $new_identifier, $initializer);
} }
; ;
@ -1004,13 +1009,13 @@ struct_declarator_list
; ;
struct_declarator struct_declarator
: IDENTIFIER : new_identifier
{ {
auto spec = $<spec>0; auto spec = $<spec>0;
spec.sym = $1; spec.sym = $1;
glsl_declare_field (spec, current_symtab); glsl_declare_field (spec, current_symtab);
} }
| IDENTIFIER array_specifier | new_identifier array_specifier
{ {
auto spec = $<spec>0; auto spec = $<spec>0;
spec.type = append_type ($2, spec.type); spec.type = append_type ($2, spec.type);
@ -1143,7 +1148,7 @@ else
condition condition
: expression : expression
| fully_specified_type IDENTIFIER '=' initializer | fully_specified_type new_identifier '=' initializer
{ {
auto symtab = current_symtab; auto symtab = current_symtab;
auto space = symtab->space; auto space = symtab->space;