Skip to content

Commit 151bded

Browse files
author
Daniel Kroening
authored
Merge pull request diffblue#99 from tautschnig/gcc-attributes
Extended GCC attributes parsing and processing
2 parents f20cf9f + 492e75b commit 151bded

File tree

14 files changed

+268
-140
lines changed

14 files changed

+268
-140
lines changed

regression/ansi-c/gcc_attributes5/main.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ STATIC_ASSERT(__alignof(var7)==8);
2121

2222
void (__attribute__((aligned)) *****f1)(void);
2323
void (__attribute__((aligned)) f2)(void);
24+
25+
int __attribute__((cdecl,regparm(0))) *foo1(int x);
26+
int __attribute__((cdecl,regparm(0))) *(foo2)(int x);
27+
int (__attribute__((cdecl,regparm(0))) *foo3)(int x);
28+
int (* __attribute__((cdecl,regparm(0))) foo4)(int x);
29+
typedef int (__attribute__((cdecl,regparm(0))) foo5)(int x);
30+
typedef int (__attribute__((cdecl,regparm(0))) *foo6)(int x);
31+
typedef int* (__attribute__((cdecl,regparm(0))) *foo7)(int x);
2432

2533
#endif
2634

regression/ansi-c/gcc_attributes5/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

44
^EXIT=0$

regression/ansi-c/gcc_attributes6/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

44
^EXIT=0$
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#ifdef __GNUC__
2+
3+
int foo();
4+
char foo __attribute__((section("other")));
5+
long more_foo __attribute__((section("other2"))) asm("foo");
6+
7+
const char* __attribute__((section("s"))) bar1();
8+
const char* __attribute__((section("s"),weak)) bar2();
9+
const char* __attribute__((section("s"))) __attribute__((weak)) bar();
10+
11+
#endif
12+
13+
int main()
14+
{
15+
#ifdef __GNUC__
16+
static int __attribute__((section(".data.unlikely"))) __warned;
17+
__warned=1;
18+
return __warned;
19+
#endif
20+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
--
7+
^warning: ignoring
8+
^CONVERSION ERROR$

src/ansi-c/ansi_c_convert_type.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,12 @@ void ansi_c_convert_typet::read_rec(const typet &type)
7878
{
7979
c_storage_spec.asm_label=type.subtype().get(ID_value);
8080
}
81+
else if(type.id()==ID_section &&
82+
type.has_subtype() &&
83+
type.subtype().id()==ID_string_constant)
84+
{
85+
c_storage_spec.section=type.subtype().get(ID_value);
86+
}
8187
else if(type.id()==ID_const)
8288
c_qualifiers.is_constant=true;
8389
else if(type.id()==ID_restrict)
@@ -110,9 +116,6 @@ void ansi_c_convert_typet::read_rec(const typet &type)
110116
{
111117
gcc_attribute_mode=type;
112118
}
113-
else if(type.id()==ID_gcc_attribute)
114-
{
115-
}
116119
else if(type.id()==ID_msc_based)
117120
{
118121
const exprt &as_expr=static_cast<const exprt &>(static_cast<const irept &>(type));

src/ansi-c/c_storage_spec.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,4 +67,10 @@ void c_storage_spect::read(const typet &type)
6767
{
6868
asm_label=type.subtype().get(ID_value);
6969
}
70+
else if(type.id()==ID_section &&
71+
type.has_subtype() &&
72+
type.subtype().id()==ID_string_constant)
73+
{
74+
section=type.subtype().get(ID_value);
75+
}
7076
}

src/ansi-c/c_storage_spec.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class c_storage_spect
3636
is_weak=false;
3737
alias.clear();
3838
asm_label.clear();
39+
section.clear();
3940
}
4041

4142
bool is_typedef, is_extern, is_static, is_register,
@@ -46,6 +47,7 @@ class c_storage_spect
4647

4748
// GCC asm labels __asm__("foo") - these change the symbol name
4849
irep_idt asm_label;
50+
irep_idt section;
4951

5052
friend bool operator == (
5153
const c_storage_spect &a,
@@ -59,7 +61,8 @@ class c_storage_spect
5961
a.is_inline==b.is_inline &&
6062
a.is_weak==b.is_weak &&
6163
a.alias==b.alias &&
62-
a.asm_label==b.asm_label;
64+
a.asm_label==b.asm_label &&
65+
a.section==b.section;
6366
}
6467

