Skip to content

Extended GCC attributes parsing and processing #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 18, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions regression/ansi-c/gcc_attributes5/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ STATIC_ASSERT(__alignof(var7)==8);

void (__attribute__((aligned)) *****f1)(void);
void (__attribute__((aligned)) f2)(void);

int __attribute__((cdecl,regparm(0))) *foo1(int x);
int __attribute__((cdecl,regparm(0))) *(foo2)(int x);
int (__attribute__((cdecl,regparm(0))) *foo3)(int x);
int (* __attribute__((cdecl,regparm(0))) foo4)(int x);
typedef int (__attribute__((cdecl,regparm(0))) foo5)(int x);
typedef int (__attribute__((cdecl,regparm(0))) *foo6)(int x);
typedef int* (__attribute__((cdecl,regparm(0))) *foo7)(int x);

#endif

Expand Down
2 changes: 1 addition & 1 deletion regression/ansi-c/gcc_attributes5/test.desc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
KNOWNBUG
CORE
main.c

^EXIT=0$
Expand Down
2 changes: 1 addition & 1 deletion regression/ansi-c/gcc_attributes6/test.desc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
KNOWNBUG
CORE
main.c

^EXIT=0$
Expand Down
20 changes: 20 additions & 0 deletions regression/ansi-c/gcc_attributes9/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifdef __GNUC__

int foo();
char foo __attribute__((section("other")));
long more_foo __attribute__((section("other2"))) asm("foo");

const char* __attribute__((section("s"))) bar1();
const char* __attribute__((section("s"),weak)) bar2();
const char* __attribute__((section("s"))) __attribute__((weak)) bar();

#endif

int main()
{
#ifdef __GNUC__
static int __attribute__((section(".data.unlikely"))) __warned;
__warned=1;
return __warned;
#endif
}
8 changes: 8 additions & 0 deletions regression/ansi-c/gcc_attributes9/test.desc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
CORE
main.c

^EXIT=0$
^SIGNAL=0$
--
^warning: ignoring
^CONVERSION ERROR$
9 changes: 6 additions & 3 deletions src/ansi-c/ansi_c_convert_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ void ansi_c_convert_typet::read_rec(const typet &type)
{
c_storage_spec.asm_label=type.subtype().get(ID_value);
}
else if(type.id()==ID_section &&
type.has_subtype() &&
type.subtype().id()==ID_string_constant)
{
c_storage_spec.section=type.subtype().get(ID_value);
}
else if(type.id()==ID_const)
c_qualifiers.is_constant=true;
else if(type.id()==ID_restrict)
Expand Down Expand Up @@ -110,9 +116,6 @@ void ansi_c_convert_typet::read_rec(const typet &type)
{
gcc_attribute_mode=type;
}
else if(type.id()==ID_gcc_attribute)
{
}
else if(type.id()==ID_msc_based)
{
const exprt &as_expr=static_cast<const exprt &>(static_cast<const irept &>(type));
Expand Down
6 changes: 6 additions & 0 deletions src/ansi-c/c_storage_spec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,10 @@ void c_storage_spect::read(const typet &type)
{
asm_label=type.subtype().get(ID_value);
}
else if(type.id()==ID_section &&
type.has_subtype() &&
type.subtype().id()==ID_string_constant)
{
section=type.subtype().get(ID_value);
}
}
6 changes: 5 additions & 1 deletion src/ansi-c/c_storage_spec.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ class c_storage_spect
is_weak=false;
alias.clear();
asm_label.clear();
section.clear();
}

bool is_typedef, is_extern, is_static, is_register,
Expand All @@ -46,6 +47,7 @@ class c_storage_spect

// GCC asm labels __asm__("foo") - these change the symbol name
irep_idt asm_label;
irep_idt section;

friend bool operator == (
const c_storage_spect &a,
Expand All @@ -59,7 +61,8 @@ class c_storage_spect
a.is_inline==b.is_inline &&
a.is_weak==b.is_weak &&
a.alias==b.alias &&
a.asm_label==b.asm_label;
a.asm_label==b.asm_label &&
a.section==b.section;
}

friend bool operator != (
Expand All @@ -82,6 +85,7 @@ class c_storage_spect
a.is_weak |=b.is_weak;
if(!b.alias.empty()) a.alias=b.alias;
if(!b.asm_label.empty()) a.asm_label=b.asm_label;
if(!b.section.empty()) a.section=b.section;

return a;
}
Expand Down
93 changes: 58 additions & 35 deletions src/ansi-c/c_typecheck_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ void c_typecheck_baset::move_symbol(symbolt &symbol, symbolt *&new_symbol)
if(symbol_table.move(symbol, new_symbol))
{
err_location(symbol.location);
str << "failed to move symbol `" << symbol.name
<< "' into symbol table";
error() << "failed to move symbol `" << symbol.name
<< "' into symbol table" << eom;
throw 0;
}
}
Expand Down Expand Up @@ -118,7 +118,7 @@ void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
else if(!is_function && symbol.value.id()==ID_code)
{
err_location(symbol.value);
str << "only functions can have a function body";
error() << "only functions can have a function body" << eom;
throw 0;
}

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

