Skip to content

Commit f60c553

Browse files
committed
Support GCC asm labels
1 parent 4ac1501 commit f60c553

File tree

7 files changed

+125
-9
lines changed

7 files changed

+125
-9
lines changed

regression/ansi-c/asm3/test.desc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
KNOWNBUG
1+
CORE
22
main.c
33
other.c
44
^EXIT=0$

src/ansi-c/ansi_c_convert_type.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,11 @@ void ansi_c_convert_typet::read_rec(const typet &type)
7272
c_qualifiers.is_ptr64=true;
7373
else if(type.id()==ID_volatile)
7474
c_qualifiers.is_volatile=true;
75-
else if(type.id()==ID_asm)
75+
else if(type.id()==ID_asm &&
76+
type.has_subtype() &&
77+
type.subtype().id()==ID_string_constant)
7678
{
77-
// These are called 'asm labels' by GCC.
78-
// ignore for now
79+
c_storage_spec.asm_label=type.subtype().get(ID_value);
7980
}
8081
else if(type.id()==ID_const)
8182
c_qualifiers.is_constant=true;

src/ansi-c/c_storage_spec.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,10 @@ void c_storage_spect::read(const typet &type)
6161
{
6262
alias=type.subtype().get(ID_value);
6363
}
64+
else if(type.id()==ID_asm &&
65+
type.has_subtype() &&
66+
type.subtype().id()==ID_string_constant)
67+
{
68+
asm_label=type.subtype().get(ID_value);
69+
}
6470
}

src/ansi-c/c_storage_spec.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,17 @@ class c_storage_spect
3535
is_inline=false;
3636
is_weak=false;
3737
alias.clear();
38+
asm_label.clear();
3839
}
3940

4041
bool is_typedef, is_extern, is_static, is_register,
4142
is_inline, is_thread_local, is_weak;
4243

4344
// __attribute__((alias("foo")))
4445
irep_idt alias;
46+
47+
// GCC asm labels __asm__("foo") - these change the symbol name
48+
irep_idt asm_label;
4549

4650
friend bool operator == (
4751
const c_storage_spect &a,
@@ -54,7 +58,8 @@ class c_storage_spect
5458
a.is_thread_local==b.is_thread_local &&
5559
a.is_inline==b.is_inline &&
5660
a.is_weak==b.is_weak &&
57-
a.alias==b.alias;
61+
a.alias==b.alias &&
62+
a.asm_label==b.asm_label;
5863
}
5964

6065
friend bool operator != (
@@ -76,6 +81,7 @@ class c_storage_spect
7681
a.is_thread_local |=b.is_thread_local;
7782
a.is_weak |=b.is_weak;
7883
if(!b.alias.empty()) a.alias=b.alias;
84+
if(!b.asm_label.empty()) a.asm_label=b.asm_label;
7985

8086
return a;
8187
}

src/ansi-c/c_typecheck_base.cpp

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,6 +693,89 @@ void c_typecheck_baset::typecheck_function_body(symbolt &symbol)
693693