6568
friend bool operator != (
@@ -82,6 +85,7 @@ class c_storage_spect
8285
a.is_weak |=b.is_weak;
8386
if(!b.alias.empty()) a.alias=b.alias;
8487
if(!b.asm_label.empty()) a.asm_label=b.asm_label;
88+
if(!b.section.empty()) a.section=b.section;
8589

8690
return a;
8791
}

src/ansi-c/c_typecheck_base.cpp

Lines changed: 58 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,8 @@ void c_typecheck_baset::move_symbol(symbolt &symbol, symbolt *&new_symbol)
7171
if(symbol_table.move(symbol, new_symbol))
7272
{
7373
err_location(symbol.location);
74-
str << "failed to move symbol `" << symbol.name
75-
<< "' into symbol table";
74+
error() << "failed to move symbol `" << symbol.name
75+
<< "' into symbol table" << eom;
7676
throw 0;
7777
}
7878
}
@@ -118,7 +118,7 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
118118
else if(!is_function && symbol.value.id()==ID_code)
119119
{
120120
err_location(symbol.value);
121-
str << "only functions can have a function body";
121+
error() << "only functions can have a function body" << eom;
122122
throw 0;
123123
}
124124

@@ -162,8 +162,8 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
162162
if(old_it->second.is_type!=symbol.is_type)
163163
{
164164
err_location(symbol.location);
165-
str << "redeclaration of `" << symbol.display_name()
166-
<< "' as a different kind of symbol";
165+
error() << "redeclaration of `" << symbol.display_name()
166+
<< "' as a different kind of symbol" << eom;
167167
throw 0;
168168
}
169169

@@ -275,9 +275,9 @@ void c_typecheck_baset::typecheck_redefinition_type(
275275
else
276276
{
277277
err_location(new_symbol.location);
278-
str << "error: conflicting definition of type symbol `"
279-
<< new_symbol.display_name()
280-
<< "'";
278+
error() << "error: conflicting definition of type symbol `"
279+
<< new_symbol.display_name()
280+
<< "'" << eom;
281281
throw 0;
282282
}
283283
}
@@ -296,9 +296,9 @@ void c_typecheck_baset::typecheck_redefinition_type(
296296
{
297297
// arg! new tag type
298298
err_location(new_symbol.location);
299-
str << "error: conflicting definition of tag symbol `"
300-
<< new_symbol.display_name()
301-
<< "'";
299+
error() << "error: conflicting definition of tag symbol `"
300+
<< new_symbol.display_name()
301+
<< "'" << eom;
302302
throw 0;
303303
}
304304
}
@@ -322,10 +322,10 @@ void c_typecheck_baset::typecheck_redefinition_type(
322322
if(follow(new_symbol.type)!=follow(old_symbol.type))
323323
{
324324
err_location(new_symbol.location);
325-
str << "error: type symbol `" << new_symbol.display_name()
326-
<< "' defined twice:" << "\n";
327-
str << "Original: " << to_string(old_symbol.type) << "\n";
328-
str << " New: " << to_string(new_symbol.type);
325+
error() << "error: type symbol `"
326+
<< new_symbol.display_name() << "' defined twice:\n"
327+
<< "Original: " << to_string(old_symbol.type) << "\n"
328+
<< " New: " << to_string(new_symbol.type) << eom;
329329
throw 0;
330330
}
331331
}
@@ -375,7 +375,8 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
375375
if(final_new.id()==ID_code)
376376
{
377377
err_location(new_symbol.location);
378-
str << "function type not allowed for K&R function parameter";
378+
error() << "function type not allowed for K&R function parameter"
379+
<< eom;
379380
throw 0;
380381
}
381382

@@ -393,10 +394,11 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
393394
if(final_old.id()!=ID_code)
394395
{
395396
err_location(new_symbol.location);
396-
str << "error: function symbol `" << new_symbol.display_name()
397-
<< "' redefined with a different type:" << "\n";
398-
str << "Original: " << to_string(old_symbol.type) << "\n";
399-
str << " New: " << to_string(new_symbol.type);
397+
error() << "error: function symbol `"
398+
<< new_symbol.display_name()
399+
<< "' redefined with a different type:\n"
400+
<< "Original: " << to_string(old_symbol.type) << "\n"
401+
<< " New: " << to_string(new_symbol.type) << eom;
400402
throw 0;
401403
}
402404