Expand Down Expand Up @@ -275,9 +275,9 @@ void c_typecheck_baset::typecheck_redefinition_type(
else
{
err_location(new_symbol.location);
str << "error: conflicting definition of type symbol `"
<< new_symbol.display_name()
<< "'";
error() << "error: conflicting definition of type symbol `"
<< new_symbol.display_name()
<< "'" << eom;
throw 0;
}
}
Expand All @@ -296,9 +296,9 @@ void c_typecheck_baset::typecheck_redefinition_type(
{
// arg! new tag type
err_location(new_symbol.location);
str << "error: conflicting definition of tag symbol `"
<< new_symbol.display_name()
<< "'";
error() << "error: conflicting definition of tag symbol `"
<< new_symbol.display_name()
<< "'" << eom;
throw 0;
}
}
Expand All @@ -322,10 +322,10 @@ void c_typecheck_baset::typecheck_redefinition_type(
if(follow(new_symbol.type)!=follow(old_symbol.type))
{
err_location(new_symbol.location);
str << "error: type symbol `" << new_symbol.display_name()
<< "' defined twice:" << "\n";
str << "Original: " << to_string(old_symbol.type) << "\n";
str << " New: " << to_string(new_symbol.type);
error() << "error: type symbol `"
<< new_symbol.display_name() << "' defined twice:\n"
<< "Original: " << to_string(old_symbol.type) << "\n"
<< " New: " << to_string(new_symbol.type) << eom;
throw 0;
}
}
Expand Down Expand Up @@ -375,7 +375,8 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
if(final_new.id()==ID_code)
{
err_location(new_symbol.location);
str << "function type not allowed for K&R function parameter";
error() << "function type not allowed for K&R function parameter"
<< eom;
throw 0;
}

Expand All @@ -393,10 +394,11 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
if(final_old.id()!=ID_code)
{
err_location(new_symbol.location);
str << "error: function symbol `" << new_symbol.display_name()
<< "' redefined with a different type:" << "\n";
str << "Original: " << to_string(old_symbol.type) << "\n";
str << " New: " << to_string(new_symbol.type);
error() << "error: function symbol `"
<< new_symbol.display_name()
<< "' redefined with a different type:\n"
<< "Original: " << to_string(old_symbol.type) << "\n"
<< " New: " << to_string(new_symbol.type) << eom;
throw 0;
}

Expand Down Expand Up @@ -449,8 +451,8 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
else
{
err_location(new_symbol.location);
str << "function body `" << new_symbol.display_name()
<< "' defined twice";
error() << "function body `" << new_symbol.display_name()
<< "' defined twice" << eom;
throw 0;
}
}
Expand Down Expand Up @@ -504,8 +506,9 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
if(s_it==symbol_table.symbols.end())
{
err_location(old_symbol.location);
str << "typecheck_redefinition_non_type: "
"failed to find symbol `" << identifier << "'";
error() << "typecheck_redefinition_non_type: "
<< "failed to find symbol `" << identifier << "'"
<< eom;
throw 0;
}

Expand Down Expand Up @@ -547,10 +550,10 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
else
{
err_location(new_symbol.location);
str << "error: symbol `" << new_symbol.display_name()
<< "' redefined with a different type:" << "\n";
str << "Original: " << to_string(old_symbol.type) << "\n";
str << " New: " << to_string(new_symbol.type);
error() << "error: symbol `" << new_symbol.display_name()
<< "' redefined with a different type:\n"
<< "Original: " << to_string(old_symbol.type) << "\n"
<< " New: " << to_string(new_symbol.type) << eom;
throw 0;
}
}
Expand Down Expand Up @@ -587,8 +590,8 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
else
{
err_location(new_symbol.value);
str << "symbol `" << new_symbol.display_name()
<< "' already has an initial value";
error() << "symbol `" << new_symbol.display_name()
<< "' already has an initial value" << eom;
warning_msg();
}
}
Expand Down Expand Up @@ -687,8 +690,8 @@ void c_typecheck_baset::typecheck_function_body(symbolt &symbol)
if(labels_defined.find(it->first)==labels_defined.end())
{
err_location(it->second);
str << "branching label `" << it->first
<< "' is not defined in function";
error() << "branching label `" << it->first
<< "' is not defined in function" << eom;
throw 0;
}
}
Expand Down Expand Up @@ -736,7 +739,9 @@ void c_typecheck_baset::apply_asm_label(
}
else
{
str << "error: conflicting asm renaming";
error() << "replacing asm renaming "
<< asm_label_map[orig_name] << " by "
<< asm_label << eom;
throw 0;
}
}
Expand Down Expand Up @@ -847,16 +852,34 @@ void c_typecheck_baset::typecheck_declaration(
if(!full_spec.alias.empty())
{
if(symbol.value.is_not_nil())
throw "alias attribute cannot be used with a body";
{
err_location(symbol.location);
error() << "alias attribute cannot be used with a body"
<< eom;
throw 0;
}

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

apply_asm_label(full_spec.asm_label, symbol);
if(full_spec.section.empty())
apply_asm_label(full_spec.asm_label, symbol);
else
{
std::string asm_name;
asm_name=id2string(full_spec.section)+"$$";
if(!full_spec.asm_label.empty())
asm_name+=id2string(full_spec.asm_label);
else
asm_name+=id2string(symbol.name);

apply_asm_label(asm_name, symbol);
}
irep_idt identifier=symbol.name;
d_it->set_name(identifier);

typecheck_symbol(symbol);

Expand Down
Loading