694694
/*******************************************************************\
695695
696+
Function: c_typecheck_baset::apply_asm_label
697+
698+
Inputs:
699+
700+
Outputs:
701+
702+
Purpose:
703+
704+
\*******************************************************************/
705+
706+
void c_typecheck_baset::apply_asm_label(
707+
const irep_idt &asm_label,
708+
symbolt &symbol)
709+
{
710+
const irep_idt orig_name=symbol.name;
711+
712+
// restrict renaming to functions and global variables;
713+
// procedure-local ones would require fixing the scope, as we
714+
// do for parameters below
715+
if(!asm_label.empty() &&
716+
!symbol.is_type &&
717+
(symbol.type.id()==ID_code || symbol.is_static_lifetime))
718+
{
719+
symbol.name=asm_label;
720+
symbol.base_name=asm_label;
721+
}
722+
723+
if(symbol.name!=orig_name)
724+
{
725+
if(!asm_label_map.insert(
726+
std::make_pair(orig_name, asm_label)).second)
727+
{
728+
err_location(symbol.location);
729+
if(asm_label_map[orig_name]==asm_label)
730+
{
731+
str << "duplicate (consistent) asm renaming";
732+
warning_msg();
733+
}
734+
else
735+
{
736+
str << "error: conflicting asm renaming";
737+
throw 0;
738+
}
739+
}
740+
}
741+
else if(asm_label.empty())
742+
{
743+
asm_label_mapt::const_iterator entry=
744+
asm_label_map.find(symbol.name);
745+
if(entry!=asm_label_map.end())
746+
{
747+
symbol.name=entry->second;
748+
symbol.base_name=entry->second;
749+
}
750+
}
751+
752+
if(symbol.name!=orig_name &&
753+
symbol.type.id()==ID_code &&
754+
symbol.value.is_not_nil() && !symbol.is_macro)
755+
{
756+
const code_typet &code_type=to_code_type(symbol.type);
757+
758+
for(code_typet::parameterst::const_iterator
759+
p_it=code_type.parameters().begin();
760+
p_it!=code_type.parameters().end();
761+
++p_it)
762+
{
763+
const irep_idt &p_bn=p_it->get_base_name();
764+
if(p_bn.empty())
765+
continue;
766+
767+
irep_idt p_id=id2string(orig_name)+"::"+id2string(p_bn);
768+
irep_idt p_new_id=id2string(symbol.name)+"::"+id2string(p_bn);
769+
770+
if(!asm_label_map.insert(
771+
std::make_pair(p_id, p_new_id)).second)
772+
assert(asm_label_map[p_id]==p_new_id);
773+
}
774+
}
775+
}
776+
777+
/*******************************************************************\
778+
696779
Function: c_typecheck_baset::typecheck_declaration
697780
698781
Inputs:
@@ -754,7 +837,6 @@ void c_typecheck_baset::typecheck_declaration(
754837

755838
symbolt symbol;
756839
declaration.to_symbol(*d_it, symbol);
757-
irep_idt identifier=symbol.name;
758840

759841
// now check other half of type
760842
typecheck_type(symbol.type);
@@ -770,6 +852,9 @@ void c_typecheck_baset::typecheck_declaration(
770852
symbol.is_macro=true;
771853
}
772854

855+
apply_asm_label(full_spec.asm_label, symbol);
856+
irep_idt identifier=symbol.name;
857+
773858
typecheck_symbol(symbol);
774859

775860
// add code contract (if any); we typecheck this after the

src/ansi-c/c_typecheck_base.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,11 @@ class c_typecheck_baset:
283283
src.id()==ID_c_enum_tag ||
284284
src.id()==ID_c_bit_field;
285285
}
286+
287+
typedef hash_map_cont<irep_idt, irep_idt, irep_id_hash> asm_label_mapt;
288+
asm_label_mapt asm_label_map;
289+
290+
void apply_asm_label(const irep_idt &asm_label, symbolt &symbol);
286291
};
287292

288293
#endif

src/ansi-c/c_typecheck_expr.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -789,7 +789,7 @@ Function: c_typecheck_baset::typecheck_expr_symbol
789789

790790
void c_typecheck_baset::typecheck_expr_symbol(exprt &expr)
791791
{
792-
const irep_idt &identifier=to_symbol_expr(expr).get_identifier();
792+
irep_idt identifier=to_symbol_expr(expr).get_identifier();
793793

794794
// Is it a parameter? We do this while checking parameter lists.
795795
id_type_mapt::const_iterator p_it=parameter_map.find(identifier);
@@ -801,6 +801,15 @@ void c_typecheck_baset::typecheck_expr_symbol(exprt &expr)
801801
return;
802802
}
803803

804+
// renaming via GCC asm label
805+
asm_label_mapt::const_iterator entry=
806+
asm_label_map.find(identifier);
807+
if(entry!=asm_label_map.end())
808+
{
809+
identifier=entry->second;
810+
to_symbol_expr(expr).set_identifier(identifier);
811+
}
812+
804813
// look it up
805814
const symbolt *symbol_ptr;
806815
if(lookup(identifier, symbol_ptr))
@@ -2145,8 +2154,12 @@ void c_typecheck_baset::typecheck_side_effect_function_call(
21452154

21462155
if(f_op.id()==ID_symbol)
21472156
{
2148-
const irep_idt &identifier=
2149-
to_symbol_expr(f_op).get_identifier();
2157+
irep_idt identifier=to_symbol_expr(f_op).get_identifier();
2158+
2159+
asm_label_mapt::const_iterator entry=
2160+
asm_label_map.find(identifier);
2161+
if(entry!=asm_label_map.end())
2162+
identifier=entry->second;
21502163

21512164
if(symbol_table.symbols.find(identifier)==symbol_table.symbols.end())
21522165
{

0 commit comments

Comments
 (0)