@@ -449,8 +451,8 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
449451
else
450452
{
451453
err_location(new_symbol.location);
452-
str << "function body `" << new_symbol.display_name()
453-
<< "' defined twice";
454+
error() << "function body `" << new_symbol.display_name()
455+
<< "' defined twice" << eom;
454456
throw 0;
455457
}
456458
}
@@ -504,8 +506,9 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
504506
if(s_it==symbol_table.symbols.end())
505507
{
506508
err_location(old_symbol.location);
507-
str << "typecheck_redefinition_non_type: "
508-
"failed to find symbol `" << identifier << "'";
509+
error() << "typecheck_redefinition_non_type: "
510+
<< "failed to find symbol `" << identifier << "'"
511+
<< eom;
509512
throw 0;
510513
}
511514

@@ -547,10 +550,10 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
547550
else
548551
{
549552
err_location(new_symbol.location);
550-
str << "error: symbol `" << new_symbol.display_name()
551-
<< "' redefined with a different type:" << "\n";
552-
str << "Original: " << to_string(old_symbol.type) << "\n";
553-
str << " New: " << to_string(new_symbol.type);
553+
error() << "error: symbol `" << new_symbol.display_name()
554+
<< "' redefined with a different type:\n"
555+
<< "Original: " << to_string(old_symbol.type) << "\n"
556+
<< " New: " << to_string(new_symbol.type) << eom;
554557
throw 0;
555558
}
556559
}
@@ -587,8 +590,8 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
587590
else
588591
{
589592
err_location(new_symbol.value);
590-
str << "symbol `" << new_symbol.display_name()
591-
<< "' already has an initial value";
593+
error() << "symbol `" << new_symbol.display_name()
594+
<< "' already has an initial value" << eom;
592595
warning_msg();
593596
}
594597
}
@@ -687,8 +690,8 @@ void c_typecheck_baset::typecheck_function_body(symbolt &symbol)
687690
if(labels_defined.find(it->first)==labels_defined.end())
688691
{
689692
err_location(it->second);
690-
str << "branching label `" << it->first
691-
<< "' is not defined in function";
693+
error() << "branching label `" << it->first
694+
<< "' is not defined in function" << eom;
692695
throw 0;
693696
}
694697
}
@@ -736,7 +739,9 @@ void c_typecheck_baset::apply_asm_label(
736739
}
737740
else
738741
{
739-
str << "error: conflicting asm renaming";
742+
error() << "replacing asm renaming "
743+
<< asm_label_map[orig_name] << " by "
744+
<< asm_label << eom;
740745
throw 0;
741746
}
742747
}
@@ -847,16 +852,34 @@ void c_typecheck_baset::typecheck_declaration(
847852
if(!full_spec.alias.empty())
848853
{
849854
if(symbol.value.is_not_nil())
850-
throw "alias attribute cannot be used with a body";
855+
{
856+
err_location(symbol.location);
857+
error() << "alias attribute cannot be used with a body"
858+
<< eom;
859+
throw 0;
860+
}
851861

852862
// alias function need not have been declared yet, thus
853863
// can't lookup
854864
symbol.value=symbol_exprt(full_spec.alias);
855865
symbol.is_macro=true;
856866
}
857867

858-
apply_asm_label(full_spec.asm_label, symbol);
868+
if(full_spec.section.empty())
869+
apply_asm_label(full_spec.asm_label, symbol);
870+
else
871+
{
872+
std::string asm_name;
873+
asm_name=id2string(full_spec.section)+"$$";
874+
if(!full_spec.asm_label.empty())
875+
asm_name+=id2string(full_spec.asm_label);
876+
else
877+
asm_name+=id2string(symbol.name);
878+
879+
apply_asm_label(asm_name, symbol);
880+
}
859881
irep_idt identifier=symbol.name;
882+
d_it->set_name(identifier);
860883

861884
typecheck_symbol(symbol);
862885

0 commit comments

Comments
 (0)